我使用sns.heatmap进行特征选择,同时使用sklearn的feature_importances进行另一项特征选择。
当使用相同的数据时,我得到了两个不同的值。
以及热图代码
from matplotlib import pyplot as pltimport pandas as pdimport numpy as npimport seaborn as snstraining_data = pd.read_csv( "/Users/aus10/NFL/Data/Betting_Data/CBB/Training_Data_Betting_CBB.csv")df_model = training_data.copy()df_model = df_model.dropna()df_model = df_model.drop(['Money_Line', 'Money_Line_Percentage', 'Money_Line_Money', 'Money_Line_Move', 'Money_Line_Direction', "Spread", 'Spread_Percentage', 'Spread_Money', 'Spread_Move', 'Spread_Direction', "Win", "Money_Line_Percentage", 'Cover'], axis=1)X = df_model.loc[:, ['Total', 'Total_Move', 'Over_Percentage', 'Over_Money', 'Under_Percentage', 'Under_Money']] # independent columnsy = df_model['Over_Under'] # target column# get correlations of each features in datasetcorrmat = df_model.corr()top_corr_features = corrmat.indexplt.figure(figsize=(20, 20))# plot heat mapg = sns.heatmap( df_model[top_corr_features].corr(), annot=True, cmap='hot')plt.xticks(rotation=90)plt.yticks(rotation=45)plt.show()
以及代码
import pandas as pdimport numpy as npfrom sklearn.ensemble import RandomForestClassifierimport matplotlib.pyplot as pltfrom sklearn.model_selection import StratifiedKFoldfrom sklearn.inspection import permutation_importancetraining_data = pd.read_csv( "/Users/aus10/NFL/Data/Betting_Data/CBB/Training_Data_Betting_CBB.csv", index_col=False)df_model = training_data.copy()df_model = df_model.dropna()X = df_model.loc[:, ['Total', 'Total_Move', 'Over_Percentage', 'Over_Money', 'Under_Percentage', 'Under_Money']] # independent columnsy = df_model['Over_Under'] # target columnmodel = RandomForestClassifier( random_state=1, n_estimators=100, min_samples_split=100, max_depth=5, min_samples_leaf=2)skf = StratifiedKFold(n_splits=2)skf.get_n_splits(X, y)StratifiedKFold(n_splits=2, random_state=None, shuffle=False)for train_index, test_index in skf.split(X, y): X_train, X_test = X.iloc[train_index], X.iloc[test_index] y_train, y_test = y.iloc[train_index], y.iloc[test_index]model.fit(X_train, y_train)# use inbuilt class feature_importances of tree based classifiersprint(model.feature_importances_)# plot graph of feature importances for better visualizationfeat_importances = pd.Series(model.feature_importances_, index=X.columns)perm_importance = permutation_importance(model, X_test, y_test)feat_importances.nlargest(5).plot(kind='barh')print(perm_importance)plt.show()
我不确定哪个更准确,或者我是否正确使用了它们?我应该使用热图来消除共线性,使用特征重要性来实际选择我的特征组吗?
回答:
你在比较两种不同的东西,为什么期望它们相同?在这种情况下,这意味着什么呢?
基于树的模型中的特征重要性是根据给定特征用于分裂的次数计算的。用于分裂次数较多的特征对于特定模型(使用特定数据集训练)来说比使用较少的特征更重要。
另一方面,相关性是衡量两个特征之间线性关系的指标。
我不确定哪个更准确
你所说的准确是什么意思?这两个指标在它们所衡量的内容上都是准确的。只是它们都没有直接告诉你应该丢弃哪些特征。
请注意,仅仅因为两个特征相关,并不意味着你可以自动丢弃其中一个。共线性可能会导致模型的可解释性出现问题。如果你有高度相关的特征,那么你就无法根据与这些特征相关的权重来判断哪个更重要。共线性不应该影响模型的预测能力。更常见的情况是,通过丢弃一个相关的特征,你的模型预测能力会下降。
因此,数据集中的共线性可能会使你的随机森林模型的特征重要性在某种意义上变得不太可解释,因为你不能完全依赖它们的严格顺序。但同样,它不应该影响模型的预测能力(除了模型更容易因为拥有更多自由度而过拟合)。
我应该使用热图来消除共线性,使用特征重要性来实际选择我的特征组吗?
特征工程/选择更多是一门艺术而非科学(除了端到端深度学习之外)。这里没有正确答案,你需要发展自己的启发式方法,并尝试不同的事情,看看在哪种情况下哪种方法效果更好。
基于特征重要性和相关性的一种简单启发式方法的例子可以是(假设你有大量特征):
- 拟合随机森林模型并测量特征重要性
- 丢弃那些似乎对模型没有影响的特征(接近0的重要性)
- 使用原始数据的新子集重新拟合模型,并查看你的关注指标(准确性、MSE等)是否与步骤1中大致相同
- 如果你仍然有很多特征,可以重复步骤1-3,增加丢弃阈值,直到你的关注指标开始变差
- 测量你剩余特征的相关性,并选择最相关的配对(基于某个阈值,例如(|c| > 0.8))
- 选择一个配对;丢弃该配对中的一个特征;测量模型性能;返回被丢弃的特征;对每个配对重复此操作
- 根据步骤6的结果,丢弃似乎对模型性能影响最小的特征
- 重复步骤6-7,直到模型性能开始下降