马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
一、方法介绍
(一)定义
在机器学习中,特性选择是一个至关紧张的环节,其目的是从原始特性聚集中挑选出最具代表性和信息量的特性子集,使得在该子集上构建的机器学习模型能够达到最佳的预测或分类效果。
在现实的数据集里,每每存在大量的特性,此中一些特性大概与目的变量高度相关,对模型的预测有紧张贡献;而另一些特性大概是冗余的、不相关的以致会对模型产生干扰,增加模型的复杂度和噪声。
(二)特性选择方法
特性选择方法通常可以分为三类:过滤式方法、包裹式方法和嵌入式方法。
1.过滤式方法:独立于模型,在模型训练之前基于数据的内在特性对特性进行评估和选择,计算速度快,但大概无法充分思量特性与特定模型的相互作用。
2.包裹式方法:以特定的机器学习模型为基础,将特性选择过程视为一个搜索问题,通过在特性子集空间中进行搜索,以模型在验证集上的性能作为评价标准来选择最优特性子集,这种方法通常能获得较好的效果,但计算成本较高。
3.嵌入式方法:将特性选择与模型训练过程相联合,在模型训练的过程中自动进行特性选择,例如Lasso回归通过在损失函数中添加L1正则化项,使得模型在训练过程中自动将一些不紧张的特性的系数收缩为零,从而实现特性选择的目的。
(三)应用
在生物信息学中,通过特性选择可以从大量的基因表达数据中筛选出与疾病相关的关键基因;
在自然语言处置惩罚中,能够从浩繁的文本特性中选择出最能代表文本主题和语义的特性,提高文本分类和情感分析等任务的准确性;
在图像辨认领域,有助于从海量的图像特性中提取出最具鉴别力的特性,低沉模型的复杂度,提高辨认效率。
二、基于树的特性选择方法
基于树的特性选择方法是机器学习中一种紧张且广泛应用的特性选择技术,它主要基于决议树或树集成模型来评估和选择特性。
(一)决议树
决议树是一种基于树布局的分类或回归模型,其核心思想是通过对特性进行递归的划分,将样本空间逐步划分为差异的子空间,使得每个子空间内的样本尽大概属于同一种别或具有相似的数值。在决议树的构建过程中,通过计算每个特性的信息增益,并选择信息增益最大的特性作为分裂特性,决议树能够自动地对特性进行排序和筛选,在树的生长过程中,那些对分类或回归没有太大贡献的特性每每不会被选择为分裂特性,从而实现了特性选择的效果。
(二)树集成模型
树集成模型如随机丛林(Random Forest)和梯度提拔树(Gradient Boosting Tree)等,也被广泛用于特性选择。在随机丛林中,包含了多个决议树,通过对训练数据进行有放回的抽样构建多个子数据集,然后分别训练决议树,最后综合多个决议树的结果进行预测。在这个过程中,可以通过计算每个特性在全部决议树中的均匀紧张性得分来评估特性的紧张性。
(三)长处与缺点
1.不需要对数据进行复杂的预处置惩罚和归一化操纵,能够处置惩罚各种类型的数据,包括数值型、分类型等。
2.树模型具有很好的可解释性,通过观察树的布局和特性的分裂情况,可以直观地了解每个特性对模型决议的影响。
3.树集成模型的计算成本相对较高,特别是在处置惩罚大规模数据集时,需要消耗较多的时间和计算资源。
- import numpy as np
- import matplotlib.pyplot as plt
- from sklearn.datasets import load_diabetes
- from sklearn.ensemble import GradientBoostingRegressor
- from sklearn.model_selection import train_test_split
- from sklearn.metrics import r2_score
- try:
- # 加载糖尿病数据集
- diabetes = load_diabetes()
- X = diabetes.data
- y = diabetes.target
- # 数据集划分(添加stratify保证数据分布一致性)
- X_train, X_test, y_train, y_test = train_test_split(
- X, y,
- test_size=0.2,
- random_state=42,
- shuffle=True
- )
- # 创建并训练GBM模型(添加提前停止机制)
- gbm = GradientBoostingRegressor(
- n_estimators=200,
- learning_rate=0.05,
- max_depth=3,
- random_state=42,
- n_iter_no_change=10, # 添加提前停止
- validation_fraction=0.1
- )
- gbm.fit(X_train, y_train)
- # 模型评估
- y_pred = gbm.predict(X_test)
- r2 = r2_score(y_test, y_pred)
- print(f"\n模型性能评估:")
- print(f"测试集 R² 分数: {r2:.4f}")
- print(f"使用特征数: {X.shape[1]}")
- print(f"最佳迭代次数: {gbm.n_estimators_}")
- # 特征重要性处理
- feature_importance = gbm.feature_importances_
- sorted_idx = np.argsort(feature_importance)[::-1] # 降序排列
- sorted_features = np.array(diabetes.feature_names)[sorted_idx]
- sorted_importance = feature_importance[sorted_idx]
- # 可视化优化
- plt.style.use('seaborn')
- plt.figure(figsize=(10, 6))
-
- # 创建颜色渐变效果
- colors = plt.cm.viridis(np.linspace(0.3, 1, len(sorted_idx)))
-
- bars = plt.barh(
- range(len(sorted_idx)),
- sorted_importance,
- align='center',
- color=colors,
- edgecolor='black'
- )
-
- # 添加数据标签
- for bar in bars:
- width = bar.get_width()
- plt.text(
- width + 0.005,
- bar.get_y() + bar.get_height()/2,
- f'{width:.3f}',
- va='center',
- fontsize=9
- )
- plt.yticks(range(len(sorted_idx)), sorted_features)
- plt.xlabel('Feature Importance Score', fontsize=12)
- plt.title('Diabetes Dataset Feature Importance (GBM)', fontsize=14, pad=20)
- plt.gca().invert_yaxis() # 反转y轴
- plt.xlim(0, max(sorted_importance)*1.15) # 为标签留出空间
- plt.grid(axis='x', alpha=0.3)
- plt.tight_layout()
-
- # 保存图表
- plt.savefig('feature_importance.png', dpi=300, bbox_inches='tight')
- plt.show()
- except Exception as e:
- print(f"\n程序执行出错: {str(e)}")
- print("建议检查:")
- print("1. 确保scikit-learn版本 >= 0.22 (提前停止功能需要)")
- print("2. 检查Python依赖包是否安装完整")
- print("3. 确认数据集加载是否正常")
- # 添加版本检查
- import sklearn
- print(f"\n当前环境版本:")
- print(f"scikit-learn: {sklearn.__version__}")
- print(f"numpy: {np.__version__}")
- print(f"matplotlib: {plt.matplotlib.__version__}")
复制代码 可以发现最紧张的两个特性变量是BMI和S5;
(二)自动特性选择
仍旧利用糖尿病数据集,自动特性选择的代码如下:
- import numpy as np
- from sklearn.datasets import load_diabetes
- from sklearn.ensemble import GradientBoostingRegressor
- from sklearn.feature_selection import RFECV
- from sklearn.model_selection import train_test_split, GridSearchCV, cross_val_score
- from sklearn.metrics import mean_squared_error
- import matplotlib.pyplot as plt
- # 加载糖尿病数据集
- diabetes = load_diabetes()
- X = diabetes.data
- y = diabetes.target
- # 将数据集划分为训练集和测试集
- X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
- # 初始化 GBM 模型
- gbm = GradientBoostingRegressor(random_state=42)
- # 使用网格搜索优化 GBM 超参数
- param_grid = {
- 'n_estimators': [50, 100, 200],
- 'learning_rate': [0.01, 0.1, 0.2],
- 'max_depth': [2, 3, 4]
- }
- grid_search = GridSearchCV(estimator=gbm, param_grid=param_grid, cv=5, scoring='neg_mean_squared_error')
- grid_search.fit(X_train, y_train)
- # 获取最佳模型
- best_gbm = grid_search.best_estimator_
- # 初始化 RFECV 进行特征选择
- rfecv = RFECV(estimator=best_gbm, step=1, cv=5, scoring='neg_mean_squared_error')
- # 进行特征选择
- rfecv.fit(X_train, y_train)
- # 获取选择的特征
- X_train_selected = rfecv.transform(X_train)
- X_test_selected = rfecv.transform(X_test)
- # 用选择的特征重新训练 GBM 模型
- best_gbm.fit(X_train_selected, y_train)
- # 预测测试集
- y_pred = best_gbm.predict(X_test_selected)
- # 计算 MSE
- mse = mean_squared_error(y_test, y_pred)
- print(f"Test MSE with selected features: {mse}")
- # 输出选择的特征索引
- print(f"Selected feature indices: {np.where(rfecv.support_)[0]}")
- # 可视化特征选择过程
- plt.figure()
- plt.xlabel("Number of features selected")
- plt.ylabel("Cross validation score (negative MSE)")
- plt.plot(range(1, len(rfecv.grid_scores_) + 1), rfecv.grid_scores_)
- plt.show()
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |