目录
相关性过滤
相关性过滤的意义
方差挑选完毕之后,我们就要考虑下一个问题:相关性了。我们希望选出与标签相关且有意义的特征,因为这样的特征能够为我们提供大量信息。如果特征与标签无关,那只会白白浪费我们的计算内存,可能还会给模型带来噪音。
相关性过滤的分类
在sklearn当中,我们有三种常用的方法来评判特征与标签之间的相关性:卡方,F检验,互信息。
1、卡方滤波
卡方过滤是专门针对离散型标签(即分类问题)的相关性过滤
另外,如果卡方检验检测到某个特征中所有的值都相同,会提示我们使用方差先进行方差过滤。并且,刚才我们已经验证过,当我们使用方差过滤筛选掉一半的特征后,模型的表现时提升的。因此在这里,我们使用threshold=中位数时完成的方差过滤的数据来做卡方检验(如果方差过滤后模型的表现反而降低了,那我们就不会使用方差过滤后的数据,而是使用原数据):
from sklearn.ensemble import RandomForestClassifier as RFC #随机森林
from sklearn.model_selection import cross_val_score
from sklearn.feature_selection import SelectKBest #选出前k个分数最高的特征的类
form sklearn.feature_selection import chi2 #卡方检验类
x_fschi=SelectKBest(chi2,k=300).fit_transform(x_fsvar,y)
#x_fsvar是前面方差过滤一般特征的数据
x_fschi.shape
#输出
>(42000,300)
验证一下模型的效果:
cross_val_score(RFC(n_estimators=10,random_state=0),x_fschi,y,cv=5).mean()
#输出
>0.9344761904761905
可以看出,模型的效果降低了,这说明我们在设定k=300的时候删除了与模型相关且有效的特征,我们的K值设置得太小,要么我们需要调整K值,要么我们必须放弃相关性过滤。当然,如果模型的表现提升,则说明我们的相关性过滤是有效的,是过滤掉了模型的噪音的,这时候我们就保留相关性过滤的结果。
1.2选取超参数K
在现实数据中,数据量很大,模型很复杂的时候,我们是希望最开始就能够选择一个最优的超参数k。
方法一:跑学习曲线
import matplotlib.pyplot as plt
#======【TIME WARNING: 5 mins】======#
score = []
for i in range(200,390,10):
x_fschi = SelectKBest(chi2,k=i).fit_transform(x_fsvar,y)
once = cross_val_score(RFC(n_estimators=10,random_state=0),x_fschi,y,cv=5).mean()
score.append(once)
plt.plot(range(200,390,10),score)
plt.show()
#输出
通过这条曲线,我们可以观察到,随着k值的不断增加, 模型的表现不断上升,这说明,k越大越好,数据中所有的特征都是与特征相关的。但是运行这条曲线的时间同样也是十分的长,接下来介绍一种更好的选择k的方法:看p值选择k
方法二:看p值选择k(推荐,因为学习曲线运行时间长)
卡方检验的本质是推测两组数据之间的差异,其检验的原假设是”两组数据是相互独立的”。卡方检验返回卡方值和P值两个统计量,其中卡方值很难界定有效的范围,而p值,我们一般使用0.01或0.05作为显著性水平,即p值判断的边界,具体我们可以这样来看:
从特征工程的角度,我们希望选取卡方值很大,p值小于0.05的特征,即和标签是相关联的特征。
调用SelectKBest之前,我们可以直接从chi2实例化后的模型中获得各个特征所对应的卡方值和P值。
chivalue, pvalues_chi = chi2(x_fsvar,y)
#卡方
chivalue
chivalue.shape[0]
#输出 392
#p值
pvalues_chi
#k取多少?我们想要消除所有p值大于设定值,比如0.05或0.01的特征
k = chivalue.shape[0] - (pvalues_chi>0.05).sum()
#也可以直接写成k = (pvalues_chi<=0.05).sum()
k
#输出 392 #特征数没有变,即卡方检验没有删除任何特征。
可以观察到,所有特征的p值都是0,这说明对于digit recognizor这个数据集来说,方差验证已经把所有和标签无关的特征都剔除了,或者这个数据集本身就不含与标签无关的特征。在这种情况下,舍弃任何一个特征,都会舍弃对模型有用的信息,而使模型表现下降,因此在我们对计算速度感到满意时,我们不需要使用相关性过滤来过滤我们的数据。
x_fschi = SelectKBest(chi2,k=看p值选择k).fit_transform(x_fsvar,y)
cross_val_score(RFC(n_estimators=10,random_state=0),x_fschi,y,cv=5).mean()
如果我们认为运算速度太缓慢,那我们可以酌情删除一些特征, 但前提是,我们必须牺牲模型的表现。接下来,我们试试看用其他的相关性过滤方法验证一下我们在这个数据集 上的结论。