活用西瓜书——sklearn包中的特征选择函数的使用

引言

最近在读西瓜书,查阅了多方资料,恶补了数值代数、统计概率和线代,总算是勉强看懂了西瓜书中的公式推导。但是知道了公式以后还是要学会应用的,几经摸索发现python下的sklearn包把机器学习中经典的算法都封装好了,因此,打算写几篇博客记录一下sklearn包下的常用学习算法的使用,防止自己以后忘了,嘿嘿。

1.特征选择

特征选择是一个很重要的“数据预处理”过程,我们在做数据挖掘时拿到的数据一般都是包含很多个属性的,虽然理论上属性列越多,我们越能够从多方面详细地分析数据,但当数据列过多时我们处理起来非常耗费时间。并且有些属性对我们所关心的分类或回归结果贡献很小,甚至是不相关的,如果我们把这些属性纳入到需要学习的范畴,反而还会加大结果的误差,造成过拟合,因此我们需要通过一些方法筛选掉数据中一些对结果无影响或影响很小的属性,从而节省学习时间,提高结果的准确度。这种筛选掉无用属性的做法就是特征选择。

2.特征选择的常用方法

进行特征选择的方法主要有:

  1. 对每个属性进行方差计算,去除小方差属性。
  2. 对每个属性进行统计方法检验(如卡方独立性检验),根据统计检验的衡量标准,去除不达标的属性(递归特征消除)。
  3. 人为构造一个分类/回归器,使用该分类/回归器逐属性减少并进行预测结果精准度判定,递归决策出n-1、n-2…个属性的最优值。
  4. 人为构造一个分类/回归学习器,使用该学习器逐属性减少并按照该学习器衡量标准对实行的重要程度进行评分,在去掉评分较小的属性。

3.sklearn包中的特征选择函数

对于以上的集中特征选择方法,sklearn模块下的sklearn.feature_selection都为我们提供了相应的方法,以下为常用的方法与其函数对应表:

  1. 方差消除:sklearn.feature_selection.VarianceThreshold
  2. 统计检验:sklearn.feature_selection.SelectKBest
  3. 递归特征消除:sklearn.feature_selection.RFECV
  4. 利用学习器进行评分:sklearn.feature_selection.SelectFromModel

4.特征选择函数的使用例子

本文代码主要是用经典的波士顿房价数据集(回归任务)来进行演示。

1.数据准备与模块引入

from sklearn import datasets
from sklearn.feature_selection import VarianceThreshold
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import RFECV
from sklearn.feature_selection import SelectFromModel
from sklearn.feature_selection import chi2
from sklearn.feature_selection import f_regression
from sklearn.tree import DecisionTreeRegressor
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
from pandas import DataFrame
iris=datasets.load_iris()
boston_data=datasets.load_boston()
boston=DataFrame(data=boston_data.data,columns=boston_data.feature_names)
boston['target']=list(boston_data.target)
pre_X=boston.iloc[:,0:13].values
Y=boston.iloc[:,13].values

以上代码是本案例中用到的几种方法的公共代码部分。代码中还加载了iris鸢尾花数据集,原因是在进行统计检验时对于回归任务和分类任务需要有不同的参数,为了详细说明,需要在前面加载iris数据集备用。

2.使用最小方差法进行属性选择

VT_test=VarianceThreshold(threshold=0.5*(1-0.5))
print("特征选择之前的数据集列数:",len(pre_X[0]))
after_X=VT_test.fit_transform(pre_X)
print('============================================================')
print("方差特征选择之后的数据集列数:",len(after_X[0]))
#打印剔除列表,为false的列即为未被选择的列
print(VT_test.get_support())

以上代码运行结果为:
最小方差法进行特征选择

3.使用统计检验方法进行单变量特征选择

