最佳特征筛选与feature_selection

本文介绍的是如何利用scikit learn中的feature_selection模块来筛选最佳特征。

1.读取数据并进行填充

titanic=pd.read_csv('./titanic.txt')
# print titanic.head()
# print titanic.info()
#分离数据特征与预测目标
y=titanic['survived'] # 提取出survived 列
X=titanic.drop(['row.names','name','survived'],axis=1) # 提取除去这三列的其它所有列
print X.shape

>>
(1313, 8)

print X['age']

>>
0       29.0000
1        2.0000
2       30.0000
3       25.0000
4        0.9167
5       47.0000
6       63.0000
7       39.0000
8       58.0000
9       71.0000
10      47.0000
11      19.0000
12          NaN
13          NaN
14          NaN

数据集的读取及详情见此处

随机输出age这一列,发现有一些缺失值,所以要进行填充。

#对(age)列缺失值进行填充
X['age'].fillna(X['age'].mean(),inplace=True)
#其余维度(非数值型)的缺失值均用unknown进行填充
X.fillna('UNKNOWN',inplace=True)

2.数据集划分与特征转换

X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.25,
                                               random_state=33)
#对类别维度的特征进行向量化
vec=DictVectorizer()
X_train=vec.fit_transform(X_train.to_dict(orient='record'))
X_test=vec.transform(X_test.to_dict(orient='record'))

print len(vec.feature_names_)

>>
474 # 经过特征向量化后,现在的特征维度已经从之前的8维变成了474维

3.特征筛选

在此之前,先简单说介绍一下sklearn.feature_selection中,两个模块(SelectKBest和SelectPercentile)的用法。二者比较相似,前者选择排名在前n个的变量,后者选择排名在前n%的变量;其中排名的方式通过指定参数来确定:对于regression,可以使用f_regression;对于classification,可以使用chi2或者f_classif。此外,此外选择算法内部会根据因变量y的存在与否自主选择有监督或无监督的学习方式。

对于一个数据集来说,是否需要进行特征值的筛选大致标准是:如果筛选后的数据集在某个模型上的表现性能比不筛选后的更低,很明显此时要么是模型选择错误,要么是不该进行特征筛选,或者是特征选择不对。所以在确定好模型后:

第一步:不进行特征筛选,训练模型得出score
第二步:按等步长筛选特征,训练模型得出score
第三步:选择score最高的特征组合

#Step 1

dt=DecisionTreeClassifier(criterion='entropy')
dt.fit(X_train,y_train)
print 'accuracy: ',dt.score(X_test,y_test)

>>
accuracy:  0.808510638298
#Step 2


percentiles=np.array(range(1,100,2),dtype=int)
results=[]

for i in percentiles:
    fs=feature_selection.SelectPercentile(feature_selection.chi2,percentile=i) # percentile表示选取前%i 的特征
    X_train_fs=fs.fit_transform(X_train,y_train)
    scores=cross_val_score(dt,X_train_fs,y_train,cv=5) #5折交叉验证,返回5次验证后的scores
    results=np.append(results,scores.mean()) #得到每次取的前%i特征所产生的score的均值
    print X_train_fs.shape #可以查看每次的新维度
print results
>>
>>
[ 0.85063904  0.85673057  0.87501546  0.88622964  0.86690373  0.87505669
  0.8740569   0.86894455  0.87097506  0.87202639  0.87097506  0.86690373
  0.86389404  0.86692435  0.8608122   0.86590394  0.86692435  0.86385281
  0.86996496  0.86587302  0.8618223   0.86384251  0.87097506  0.86486291
  0.86591424  0.86793445  0.86791383  0.86895485  0.86793445  0.86792414
  0.86794475  0.87199546  0.87098536  0.86894455  0.87299526  0.87197485
  0.87605648  0.86692435  0.86893424  0.86893424  0.87404659  0.86587302
  0.86691404  0.86591424  0.86693465  0.86184292  0.86389404  0.86286333
  0.8598021   0.86388374]


opt=np.where(results==results.max())[0] #找到score最大的

>>
>>
print '\noptimanl number of features ',percentiles[opt]
# 我们可以看到,当取前7%的特征时,score最大
#Step 3

pl.plot(percentiles,results)
pl.xlabel('percentiles of features')
pl.ylabel('accuracy')
pl.show()

这里写图片描述

4.确定最佳特征并进行训练

 #只选取前7%的特征   注意  要先特征向量化之后才能进行特征选择
fs=feature_selection.SelectPercentile(feature_selection.chi2,percentile=7)
X_train_fs=fs.fit_transform(X_train,y_train)
X_test_fs=fs.transform(X_test)

# print X_train_fs.shape
# print X_train.shape

dt.fit(X_train_fs,y_train)
print dt.score(X_test_fs,y_test)

源码及数据集

参考:

  • Python机器学习及实践

猜你喜欢

转载自blog.csdn.net/the_lastest/article/details/79112746