mutual_info_classif 独立使用和通过 SelectKBest 使用时的不同分数
Different scores when mutual_info_classif used independently and through SelectKBest
我正在尝试 select 60,000 个中的数百个功能,为此我想使用 mutual_info_classif。
但是我看到,与使用 SelectKBest 相比,直接使用 mutual_info_classif 得到的结果不同。
为了演示它,我定义了一个小的 df,其中只有 1 列与目标相关:
A B C D E target
0 1 1 1 1 1 1
1 2 3 2 2 2 0
2 3 3 3 3 3 0
3 4 3 4 4 4 0
4 5 1 5 5 5 1
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import mutual_info_classif
df = pd.DataFrame({'A':[1,2,3,4,5],
'B':[1,3,3,3,1],
'C':[1,2,3,4,5],
'D':[1,2,3,4,5],
'E':[1,2,3,4,5],
'target':[1,0,0,0,1]})
X = df.drop(['target'],axis=1)
y = df.target
threshold = 3 # the number of most relevant features
然后我使用 mutual_info_classif:
得到 MI 分数
high_score_features1 = []
feature_scores = mutual_info_classif(X, y, random_state=0, n_neighbors=3,discrete_features='auto')
for score, f_name in sorted(zip(feature_scores, X.columns), reverse=True)[:threshold]:
print(f_name, score)
high_score_features1.append(f_name)
feature_scores
输出:
B 0.48333333333333306
E 0.0
D 0.0
array([0. , 0.48333333, 0. , 0. , 0. ])
然后我使用 SelectKBest,并确保使用相同的参数,我使用我自己的调用:
def my_func(X, y):
return mutual_info_classif(X, y, random_state=0, n_neighbors=3, discrete_features='auto')
high_score_features1=[]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
f_selector = SelectKBest(score_func=my_func, k=threshold)
f_selector.fit(X_train, y_train)
for score, f_name in sorted(zip(f_selector.scores_, X.columns), reverse=True)[:threshold]:
print(f_name, score)
high_score_features1.append(f_name)
f_selector.scores_
输出:
B 0.8333333333333331
E 0.0
D 0.0
array([0. , 0.83333333, 0. , 0. , 0. ])
我不明白差异的来源,我不确定哪种方式对我的真实数据更可靠。
您在直接使用 mutual_info_classif
模型和使用 SelectKBest
模型之间得到不同结果的原因似乎是因为您在不同的数据集上拟合它们。您的 SelectKBest
模型适用于训练集,而您的 mutual_info_classif
模型适用于整个数据。如果您在训练数据上拟合两个模型,那么两个模型都会给出相同的输出。
我正在尝试 select 60,000 个中的数百个功能,为此我想使用 mutual_info_classif。
但是我看到,与使用 SelectKBest 相比,直接使用 mutual_info_classif 得到的结果不同。
为了演示它,我定义了一个小的 df,其中只有 1 列与目标相关:
A B C D E target
0 1 1 1 1 1 1
1 2 3 2 2 2 0
2 3 3 3 3 3 0
3 4 3 4 4 4 0
4 5 1 5 5 5 1
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import mutual_info_classif
df = pd.DataFrame({'A':[1,2,3,4,5],
'B':[1,3,3,3,1],
'C':[1,2,3,4,5],
'D':[1,2,3,4,5],
'E':[1,2,3,4,5],
'target':[1,0,0,0,1]})
X = df.drop(['target'],axis=1)
y = df.target
threshold = 3 # the number of most relevant features
然后我使用 mutual_info_classif:
得到 MI 分数high_score_features1 = []
feature_scores = mutual_info_classif(X, y, random_state=0, n_neighbors=3,discrete_features='auto')
for score, f_name in sorted(zip(feature_scores, X.columns), reverse=True)[:threshold]:
print(f_name, score)
high_score_features1.append(f_name)
feature_scores
输出:
B 0.48333333333333306
E 0.0
D 0.0
array([0. , 0.48333333, 0. , 0. , 0. ])
然后我使用 SelectKBest,并确保使用相同的参数,我使用我自己的调用:
def my_func(X, y):
return mutual_info_classif(X, y, random_state=0, n_neighbors=3, discrete_features='auto')
high_score_features1=[]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
f_selector = SelectKBest(score_func=my_func, k=threshold)
f_selector.fit(X_train, y_train)
for score, f_name in sorted(zip(f_selector.scores_, X.columns), reverse=True)[:threshold]:
print(f_name, score)
high_score_features1.append(f_name)
f_selector.scores_
输出:
B 0.8333333333333331
E 0.0
D 0.0
array([0. , 0.83333333, 0. , 0. , 0. ])
我不明白差异的来源,我不确定哪种方式对我的真实数据更可靠。
您在直接使用 mutual_info_classif
模型和使用 SelectKBest
模型之间得到不同结果的原因似乎是因为您在不同的数据集上拟合它们。您的 SelectKBest
模型适用于训练集,而您的 mutual_info_classif
模型适用于整个数据。如果您在训练数据上拟合两个模型,那么两个模型都会给出相同的输出。