Day 19 常见的特征筛选算法

@浙大疏锦行

今日任务:

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

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

对于许多数据来说,它们拥有众多的特征,如果不进行处理,就会出现计算速度下降以及冗余特征的干扰等问题。因此,对于高维特征的数据,特征降维十分必要。

常见的特征降维方法主要有两种:

  • 特征筛选:从n个特征中筛选出m个特,包括过滤法、包裹法及嵌入法等
  • 特征组合:从n个特征组合出m个特征,如PCA

今日主要学习特征筛选,它适合于不相关特征、冗余特征和噪声特征的处理。下面是三类常用的特征筛选方法的介绍:

  • 过滤法:基于特征的统计属性(如方差、相关性、互信息)进行筛选。如方差选择法、相关系数法、卡方检验、互信息法。
  • 包裹法:将模型本身的性能作为评价标准,通过不断尝试不同的特征子集,选择使模型性能最佳的特征组合。如递归特征消除(RFE)、前向选择、后向剔除。
  • 嵌入法:将特征选择过程与模型训练过程融为一体。模型在训练时会自动进行特征选择。如使用L1正则化(Lasso回归)的模型、决策树/随机森林/Gradient Boosting模型提供的特征重要性。

首先对信贷数据集使用默认参数的随机森林训练得到下面的结果:

下面是具体的六种方法的说明,以及特征筛选后的结果:

方差筛选

过滤式无监督,通过计算数据的方差大小和阈值(认为设定)进行比较,大于则保留,小于则删去。它的核心思想基于下面的假设:如果一个特征在不同的样本中的取值几乎没有变化(方差值很小),那么它能提供的区分样本的信息量就很少,故而该特征对模型的预测能力的贡献就几乎忽略不计。

方差筛选法可以通过sklearn库中VarienceThreshold(threshold=0.0)完成。

#方差筛选法
from sklearn.feature_selection import VarianceThreshold

start_time = time.time()
selector = VarianceThreshold(threshold=0.01) #实例化
X_train_var = selector.fit_transform(X_train) #训练并转换原始训练集
X_test_var = selector.transform(X_test) #转换测试集

#查看筛选后的特征
selected_features_var = X_train.columns[selector.get_support()].tolist() #X_train.columns[selector.get_support()]的类型
#print('筛选的特征:{},长度:{}'.format(selected_features_var,len(selected_features_var)))
#重新训练模型
rf_model_var = RandomForestClassifier(random_state=42)
rf_model_var.fit(X_train_var,y_train)
rf_pred_var = rf_model_var.predict(X_test_var)
end_time = time.time()

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

特征筛选后,得到21个特征,训练结果与之前差异不大:

根据定义,可以看出方差筛选法的优缺点:

  • 优点:计算速度较快;简单易懂;不需要标签,在预处理阶段可完成
  • 缺点:阈值选择困难;忽略特征与目标的关系,只关注特征本身的分布;对特征尺度敏感

皮尔逊相关系数筛选

过滤式有监督,通过量化每个特征与目标变量之间的线性关系强度,来筛选出与目标最相关的特征,同时也可以用于提出高度相关的冗余特征。需要注意的是它处理的目标变量为连续性,若为离散型需要进行编码处理,转换为数据型。

判断线性关系程度与方向的指标是皮尔逊相关系数(r),取值范围是[-1,1]:

  • 方向:r = 1表示完全正相关,一个变量增加,另一个变量也线性增加。r = -1表示完全负相关,一个变量增加,另一个变量线性减少。 r =0表示没有线性相关关系。
  • 强度:|r| ≥ 0.8,强相关;0.5 ≤ |r| < 0.8,中等相关;0.3 ≤ |r| < 0.5,弱相关;|r| < 0.3,极弱相关或无相关。

这里使用SelectKBest(score_func=f_classif,k=k)来筛选前k个特征。其中f_classif为评分函数,计算的是每个特征与目标变量之间的ANOVA F值(方差分析F值),用于衡量特征在不同类别间的差异程度。

#皮尔逊系数筛选
from sklearn.feature_selection import SelectKBest,f_classif

