Python打卡DAY19

常见的特征筛选算法

  1. 方差筛选
  2. 皮尔逊相关系数筛选
  3. lasso筛选
  4. 树模型重要性
  5. shap重要性
  6. 递归特征消除REF

作业:对心脏病数据集完成特征筛选,对比精度

import pandas as pd
import pandas as pd  # 用于数据处理和分析,可处理表格数据。
import numpy as np  # 用于数值计算,提供了高效的数组操作。
import matplotlib.pyplot as plt  # 用于绘制各种类型的图表
import seaborn as sns  # 基于matplotlib的高级绘图库,能绘制更美观的统计图形。
import warnings

warnings.filterwarnings("ignore")

# 设置中文字体(解决中文显示问题)
plt.rcParams['font.sans-serif'] = ['SimHei']  # Windows系统常用黑体字体
plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号
data = pd.read_csv('heart.csv')
# 数据划分
X = data.drop(['target'], axis = 1)
y = data['target']
from sklearn.model_selection import train_test_split
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))
  1. 方差筛选
    #方差筛选
    # 打印标题,表明这是方差筛选的部分
    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))
  2. 皮尔逊相关系数筛选
    # 皮尔逊相关系数筛选
    print("--- 皮尔逊相关系数筛选 ---")
    from sklearn.feature_selection import SelectKBest, f_classif
    import time
    
    start_time = time.time()
    
    # 计算特征与目标变量的相关性,选择前k个特征(这里设为10个,可调整)
    # 注意:皮尔逊相关系数通常用于回归问题(连续型目标变量),但如果目标是分类问题,可以用f_classif
    k = 10
    selector = SelectKBest(score_func=f_classif, k=k)
    X_train_corr = selector.fit_transform(X_train, y_train)
    X_test_corr = selector.transform(X_test)
    
    # 获取筛选后的特征名
    selected_features_corr = X_train.columns[selector.get_support()].tolist()
    print(f"皮尔逊相关系数筛选后保留的特征数量: {len(selected_features_corr)}")
    print(f"保留的特征: {selected_features_corr}")
    
    # 训练随机森林模型
    rf_model_corr = RandomForestClassifier(random_state=42)
    rf_model_corr.fit(X_train_corr, y_train)
    rf_pred_corr = rf_model_corr.predict(X_test_corr)
    
    end_time = time.time()
    print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")
    print("\n皮尔逊相关系数筛选后随机森林在测试集上的分类报告:")
    print(classification_report(y_test, rf_pred_corr))
    print("皮尔逊相关系数筛选后随机森林在测试集上的混淆矩阵:")
    print(confusion_matrix(y_test, rf_pred_corr))
  3. lasso筛选
    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))
  4. 树模型重要性
    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))
  5. shap重要性
    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))
  6. 递归特征消除REF
    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))

    @浙大疏锦行

你可能感兴趣的:(浙大疏锦行打卡,python,机器学习)