'''
#注意:对于回归问题和分类问题,score_func参数需要选择和问题相关的值,
如chi2是卡方检验,针对的是分类问题.
f_regression是方差齐性检验,针对的是回归问题
针对分类问题可选:chi2,f_classif,mutual_info_classif
针对回归问题可选:f_regression(默认),mutual_info_regression
'''
#对于波士顿房价,属于回归问题
new_X=SelectKBest(score_func=f_regression,k=10).fit_transform(pre_X,Y)
print("波士顿单变量特征选择之前的数据集列数:",len(pre_X[0]))
print('============================================================')
print("波士顿单变量特征选择之后的数据集列数:",len(new_X[0]))
#使用鸢尾花来演示分类数据
print('============================================================')
print("鸢尾花单变量特征选择之前的数据集列数:",len(iris.data[0]))
new_X=SelectKBest(score_func=chi2,k=3).fit_transform(iris.data,iris.target)
print('============================================================')
print("鸢尾花单变量特征选择之后的数据集列数:",len(new_X[0]))

在进行统计检验方法的选择时,需要根据人物的类型选择适当的参数,注释中已经给出了详细说明。
以上代码运行结果为:
单变量特征选择

4.使用递归特征消除来进行特征选择

在使用递归特征消除时,需要人为地先训练一个学习器传入,以该学习器学习的结果来作为特征选择的依据,由于波士顿房价问题为回归问题,我们选择回归树作为回归学习器,并使用MSE作为回归效果的误差衡量。下面是代码:

X_train,X_test,Y_train,Y_test=train_test_split(pre_X,Y,test_size=0.3,random_state=0)
estimator=DecisionTreeRegressor()
pre_predict_result=estimator.fit(X_train,Y_train).predict(X_test)
mse=np.sum((pre_predict_result-Y_test)**2)/len(Y_test)
print(mse)
# 进行递归特征消除,这里设置每一轮迭代中每次删去一个变量,并进行5折交叉验证来用于评估性能
selector=RFECV(estimator,step=1,cv=5)
# 将学习器进化成特征选择后的学习器
selector=selector.fit(pre_X,Y)
#打印特征选择情况,与上同
print(selector.get_support())
#这里RFECV进化的学习器需要手工使用花式索引来去掉被筛选掉的特征
after_predict_result=selector.estimator_.predict(X_test[:,selector.support_])
mse=np.sum((after_predict_result-Y_test)**2)/len(Y_test)
print(mse)

运行结果为:
递归特征选择
进行特征选择后MSE变成了0,我的理解是:特征选择前的数据和选择后的数据:使用了同类学习器进行学习,因为强化学习器就是针对这个数据集和基础学习器进行优化的,因此强化后的学习器还在这个数据集上运行,误差为0,不知道我这么理解有没有问题,欢迎指正。

5.使用SelectFromModel进行学习器评分选择

代码如下:

X_train,X_test,Y_train,Y_test=train_test_split(pre_X,Y,test_size=0.3,random_state=0)
estimator=DecisionTreeRegressor()
pre_predict_result=estimator.fit(X_train,Y_train).predict(X_test)
mse=np.sum((pre_predict_result-Y_test)**2)/len(Y_test)
print(mse)
selector=SelectFromModel(estimator,threshold='median')
# 将学习器进化成特征选择后的学习器
selector = selector.fit(pre_X,Y)
# #打印特征选择情况,与上同
print(selector.get_support())
#这里SelectFromModel进化的学习器会自动去掉被筛选掉的特征
after_predict_result=selector.estimator_.predict(X_test)
mse=np.sum((after_predict_result-Y_test)**2)/len(Y_test)
print(mse)

运行结果如下:
SelectFromModel
强化学习器的预测MSE也是为0,原因同上。

5.总结

以上是sklearn模块中的特征选择相关函数,在这里补充一点,在后两种方法中,特征选择厚的最优学习器在测试机上的学习误差MSE为0,即完全正确,猜测是因为强化学习器和基本学习器是同一种学习器。所以,我们可以使用一类方法进行特征选择,再拿着特征选择后得到的新数据集去使用另外一种学习方法来对数据进行学习,从而验证该特征选择的效果。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值