start_time = time.time()
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('筛选的特征:{},\n长度:{}'.format(selected_features_corr,len(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))

皮尔逊系数筛选后剩余10个特征,在训练效果上有所差异:

lasso筛选(基于L1正则化)

Lasso(Least Absolute Shrinkage and Selection Operator,即最小绝对收缩和选择算子)筛选,它的核心思想是在线性回归的同时,通过引入L1正则化项惩罚项),强制将一些不重要特征的回归系数压缩到0,从而实现特征筛选。

也就是说,Lasso会自动“挑选”对预测目标有贡献的特征(系数不为0),而剔除无关或冗余的特征(系数为0)。

lasso筛选的实现可以通过SelectFromModel包装器,基于LASSO模型的系数来自动选择重要特征:

  • SelectFromModel:元转换器,自动设置阈值(默认为中位数),只保留那些重要性高于改阈值的特征。相比直接使用LASSO系数(手动),可以自动选择重要特征
  • Lasso:创建LASSO回归模型,alpha为正则化强度参数,alpha越大,正则化越强,保留的特征越少
#lasso筛选
from sklearn.linear_model import Lasso
from sklearn.feature_selection import SelectFromModel

start_time = time.time()
#创建Lasso模型
lasso = Lasso(alpha=0.01,random_state=42) #alpha正则化强度参数
selector = SelectFromModel(estimator=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('筛选的特征:{},\n长度:{}'.format(selected_features_lasso,len(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("默认随机森林 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred_lasso))

经过lasso筛选后,得到7个特征:

树模型的重要性

属于嵌入性,这个是树模型自带的重要性筛选。

同样地,借助SelectFromModel(estimator,threshold,...)包装器,完成特征筛选工作。一般步骤是:(1)建立模型(2)包装器筛选(3)训练、转换(4)查看筛选后的特征名,借助selector.get_support()布尔掩码(5)使用筛选后的特征训练,对比前后结果

#树模型筛选重要性
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import SelectFromModel

start_time = time.time()
#创建rf模型
rf_selector = RandomForestClassifier(random_state=42) 
rf_selector.fit(X_train,y_train)
selector = SelectFromModel(estimator=rf_selector)
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('筛选的特征:{},\n长度:{}'.format(selected_features_rf,len(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))

通过筛选后,剩余11个特征:

SHAP重要性筛选

基于SHAP值的模型解释性的高级特征选择方法。根据每个特征对模型预测的贡献度大小,选择最重要的k个特征。

具体步骤如下:(1)训练模型并创建shap解释器(2)计算shap值(3)计算特征重要性并选择top-k特征(4)使用特征索引选择训练集和测试集的对应特征iloc (5)重新训练,对比结果

通过SHAP筛选后,剩余10个特征:

递归特征消除RFE

递归特征消除法(Recursive Feature Elimination,RFE),属于包裹法,通过递归地构建模型并剔除最不重要的特征,最终保留最优的特征子集。它是一个反复迭代的过程,每次迭代都会训练一个模型,根据特征重要性排序,淘汰掉最不重要的特征,直到达到指定的特征数量。

通过RFE筛选后,剩余10个特征:

下面是六种方法的总结:

方法类型监督性计算成本核心原理是否考虑特征交互
方差筛选过滤法无监督很低特征本身的方差大小
皮尔逊系数筛选过滤法有监督特征与目标的线性相关性
LASSO筛选嵌入法有监督L1正则化压缩系数为0是(线性)
树模型筛选嵌入法有监督基于分裂增益的重要性
SHAP筛选模型解释有监督基于博弈论的边际贡献
递归特征消除(RFE)包裹法有监督很高递归剔除最不重要特征

作业:心脏病特征筛选

总结一下,使用上述六种方法进行特征筛选时,基本的步骤相似:

  • 导入所需要的库
  • 创建模型,确定是否需要包装器等辅助
  • 训练、转换训练集与测试集
  • 借助selector.get_support()查看筛选特征后的结果
  • 重新训练模型,比对结果

今日时间有限,明日续上今日剩余部分

任务概述 此任务中,我们要完成三项任务: 使用随机森林算法完成基本建模任务 基本任务需要我们处理数据,观察特征,完成建模并进行可视化展示分析 观察数据量与特征个数对结果影响 在保证算法一致的前提下, 加大数据个数,观察结果变换。重新考虑特征工程,引入新特征后观察结果走势。 对随机森林算法进行调参,找到最合适的参数 掌握机器学习中两种经典调参方法,对当前模型进行调节 数据展示 # Pandas is used for data manipulation import pandas as pd # Read in data as pandas dataframe and display first 5 rows features = pd.read_csv('data/temps.csv') features.head(5) AI写代码 python 运行 1 2 3 4 5 6 本数据表中: year,moth,day,wek分别表示的具体的时间 temp_ 2:前天的最高温度值 temp_ 1:昨天的最高温度值 average: 在历史中,每年这一天的平均最高温度值 actual: 这就是我们的标签值了,当天的真实最高温度 friend: 朋友的评价 #查看数据维度 print('The shape of our features is:', features.shape) #查看有无异常值 features.describe() AI写代码 python 运行 1 2 3 4 无异常值我们就可以接着往下做了 在此数据集中,我们可以看到关于时间的特征是分散的,下面我们需要把他们合并一下,得到一个datetime格式的特征数据 # 处理时间数据 import datetime # 分别得到年月日 years = features['year'] months = features['month'] days = features['day'] # datetime格式 dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)] dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates] AI写代码 python 运行 1 2 3 4 5 6 7 8 9 10 11 查看数据 # 准备画图 import matplotlib.pyplot as plt %matplotlib inline # 指定默认风格 plt.style.use('fivethirtyeight') # 设计布局 fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, figsize = (10,10)) fig.autofmt_xdate(rotation = 45) # 标签值 ax1.plot(dates, features['actual']) ax1.set_xlabel(''); ax1.set_ylabel('Temperature'); ax1.set_title('Max Temp') # 昨天 ax2.plot(dates, features['temp_1']) ax2.set_xlabel(''); ax2.set_ylabel('Temperature'); ax2.set_title('Previous Max Temp') # 前天 ax3.plot(dates, features['temp_2']) ax3.set_xlabel('Date'); ax3.set_ylabel('Temperature'); ax3.set_title('Two Days Prior Max Temp') # 朋友的评价 ax4.plot(dates, features['friend']) ax4.set_xlabel('Date'); ax4.set_ylabel('Temperature'); ax4.set_title('Friend Estimate') plt.tight_layout(pad=2) AI写代码 python 运行 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 得到可视化信息如下: 横轴为日期,纵轴分别是 actual、temp_1、temp_2、friend 基本随机森林模型建立 数据预处理 在文章一开始的观察数据的那一步,我们就发现了一个问题,week 特征它不是数字形式,而是 Mon、Tue、Wed、Thu、Fri、Sat、Sun 使用 独热编码 One-Hot Encoding 方式进行数据处理,使其全部成为数字形式,这里我们使用 pd.get_dummies(),它的 官网API # 独热编码 pd.get_dummies自动寻找 features = pd.get_dummies(features) features.head(5) AI写代码 python 运行 1 2 3 标签与数据集格式转换 # 数据与标签 import numpy as np # 标签 labels = np.array(features['actual']) # 在特征中去掉标签 features= features.drop('actual', axis = 1) # 保存特征名称,后续使用 feature_list = list(features.columns) # 转换为 np.array形式 features = np.array(features) AI写代码 python 运行 1 2 3 4 5 6 7 8 9 10 训练集与测试集 # 使用 Skicit-learn 切分数据集 from sklearn.model_selection import train_test_split # 将数据分为训练集和测试集 // 传入参数:特征、标签、比例、随机种子 train_features, test_features, train_labels, test_labels = train_test_split(features, labels, test_size = 0.25, random_state = 42) AI写代码 python 运行 1 2 3 4 5 建立一个基础的随机森林模型 所有准备工作都已经完成了,现在可以来建立随机森林模型了,导入Sklearn工具包,在这里我们先建立1000个树模型尝试一下,其他参数先用默认值,之后再细化调参任务 # 导入随机森林算法模型 from sklearn.ensemble import RandomForestRegressor # 实例化模型 rf = RandomForestRegressor(n_estimators= 1000, random_state=42) # 训练数据模型 rf.fit(train_features, train_labels) AI写代码 python 运行 1 2 3 4 5 6 测试 # 在测试数据上使用森林预测方法 predictions = rf.predict(test_features) # 计算绝对误差 errors = abs(predictions - test_labels) # 计算绝对百分比误差 mape = 100*(errors/test_labels) accuracy = 100 - np.mean(mape) # 打印出平均绝对误差(mae) print('Mean Absolute Error:', round(np.mean(errors), 2),) # 打印准确率 print('Accuracy:', round(accuracy,2),'%') AI写代码 python 运行 1 2 3 4 5 6 7 8 9 10 11 Mean Absolute Error: 3.83 Accuracy: 93.99 % AI写代码 1 2 预测指标 MAE、MAPE: MAE: 平均绝对误差(Mean Absolute Error) M A E = 1 n ∑ i = 1 n ∣ y ^ i − y i ∣ MAE=\frac{1}{n}\sum_{i=1}^{n}|\hat{y}_i-yi| MAE= n 1 ​ i=1 ∑ n ​ ∣ y ^ ​ i ​ −yi∣ 值域:[0,+∞) 当预测值与真实值完全吻合时等于0,即完美模型;误差越大,MAE 值越大。 MAPE: 平均绝对百分比误差(Mean Absolute Percentage Error) M A P E = 100 % n ∑ i = 1 n ∣ y ^ i − y i y i ∣ MAPE=\frac{100\%}{n}\sum_{i=1}^{n}|\frac{\hat{y}_i-yi}{y_i}| MAPE= n 100% ​ i=1 ∑ n ​ ∣ y i ​ y ^ ​ i ​ −yi ​ ∣ 值域:[0,+∞),MAPE 为0%表示完美模型,MAPE 大于 100 %则表示劣质模型。 但 MAPE 有一点需要注意,当真实值 y i y_iy i ​ 有数据等于0时,存在分母 0 00 除问题,则该公式无意义不可用 可视化展示与特征重要性 树模型的可视化需要安装软件库 Graphviz,并好相关环境变量 graphviz-2.38.msi 官方下载地址:https://graphviz.gitlab.io/_pages/Download/Download_windows.html # 导入工具包 from sklearn.tree import export_graphviz import pydot #pip install pydot # 拿到其中的一棵树 tree = rf.estimators_[5] # 将图像导出为 dot 文件 export_graphviz(tree, out_file = 'tree.dot', feature_names = feature_list, rounded = True, precision = 1) # 绘图 (graph, ) = pydot.graph_from_dot_file('tree.dot') # 展示 graph.write_png('tree.png'); AI写代码 python 运行 1 2 3 4 5 6 7 8 9 10 11 生成的原始图像文件中,树的深度是15,下面我们简化一下,将树的深度改为3,再看一下 # 限制树模型深度 rf_small = RandomForestRegressor(n_estimators=10, max_depth = 3, random_state=42) rf_small.fit(train_features, train_labels) # 拿到其中的一棵树 tree_small = rf_small.estimators_[5] # 将图像导出为 dot 文件 export_graphviz(tree_small, out_file = 'small_tree.dot', feature_names = feature_list, rounded = True, precision = 1) # 绘图 (graph, ) = pydot.graph_from_dot_file('small_tree.dot') # 展示 graph.write_png('small_tree.png'); AI写代码 python 运行 1 2 3 4 5 6 7 8 9 10 11 这张图像显示的即是树模型的上面的形状 解释: 特征重要性 # 得到特征重要性 importances = list(rf.feature_importances_) # 转换格式 feature_importances = [(feature, round(importance, 2)) for feature, importance in zip(feature_list, importances)] # 排序 feature_importances = sorted(feature_importances, key = lambda x: x[1], reverse = True) # 对应进行打印 [print('Variable: {:20} Importance: {}'.format(*pair)) for pair in feature_importances]; AI写代码 python 运行 1 2 3 4 5 6 7 8 Variable: temp_1 Importance: 0.7 Variable: average Importance: 0.19 Variable: day Importance: 0.03 Variable: temp_2 Importance: 0.02 Variable: friend Importance: 0.02 Variable: month Importance: 0.01 Variable: year Importance: 0.0 Variable: week_Fri Importance: 0.0 Variable: week_Mon Importance: 0.0 Variable: week_Sat Importance: 0.0 Variable: week_Sun Importance: 0.0 Variable: week_Thurs Importance: 0.0 Variable: week_Tues Importance: 0.0 Variable: week_Wed Importance: 0.0 AI写代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 画图展示 # 生成X轴坐标位置 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] x_values = list(range(len(importances))) # 绘图 plt.bar(x_values, importances, orientation = 'vertical') # 定义各柱状图名称 plt.xticks(x_values, feature_list, rotation='vertical') # X、Y轴设定 plt.ylabel('Importance') plt.xlabel('Variable') # 图片名称 plt.title('Variable Importances') AI写代码 python 运行 1 2 3 4 5 6 7 8 9 10 11 用最重要的特征再来试试 得到了我们的特征重要性之后,我们可以了解到模型训练时用到的主要特征是 temp_1、average,那么我们就来看一下,如果只用这两个特征进行训练,效果会是什么样子,会不会对结果无影响 # 选择最重要的两个特征来实验 rf_most_important = RandomForestRegressor(n_estimators= 1000, random_state=42) # 拿到特征值 important_indices = [feature_list.index('temp_1'), feature_list.index('average')] train_important = train_features[:, important_indices] test_important = test_features[:, important_indices] # 重新训练模型 rf_most_important.fit(train_important, train_labels) # 预测结果 predictions = rf_most_important.predict(test_important) # 计算绝对误差 errors = abs(predictions - test_labels) # 计算 MAPE mape = np.mean(100 * (errors / test_labels)) accuracy = 100 - mape # 打印 print('Mean Absolute Error:', round(np.mean(errors), 2)) print('Accuracy:', round(accuracy, 2), '%') AI写代码 python 运行 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Mean Absolute Error: 3.92 Accuracy: 93.77 % AI写代码 1 2 使用所有特征训练时:Mean Absolute Error: 3.83,Accuracy: 93.99 %;使用两个特征训练时:Mean Absolute Error: 3.92,Accuracy: 93.77 %。数据集共有15个特征,在经过特征重要性筛选后我们使用的是2个特征,训练速度肯定是变快了,但是精度值有一点下降。在实际应用场景中,我们可以根据应用场景中是更注重预测速度还是更注重预测精度来进行模型选择。 预测值与真实值之间的差异 最后我们将本文中做的实验结果进行整合 # 日期数据 months = features[:, feature_list.index('month')] days = features[:, feature_list.index('day')] years = features[:, feature_list.index('year')] # 转换日期格式 dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)] dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates] # 创建一个表格来存日期和其对应的标签数值 true_data = pd.DataFrame(data = {'date': dates, 'actual': labels}) # 再创建一个表格来存日期和其对应的标签数值 months = test_features[:, feature_list.index('month')] days = test_features[:, feature_list.index('day')] years = test_features[:, feature_list.index('year')] # Column of dates test_dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)] # Convert to datetime objects test_dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in test_dates] # Dataframe with predictions and dates predictions_data = pd.DataFrame(data = {'date': test_dates, 'prediction': predictions}) AI写代码 python 运行 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # 真实值 plt.plot(true_data['date'], true_data['actual'], 'b-', label = 'actual') # 预测值 plt.plot(predictions_data['date'], predictions_data['prediction'], 'ro', label = 'prediction') plt.xticks(rotation = '60'); plt.legend() # 画图 plt.xlabel('Date') plt.ylabel('Maximum Temperature (F)') plt.title('Actual and Predicted Values') AI写代码 python 运行 1 2 3 4 5 6 7 8 9 10 此图显示出数据的走势,证明我们已经基本能够掌握此模型了,接下来就是要深入到数据中,做更精细的调整! ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.youkuaiyun.com/qq_42549612/article/details/105304889帮我写一份报告
08-08
### 3.1 数据处理 在进行随机森林算法建模之前,首先需要完成数据的采集与预处理工作。数据来源可以包括空气质量监测站的历史数据、气象数据、地理信息数据等多源数据。对于采集到的原始数据,需要进行缺失值填补、异常值处理、数据标准化等操作,以确保后续建模过程的准确性。 在数据清洗过程中,通常采用插值法、均值替代法或基于时间序列的预测填补方法处理缺失值;对于异常值,可以通过Z-score方法或IQR方法进行识别并修正。此外,为了提升模型的泛化能力,还可以对数据进行归一化或标准化处理,例如使用`StandardScaler`将数据转换为均值为0、标准差为1的分布[^2]。 ```python from sklearn.preprocessing import StandardScaler scaler = StandardScaler() scaled_data = scaler.fit_transform(raw_data) ``` ### 3.2 特征工程 特征工程是提升模型性能的关键环节。在温度预测任务中,原始特征可能包括时间戳、气温、湿度、风速、风向、气压、降水量等。为了提升模型的表达能力,可以构造新的特征,例如滑动窗口统计特征(如过去24小时平均温度、标准差)、时间特征(如小时、星期几、是否为节假日)等。 此外,还可以引入滞后特征(Lagged Features),即利用前几个时间点的观测值作为当前时刻的输入特征,以捕捉时间序列的动态变化趋势。特征编码方面,对于类别型变量(如天气状况),可以采用One-Hot编码或目标编码(Target Encoding)进行处理。 ### 3.3 模型构建 随机森林是一种集成学习方法,通过构建多个决策树并对其预测结果进行集成,具有较强的抗过拟合能力和对非线性关系的建模能力。在构建模型时,需要将数据划分为训练集和测试集,通常采用时间序列划分方式,以避免未来信息泄露。 ```python from sklearn.ensemble import RandomForestRegressor from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(features, target, test_size=0.2, shuffle=False) rf_model = RandomForestRegressor(n_estimators=100, random_state=42) rf_model.fit(X_train, y_train) ``` 模型训练完成后,可以使用均方误差(MSE)、平均绝对误差(MAE)等指标评估模型性能。 ### 3.4 可视化分析 可视化分析有助于理解模型预测结果与实际值之间的差异。可以绘制预测值与真实值的对比曲线、残差图、误差分布直方图等。例如,使用Matplotlib绘制预测温度与实际温度的时序对比图: ```python import matplotlib.pyplot as plt plt.figure(figsize=(12, 6)) plt.plot(y_test.values, label='Actual') plt.plot(predictions, label='Predicted') plt.legend() plt.title('Temperature Prediction vs Actual') plt.xlabel('Time') plt.ylabel('Temperature (°C)') plt.show() ``` 此外,还可以使用SHAP(SHapley Additive exPlanations)库对模型的预测结果进行可解释性分析,帮助理解每个特征对预测值的贡献程度。 ### 3.5 特征重要性评估 随机森林模型内置了特征重要性的评估机制,可以通过`feature_importances_`属性获取每个特征的重要性得分。这些得分反映了各特征对模型预测结果的影响程度,有助于特征选择与模型优化。 ```python import pandas as pd importances = rf_model.feature_importances_ feature_names = features.columns feature_importance_df = pd.DataFrame({'Feature': feature_names, 'Importance': importances}) feature_importance_df = feature_importance_df.sort_values(by='Importance', ascending=False) print(feature_importance_df) ``` 通过可视化特征重要性排序图,可以直观识别出对温度预测影响最大的变量,从而优化特征集,提升模型效率。 ### 3.6 模型优化与调参 为了进一步提升模型性能,可以对随机森林的关键超参数进行调优,例如决策树的数量(`n_estimators`)、最大深度(`max_depth`)、最小样本分割数(`min_samples_split`)等。常用的方法包括网格搜索(Grid Search)和贝叶斯优化。 ```python from sklearn.model_selection import GridSearchCV param_grid = { 'n_estimators': [100, 200], 'max_depth': [None, 10, 20], 'min_samples_split': [2, 5] } grid_search = GridSearchCV(estimator=RandomForestRegressor(random_state=42), param_grid=param_grid, scoring='neg_mean_absolute_error', cv=5, n_jobs=-1) grid_search.fit(X_train, y_train) best_model = grid_search.best_estimator_ ``` 通过交叉验证的方式评估不同参数组合下的模型性能,选择最优参数配置。调参后,再次评估模型在测试集上的表现,确保模型泛化能力得到提升。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值