为什么我在热图和 feature_importances 中得到两个不同的值?

Why do I get two different values in heatmap and feature_importances?

我是 运行 一个使用 sns.heatmap 的特征选择和一个使用 sklearn feature_importances 的特征选择。

当使用相同的数据时,我得到两个不同的值。

这是热图

和热图代码

from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
import seaborn as sns

training_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 columns
y = df_model['Over_Under']  # target column

# get correlations of each features in dataset
corrmat = df_model.corr()
top_corr_features = corrmat.index
plt.figure(figsize=(20, 20))
# plot heat map
g = sns.heatmap(
    df_model[top_corr_features].corr(), annot=True, cmap='hot')

plt.xticks(rotation=90)
plt.yticks(rotation=45)

plt.show()

这是feature_importances条形图

和代码

import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
import matplotlib.pyplot as plt
from sklearn.model_selection import StratifiedKFold
from sklearn.inspection import permutation_importance

training_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 columns
y = df_model['Over_Under']  # target column

model = 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 classifiers
print(model.feature_importances_)
# plot graph of feature importances for better visualization
feat_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()

我不确定哪一个更准确或者我是否以正确的方式使用它们?我是否应该使用热图来消除共线性和特征重要性以实际选择我的特征组?

您正在比较两个不同的事物,为什么您会期望它们相同?在这种情况下它甚至意味着什么?

基于树的模型中的特征重要性是根据给定特征用于拆分的次数计算的。更常用于拆分的特征比不常使用的特征更重要(对于适合特定数据集的特定模型)。

另一方面,相关性是衡量两个特征之间线性关系的指标。

I'm not sure which one is more accurate

准确度是什么意思?这两者在它们所测量的方面都是准确的。只是这些none直接告诉你哪个feature/s要扔掉

请注意,仅仅因为 2 个特征相关,并不意味着您可以自动丢弃其中一个。共线性会导致模型的可解释性问题。如果你有高度相关的特征,那么你不能根据与这些特征相关的权重来判断哪个更重要。共线性不应影响模型的预测能力。更多时候,您会发现通过丢弃其中一个相关特征,您的模型的预测能力会降低。

因此,数据集中的共线性会使随机 Forrest 模型的特征重要性变得难以解释,因为您不能依赖它们的严格排序。但同样,它不应该影响模型的预测能力(除了模型由于具有更多自由度而更容易过度拟合)。

Should I being using the heatmap to eliminate collinearity and the feature importances to actually selection my group of features?

特征 engineering/selection 与其说是科学,不如说是一门艺术(端到端深度学习除外)。这里没有正确答案,您需要开发自己的启发式方法并尝试不同的方法,看看哪种方法在哪种情况下效果更好。

基于特征重要性和相关性的简单启发式示例可以是(假设您有大量特征):

  1. 拟合随机 forrest 模型并测量特征重要性
  2. 扔掉那些似乎对模型没有影响的(接近于0的重要性)
  3. 使用原始数据的新子集重新拟合模型,并查看您感兴趣的指标(准确性、MSE 等)是否与步骤 1 中的大致相同。
  4. 如果你还有很多特征,你可以重复步骤 1-3,增加一次性阈值,直到你感兴趣的指标开始恶化
  5. 衡量您剩下的特征与select最相关对的相关性(基于某个阈值,例如 (|c| > 0.8))
  6. 选一对;从这对中删除一个特征;测量模型性能; return 删除的功能;每对重复
  7. 根据第 6 步的结果,删除似乎对模型性能负面影响最小的特征。
  8. 重复步骤 6-7 直到模型的性能开始下降