马鞍山网站建设cnfg,上海网站推荐,北京市门户网站,怎么推广自己的微信作者 | Pier Paolo Ippolito翻译 | Skura编辑 | 唐里原文标题#xff1a;Feature Selection Techniques据《福布斯》报道#xff0c;每天大约会有 250 万字节的数据被产生。然后#xff0c;可以使用数据科学和机器学习技术对这些数据进行分析#xff0c;以便提供分析和作出…作者 | Pier Paolo Ippolito翻译 | Skura编辑 | 唐里原文标题Feature Selection Techniques据《福布斯》报道每天大约会有 250 万字节的数据被产生。然后可以使用数据科学和机器学习技术对这些数据进行分析以便提供分析和作出预测。尽管在大多数情况下在开始任何统计分析之前需要先对最初收集的数据进行预处理。有许多不同的原因导致需要进行预处理分析例如收集的数据格式不对(如 SQL 数据库、JSON、CSV 等)缺失值和异常值标准化减少数据集中存在的固有噪声(部分存储数据可能已损坏)数据集中的某些功能可能无法收集任何信息以供分析在本文中我将介绍如何使用 python 减少 kaggle Mushroom Classification 数据集中的特性数量。本文中使用的所有代码在 kaggle 和我的 github 帐号上都有。减少统计分析期间要使用的特征的数量可能会带来一些好处例如提高精度降低过拟合风险加快训练速度改进数据可视化增加我们模型的可解释性事实上统计上证明当执行机器学习任务时存在针对每个特定任务应该使用的最佳数量的特征(图 1)。如果添加的特征比必要的特征多那么我们的模型性能将下降(因为添加了噪声)。真正的挑战是找出哪些特征是最佳的使用特征(这实际上取决于我们提供的数据量和我们正在努力实现的任务的复杂性)。这就是特征选择技术能够帮到我们的地方图 1分类器性能和维度之间的关系1、特征选择有许多不同的方法可用于特征选择。其中最重要的是1)过滤方法过滤我们的数据集只取包含所有相关特征的子集(例如使用 Pearson 相关的相关矩阵)。2)遵循过滤方法的相同目标但使用机器学习模型作为其评估标准(例如向前/向后/双向/递归特征消除)。我们将一些特征输入机器学习模型评估它们的性能然后决定是否添加或删除特征以提高精度。因此这种方法可以比滤波更精确但计算成本更高。3)嵌入方法。与过滤方法一样嵌入方法也使用机器学习模型。这两种方法的区别在于嵌入的方法检查 ML 模型的不同训练迭代然后根据每个特征对 ML 模型训练的贡献程度对每个特征的重要性进行排序。图 2过滤器、包装器和嵌入式方法表示 [3]2、实践在本文中我将使用 Mushroom Classification 数据集通过查看给定的特征来尝试预测蘑菇是否有毒。在这样做的同时我们将尝试不同的特征消除技术看看它们会如何影响训练时间和模型整体的精度。首先我们需要导入所有必需的库。我们将在本例中使用的数据集如下图所示。图 3Mushroom Classification 数据集在将这些数据输入机器学习模型之前我决定对所有分类变量进行 one hot 编码将数据分为特征(x)和标签(y)最后在训练集和测试集中进行。X df.drop([class], axis 1)Y df[class]X pd.get_dummies(X, prefix_sep_)Y LabelEncoder().fit_transform(Y)X2 StandardScaler().fit_transform(X)X_Train, X_Test, Y_Train, Y_Test train_test_split(X2, Y, test_size 0.30, random_state 101)3、特征重要性基于集合的决策树模型(如随机森林)可以用来对不同特征的重要性进行排序。了解我们的模型最重要的特征对于理解我们的模型如何做出预测(使其更易于解释)是至关重要的。同时我们可以去掉那些对我们的模型没有任何好处的特征。start time.process_time()trainedforest RandomForestClassifier(n_estimators700).fit(X_Train,Y_Train)print(time.process_time() - start)predictionforest trainedforest.predict(X_Test)print(confusion_matrix(Y_Test,predictionforest))print(classification_report(Y_Test,predictionforest))如下图所示使用所有特征训练一个随机森林分类器在大约 2.2 秒的训练时间内获得 100% 的准确率。在下面的每个示例中每个模型的训练时间都将打印在每个片段的第一行供你参考。一旦我们的随机森林分类器得到训练我们就可以创建一个特征重要性图看看哪些特征对我们的模型预测来说是最重要的(图 4)。在本例中下面只显示了前 7 个特性。figure(numNone, figsize(20, 22), dpi80, facecolorw, edgecolork)feat_importances pd.Series(trainedforest.feature_importances_, index X.columns) feat_importances.nlargest(7).plot(kindbarh)图 4特征重要性图现在我们知道了哪些特征被我们的随机森林认为是最重要的我们可以尝试使用前 3 个来训练我们的模型。X_Reduced X[[odor_n,odor_f, gill-size_n,gill-size_b]]X_Reduced StandardScaler().fit_transform(X_Reduced)X_Train2, X_Test2, Y_Train2, Y_Test2 train_test_split(X_Reduced, Y, test_size 0.30, random_state 101)start time.process_time()trainedforest RandomForestClassifier(n_estimators700).fit(X_Train2,Y_Train2)print(time.process_time() - start)predictionforest trainedforest.predict(X_Test2)print(confusion_matrix(Y_Test2,predictionforest))print(classification_report(Y_Test2,predictionforest))正如我们在下面看到的仅仅使用 3 个特征只会导致准确率下降 0.03%训练时间减少一半。我们还可以通过可视化一个训练过的决策树来理解如何进行特征选择。start time.process_time()trainedtree tree.DecisionTreeClassifier().fit(X_Train, Y_Train)print(time.process_time() - start)predictionstree trainedtree.predict(X_Test)print(confusion_matrix(Y_Test,predictionstree)) print(classification_report(Y_Test,predictionstree))树结构顶部的特征是我们的模型为了执行分类而保留的最重要的特征。因此只选择顶部的前几个特征而放弃其他特征可能创建一个准确度非常可观的模型。import graphvizfrom sklearn.treeimport DecisionTreeClassifier, export_graphvizdata export_graphviz(trainedtree,out_fileNone,feature_names X.columns, class_names[edible, poisonous], filledTrue, roundedTrue, max_depth2, special_charactersTrue)graph graphviz.Source(data)graph图 5决策树可视化4、递归特征消除(RFE)递归特征消除(RFE)将机器学习模型的实例和要使用的最终期望特征数作为输入。然后它递归地减少要使用的特征的数量采用的方法是使用机器学习模型精度作为度量对它们进行排序。创建一个 for 循环其中输入特征的数量是我们的变量这样就可以通过跟踪在每个循环迭代中注册的精度找出我们的模型所需的最佳特征数量。使用 RFE 支持方法我们可以找出被评估为最重要的特征的名称(rfe.support 返回一个布尔列表其中 true 表示一个特征被视为重要false 表示一个特征不重要)。from sklearn.feature_selection import RFEmodel RandomForestClassifier(n_estimators700)rfe RFE(model, 4)start time.process_time()RFE_X_Train rfe.fit_transform(X_Train,Y_Train)RFE_X_Test rfe.transform(X_Test)rfe rfe.fit(RFE_X_Train,Y_Train)print(time.process_time() - start) print(Overall Accuracy using RFE: , rfe.score(RFE_X_Test,Y_Test))5、SelecFromModelselectfrommodel 是另一种 scikit 学习方法可用于特征选择。此方法可用于具有 coef 或 feature 重要性属性的所有不同类型的 scikit 学习模型(拟合后)。与 rfe 相比selectfrommodel 是一个不太可靠的解决方案。实际上selectfrommodel 只是根据计算出的阈值(不涉及优化迭代过程)删除不太重要的特性。为了测试 selectfrommodel 的有效性我决定在这个例子中使用一个 ExtraTreesClassifier。ExtratreesClassifier(极端随机树)是基于树的集成分类器与随机森林方法相比它可以产生更少的方差(因此减少了过拟合的风险)。随机森林和极随机树的主要区别在于极随机树中节点的采样不需要替换。from sklearn.ensemble import ExtraTreesClassifierfrom sklearn.feature_selection import SelectFromModelmodel ExtraTreesClassifier()start time.process_time()model model.fit(X_Train,Y_Train)model SelectFromModel(model, prefitTrue)print(time.process_time() - start)Selected_X model.transform(X_Train)start time.process_time()trainedforest RandomForestClassifier(n_estimators700).fit(Selected_X, Y_Train)print(time.process_time() - start)Selected_X_Test model.transform(X_Test)predictionforest trainedforest.predict(Selected_X_Test)print(confusion_matrix(Y_Test,predictionforest)) print(classification_report(Y_Test,predictionforest))6、相关矩阵分析为了减少数据集中的特征数量另一种可能的方法是检查特征与标签的相关性。使用皮尔逊相关我们的返回系数值将在-1 和 1 之间变化如果两个特征之间的相关性为 0则意味着更改这两个特征中的任何一个都不会影响另一个。如果两个特征之间的相关性大于 0这意味着增加一个特征中的值也会增加另一个特征中的值(相关系数越接近 1两个不同特征之间的这种联系就越强)。如果两个特征之间的相关性小于 0这意味着增加一个特征中的值将使减少另一个特征中的值(相关性系数越接近-1两个不同特征之间的这种关系将越强)。在这种情况下我们将只考虑与输出变量至少 0.5 相关的特性。Numeric_df pd.DataFrame(X)Numeric_df[Y] Ycorr Numeric_df.corr()corr_y abs(corr[Y])highest_corr corr_y[corr_y 0.5] highest_corr.sort_values(ascendingTrue)我们现在可以通过创建一个相关矩阵来更仔细地研究不同相关特征之间的关系。figure(numNone, figsize(12, 10), dpi80, facecolorw, edgecolork)corr2 Numeric_df[[bruises_f , bruises_t , gill-color_b , gill-size_b , gill-size_n , ring-type_p , stalk-surface-below-ring_k , stalk-surface-above-ring_k , odor_f, odor_n]].corr()sns.heatmap(corr2, annotTrue, fmt.2g)图 6最高相关特征的相关矩阵在这项分析中另一个可能要控制的方面是检查所选变量是否彼此高度相关。如果是的话我们就只需要保留其中一个相关的去掉其他的。最后我们现在可以只选择与 y 相关度最高的特征训练/测试一个支持向量机模型来评估该方法的结果。7、单变量选择单变量特征选择是一种统计方法用于选择与我们对应标签关系最密切的特征。使用 selectkbest 方法我们可以决定使用哪些指标来评估我们的特征以及我们希望保留的 k 个最佳特征的数量。根据我们的需要提供不同类型的评分函数Classification chi2, f_classif, mutual_info_classifRegression f_regression, mutual_info_regression在本例中我们将使用 chi2(图 7)。图 7卡方公式 [4]卡方(chi-squaredchi2)可以将非负值作为输入因此首先我们在 0 到 1 之间的范围内缩放输入数据。from sklearn.feature_selection import SelectKBestfrom sklearn.feature_selection import chi2min_max_scaler preprocessing.MinMaxScaler()Scaled_X min_max_scaler.fit_transform(X2)X_new SelectKBest(chi2, k2).fit_transform(Scaled_X, Y)X_Train3, X_Test3, Y_Train3, Y_Test3 train_test_split(X_new, Y, test_size 0.30, random_state 101)start time.process_time()trainedforest RandomForestClassifier(n_estimators700).fit(X_Train3,Y_Train3)print(time.process_time() - start)predictionforest trainedforest.predict(X_Test3)print(confusion_matrix(Y_Test3,predictionforest)) print(classification_report(Y_Test3,predictionforest))8、套索回归当将正则化应用于机器学习模型时我们在模型参数上加上一个惩罚以避免我们的模型试图太接近我们的输入数据。通过这种方式我们可以使我们的模型不那么复杂并且我们可以避免过度拟合(使我们的模型不仅学习关键的数据特征而且学习它的内在噪声)。其中一种可能的正则化方法是套索回归。当使用套索回归时如果输入特征的系数对我们的机器学习模型训练没有积极的贡献则它们会缩小。这样一些特征可能会被自动丢弃即将它们的系数指定为零。from sklearn.linear_model import LassoCVregr LassoCV(cv5, random_state101)regr.fit(X_Train,Y_Train)print(LassoCV Best Alpha Scored: , regr.alpha_)print(LassoCV Model Accuracy: , regr.score(X_Test, Y_Test))model_coef pd.Series(regr.coef_, index list(X.columns[:-1]))print(Variables Eliminated: , str(sum(model_coef 0))) print(Variables Kept: , str(sum(model_coef ! 0)))一旦训练了我们的模型我们就可以再次创建一个特征重要性图来了解哪些特征被我们的模型认为是最重要的(图 8)。这是非常有用的尤其是在试图理解我们的模型是如何决定做出预测的时候因此使我们的模型更易于解释。figure(numNone, figsize(12, 10), dpi80, facecolorw, edgecolork)top_coef model_coef.sort_values()top_coef[top_coef ! 0].plot(kind barh) plt.title(Most Important Features Identified using Lasso (!0))图 8套索特征重要性图