Python打卡训练营学习记录Day19

import pandas as pd    #用于数据处理和分析,可处理表格数据。
import numpy as np     #用于数值计算,提供了高效的数组操作。
import matplotlib.pyplot as plt    #用于绘制各种类型的图表
import seaborn as sns   #基于matplotlib的高级绘图库,能绘制更美观的统计图形。
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import StratifiedKFold, cross_validate # 引入分层 K 折和交叉验证工具
from sklearn.metrics import make_scorer, accuracy_score, precision_score, recall_score, f1_score, confusion_matrix, classification_report
import time
import warnings
warnings.filterwarnings("ignore")
# 设置中文字体(解决中文显示问题)
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows系统常用黑体字体
plt.rcParams['axes.unicode_minus'] = False    # 正常显示负号
data  = pd.read_csv('heart.csv')
# 提取连续值特征
continuous_features = ['age', 'trestbps', 'chol', 'thalach', 'oldpeak']
# 提取离散值特征
discrete_features = ['sex', 'cp', 'fbs', 'restecg', 'exang', 'slope', 'ca', 'thal', 'target']
# 使用映射字典进行转换
mapping = {
    'cp': {0: 0, 1: 1, 2: 2, 3: 3},
    'restecg': {0: 0, 1: 1, 2: 2},
    'slope': {0: 0, 1: 1, 2: 2},
    'ca': {0: 0, 1: 1, 2: 2, 3: 3, 4: 4},
    'thal': {0: 0, 1: 1, 2: 2, 3: 3}
}
for feature, mapping in mapping.items():
    data[feature] = data[feature].map(mapping)
# Purpose 独热编码
columns_to_encode = ['sex','fbs','exang']
data = pd.get_dummies(data, columns=columns_to_encode, drop_first=True)
data2 = pd.read_csv("heart.csv") # 重新读取数据,用来做列名对比
list_final = [] # 新建一个空列表,用于存放独热编码后新增的特征名
for i in data.columns:
    if i not in data2.columns:
        list_final.append(i) # 这里打印出来的就是独热编码后的特征名
for i in list_final:
    data[i] = data[i].astype(int) # 这里的i就是独热编码后的特征名
# 划分训练集和测试机
X = data.drop(['target'], axis=1)  # 特征,axis=1表示按列删除
y = data['target']  # 标签
# 按照8:2划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 80%训练集,20%测试集



from sklearn.ensemble import RandomForestClassifier #随机森林分类器

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score # 用于评估分类器性能的指标
from sklearn.metrics import classification_report, confusion_matrix #用于生成分类报告和混淆矩阵
import warnings #用于忽略警告信息
warnings.filterwarnings("ignore") # 忽略所有警告信息
# --- 1. 默认参数的随机森林 ---
# 评估基准模型,这里确实不需要验证集
print("--- 1. 默认参数随机森林 (训练集 -> 测试集) ---")
import time # 这里介绍一个新的库,time库,主要用于时间相关的操作,因为调参需要很长时间,记录下会帮助后人知道大概的时长
start_time = time.time() # 记录开始时间
rf_model = RandomForestClassifier(random_state=42)
rf_model.fit(X_train, y_train) # 在训练集上训练
rf_pred = rf_model.predict(X_test) # 在测试集上预测
end_time = time.time() # 记录结束时间

print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")
print("\n默认随机森林 在测试集上的分类报告:")
print(classification_report(y_test, rf_pred))
print("默认随机森林 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred))

 

 

# 打印标题,表明这是方差筛选的部分
print("--- 方差筛选 (Variance Threshold) ---")

# 导入需要的工具库
from sklearn.feature_selection import VarianceThreshold  # 方差筛选工具,用于剔除方差小的特征
import time  # 用于记录代码运行时间,方便比较效率

# 记录开始时间,后面会计算整个过程耗时
start_time = time.time()

# 创建方差筛选器,设置方差阈值为0.01
# 阈值是指方差的最小值,低于这个值的特征会被删除(可以根据数据情况调整阈值)
selector = VarianceThreshold(threshold=0.01)

# 对训练数据进行方差筛选,fit_transform会计算每个特征的方差并剔除不满足阈值的特征
# X_train是原始训练数据,X_train_var是筛选后的训练数据
X_train_var = selector.fit_transform(X_train)

# 对测试数据应用同样的筛选规则,transform会直接用训练数据的筛选结果处理测试数据
# X_test是原始测试数据,X_test_var是筛选后的测试数据
X_test_var = selector.transform(X_test)

# 获取被保留下来的特征名称
# selector.get_support()返回一个布尔值列表,表示哪些特征被保留,这个是selector这个实例化的类的一个方法
# X_train.columns是特征的名称,结合布尔值列表可以提取保留特征的名字
selected_features_var = X_train.columns[selector.get_support()].tolist()

# 打印筛选后保留的特征数量和具体特征名称,方便查看结果
print(f"方差筛选后保留的特征数量: {len(selected_features_var)}")
print(f"保留的特征: {selected_features_var}")

# 创建一个随机森林分类模型,用于在筛选后的数据上进行训练和预测
# random_state=42是为了保证每次运行结果一致,方便教学和对比
rf_model_var = RandomForestClassifier(random_state=42)

# 在筛选后的训练数据上训练模型
# X_train_var是筛选后的特征数据,y_train是对应的目标标签
rf_model_var.fit(X_train_var, y_train)

# 使用训练好的模型对筛选后的测试数据进行预测
# X_test_var是筛选后的测试特征数据,rf_pred_var是预测结果
rf_pred_var = rf_model_var.predict(X_test_var)

# 记录结束时间,计算整个训练和预测过程的耗时
end_time = time.time()
print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")

# 打印模型在测试集上的分类报告,展示模型的性能
# 分类报告包括精确率、召回率、F1分数等指标,帮助评估模型好坏
print("\n方差筛选后随机森林在测试集上的分类报告:")
print(classification_report(y_test, rf_pred_var))

# 打印混淆矩阵,展示模型预测的详细结果
# 混淆矩阵显示了真实标签和预测标签的对应情况,比如多少样本被正确分类,多少被错分
print("方差筛选后随机森林在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred_var))

 

 

print("--- Lasso筛选 (L1正则化) ---")
from sklearn.linear_model import Lasso
from sklearn.feature_selection import SelectFromModel
import time

start_time = time.time()

# 使用Lasso回归进行特征筛选
lasso = Lasso(alpha=0.01, random_state=42)  # alpha值可调整
selector = SelectFromModel(lasso)
selector.fit(X_train, y_train)
X_train_lasso = selector.transform(X_train)
X_test_lasso = selector.transform(X_test)

# 获取筛选后的特征名
selected_features_lasso = X_train.columns[selector.get_support()].tolist()
print(f"Lasso筛选后保留的特征数量: {len(selected_features_lasso)}")
print(f"保留的特征: {selected_features_lasso}")

# 训练随机森林模型
rf_model_lasso = RandomForestClassifier(random_state=42)
rf_model_lasso.fit(X_train_lasso, y_train)
rf_pred_lasso = rf_model_lasso.predict(X_test_lasso)

end_time = time.time()
print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")
print("\nLasso筛选后随机森林在测试集上的分类报告:")
print(classification_report(y_test, rf_pred_lasso))
print("Lasso筛选后随机森林在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred_lasso))

 

 

print("--- 树模型自带的重要性筛选 ---")
from sklearn.feature_selection import SelectFromModel
import time

start_time = time.time()

# 使用随机森林的特征重要性进行筛选
rf_selector = RandomForestClassifier(random_state=42)
rf_selector.fit(X_train, y_train)
selector = SelectFromModel(rf_selector, threshold="mean")  # 阈值设为平均重要性,可调整
X_train_rf = selector.transform(X_train)
X_test_rf = selector.transform(X_test)

# 获取筛选后的特征名
selected_features_rf = X_train.columns[selector.get_support()].tolist()
print(f"树模型重要性筛选后保留的特征数量: {len(selected_features_rf)}")
print(f"保留的特征: {selected_features_rf}")

# 训练随机森林模型
rf_model_rf = RandomForestClassifier(random_state=42)
rf_model_rf.fit(X_train_rf, y_train)
rf_pred_rf = rf_model_rf.predict(X_test_rf)

end_time = time.time()
print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")
print("\n树模型重要性筛选后随机森林在测试集上的分类报告:")
print(classification_report(y_test, rf_pred_rf))
print("树模型重要性筛选后随机森林在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred_rf))

 

 

print("--- SHAP重要性筛选 ---")
import shap
from sklearn.feature_selection import SelectKBest
import time

start_time = time.time()

# 使用随机森林模型计算SHAP值
rf_shap = RandomForestClassifier(random_state=42)
rf_shap.fit(X_train, y_train)
explainer = shap.TreeExplainer(rf_shap)
shap_values = explainer.shap_values(X_train)

# 计算每个特征的平均SHAP值(取绝对值的平均)
mean_shap = np.abs(shap_values[1]).mean(axis=0)  # shap_values[1]对应正类
k = 10  # 选择前10个特征,可调整
top_k_indices = np.argsort(mean_shap)[-k:]
X_train_shap = X_train.iloc[:, top_k_indices]
X_test_shap = X_test.iloc[:, top_k_indices]

# 获取筛选后的特征名
selected_features_shap = X_train.columns[top_k_indices].tolist()
print(f"SHAP重要性筛选后保留的特征数量: {len(selected_features_shap)}")
print(f"保留的特征: {selected_features_shap}")

# 训练随机森林模型
rf_model_shap = RandomForestClassifier(random_state=42)
rf_model_shap.fit(X_train_shap, y_train)
rf_pred_shap = rf_model_shap.predict(X_test_shap)

end_time = time.time()
print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")
print("\nSHAP重要性筛选后随机森林在测试集上的分类报告:")
print(classification_report(y_test, rf_pred_shap))
print("SHAP重要性筛选后随机森林在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred_shap))

 

print("--- 递归特征消除 (RFE) ---")
from sklearn.feature_selection import RFE
import time

start_time = time.time()

# 使用随机森林作为基础模型进行RFE
base_model = RandomForestClassifier(random_state=42)
rfe = RFE(base_model, n_features_to_select=10)  # 选择10个特征,可调整
rfe.fit(X_train, y_train)
X_train_rfe = rfe.transform(X_train)
X_test_rfe = rfe.transform(X_test)

# 获取筛选后的特征名
selected_features_rfe = X_train.columns[rfe.support_].tolist()
print(f"RFE筛选后保留的特征数量: {len(selected_features_rfe)}")
print(f"保留的特征: {selected_features_rfe}")

# 训练随机森林模型
rf_model_rfe = RandomForestClassifier(random_state=42)
rf_model_rfe.fit(X_train_rfe, y_train)
rf_pred_rfe = rf_model_rfe.predict(X_test_rfe)

end_time = time.time()
print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")
print("\nRFE筛选后随机森林在测试集上的分类报告:")
print(classification_report(y_test, rf_pred_rfe))
print("RFE筛选后随机森林在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred_rfe))

 

 

@浙大疏锦行 

 

 

n many data analysis tasks, one is often confronted with very high dimensional data. Feature selection techniques are designed to find the relevant feature subset of the original features which can facilitate clustering, classification and retrieval. The feature selection problem is essentially a combinatorial optimization problem which is computationally expensive. Traditional feature selection methods address this issue by selecting the top ranked features based on certain scores computed independently for each feature. These approaches neglect the possible correlation between different features and thus can not produce an optimal feature subset. Inspired from the recent developments on manifold learning and L1-regularized models for subset selection, we propose here a new approach, called {\em Multi-Cluster/Class Feature Selection} (MCFS), for feature selection. Specifically, we select those features such that the multi-cluster/class structure of the data can be best preserved. The corresponding optimization problem can be efficiently solved since it only involves a sparse eigen-problem and a L1-regularized least squares problem. It is important to note that MCFS can be applied in superised, unsupervised and semi-supervised cases. If you find these algoirthms useful, we appreciate it very much if you can cite our following works: Papers Deng Cai, Chiyuan Zhang, Xiaofei He, "Unsupervised Feature Selection for Multi-cluster Data", 16th ACM SIGKDD Conference on Knowledge Discovery and Data Mining (KDD'10), July 2010. Bibtex source Xiaofei He, Deng Cai, and Partha Niyogi, "Laplacian Score for Feature Selection", Advances in Neural Information Processing Systems 18 (NIPS'05), Vancouver, Canada, 2005 Bibtex source
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值