《Python机器学习及实践:从零开始通往Kaggle竞赛之路》第3章 进阶篇 学习笔记(二)3.1.1.2特征筛选总结

目录

3.1.1.2特征筛选

1、特征筛选

2、编程实践

3、总结


3.1.1.2特征筛选

1、特征筛选

总体来讲,良好的数据特征组合不需太多,便可以使得模型的性能表现突出。比如,在第1章的“良/恶性乳腺癌肿瘤预测”问题中,仅仅使用两个描述肿瘤形态的特征便可以取得很高的识别率。冗余的特征虽然不会影响到模型性能,不过却使得CPU的计算做了无用功。比如,主成分分析主要用于去除多余的那些线性相关的特征组合,原因在于这些冗余的特征组合并不会对模型训练有更多贡献。而不良的特征自然会降低模型的精度。

特征筛选与PCA这类通过选择主成分对特征进行重建的方法略有区别:对于PCA而言,经常无法解释重建之后的特征;但是特征筛选不存在对特征值的修改,而更加侧重于寻找那些对模型的性能提升较大的少量特征。

2、编程实践

继续沿用Titanic数据集,这次试图通过特征筛选来寻找最佳的特征组合,并且达到提高预测准确性的目标。

# 代码59:使用Titanic数据集,通过特征筛选的方法一步步提升决策树的预测性能
# 导入pandas并且更名为pd。
import pandas as pd

# 从本地文件读取titanic数据。
titanic = pd.read_csv('../Datasets/titanic.csv')

# 分离数据特征与预测目标。
y = titanic['survived']
X = titanic.drop(['row.names', 'name', 'survived'], axis=1)

# 对缺失数据进行填充。
X['age'].fillna(X['age'].mean(), inplace=True)
X.fillna('UNKNOWN', inplace=True)

# 分割数据,依然采样25%用于测试。
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=33)

# 类别型特征向量化。
from sklearn.feature_extraction import DictVectorizer

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_))

# 使用决策树模型依靠所有特征进行预测,并作性能评估。
from sklearn.tree import DecisionTreeClassifier

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

# 从sklearn导入特征筛选器。
from sklearn import feature_selection

# 筛选前20%的特征,使用相同配置的决策树模型进行预测,并且评估性能。
fs = feature_selection.SelectPercentile(feature_selection.chi2, percentile=20)
X_train_fs = fs.fit_transform(X_train, y_train)
dt.fit(X_train_fs, y_train)
X_test_fs = fs.transform(X_test)
dt.score(X_test_fs, y_test)
print(dt.score(X_test_fs, y_test))

# 通过交叉验证(下一节将详细介绍)的方法,按照固定间隔的百分比筛选特征,并作图展示性能随特征筛选比例的变化。
from sklearn.model_selection import cross_val_score
import numpy as np

percentiles = range(1, 100, 2)
results = []

for i in percentiles:
    fs = feature_selection.SelectPercentile(feature_selection.chi2, percentile=i)
    X_train_fs = fs.fit_transform(X_train, y_train)
    scores = cross_val_score(dt, X_train_fs, y_train, cv=5)
    results = np.append(results, scores.mean())
print(results)

# 找到体现最佳性能的特征筛选的百分比。
opt = np.where(results == results.max())[0]
print('Optimal number of features %d' % percentiles[opt[0]])

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

# 使用最佳筛选后的特征,利用相同配置的模型在测试集上进行性能评估。
from sklearn import feature_selection

fs = feature_selection.SelectPercentile(feature_selection.chi2, percentile=7)
X_train_fs = fs.fit_transform(X_train, y_train)
dt.fit(X_train_fs, y_train)
X_test_fs = fs.transform(X_test)
dt.score(X_test_fs, y_test)
print(dt.score(X_test_fs, y_test))

备注1:原来直接从互联网(http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt)收集数据,加载太慢;故从互联网下载数据,保存为.csv格式文件。

备注2:原来的导入模型from sklearn.cross_validation import train_test_split的时候,提示错误:

from sklearn.cross_validation import train_test_split
ModuleNotFoundError: No module named 'sklearn.cross_validation'

需要替换cross_validation:

from sklearn.model_selection import train_test_split

备注3:原来的导入模型from sklearn.cross_validation import cross_val_score的时候,提示错误:

from sklearn.cross_validation import cross_val_score
ModuleNotFoundError: No module named 'sklearn.cross_validation'

需要替换cross_validation:

from sklearn.model_selection import cross_val_score

备注4:原来的会报错,错误提示为:

print('Optimal number of features %d' % percentiles[opt])
TypeError: only integer scalar arrays can be converted to a scalar

报错原因:

只有整数标量数组才能转换为标量索引。Python版本升级,有些方法已经发生改变,使将单个元素数组作为标量进行索引成为一个错误。

故采用以下方法。

print('Optimal number of features %d' % percentiles[opt[0]])

本地输出:

474
0.8206686930091185
0.8085106382978723
[0.85063904 0.85673057 0.87501546 0.88622964 0.86283241 0.87100598
 0.87404659 0.87100598 0.86996496 0.86895485 0.86896516 0.86794475
 0.86388374 0.86691404 0.86589363 0.86489384 0.86996496 0.86386312
 0.86486291 0.86385281 0.8608122  0.86283241 0.86793445 0.86285302
 0.87100598 0.86384251 0.86794475 0.87096475 0.86999588 0.87404659
 0.86792414 0.86793445 0.86589363 0.87098536 0.87097506 0.87100598
 0.87504638 0.87099567 0.86894455 0.86693465 0.87099567 0.86993403
 0.86591424 0.86083282 0.86183261 0.86387343 0.86490414 0.8608122
 0.86793445 0.85880231]
Optimal number of features 7
0.8541033434650456

3、总结

①经过初步的特征处理后,最终的训练与测试数据均有474个维度的特征。

②如果直接使用全部474个维度的特征用于训练决策树模型进行分类预测,那么模型在测试集上的准确性约为82.07%。

③如果筛选前20%维度的特征,在相同的模型配置下进行预测,那么在测试集上表现的准确性约为80.85%。

④如果按照固定的间隔采用不同百分比的特征进行训练和测试,通过交叉验证得出的准确性有很大的波动,并且最好的模型性能表现在选取前7%维度的特征的时候。

⑤如果使用前7%维度的特征,那么最终决策树模型可以在该分类预测任务的测试集上表现出85.41%的准确性,比起最初使用全部特征的模型性能高出接近4个百分点。

备注:总结是根据“本地输出”得到的数据,与原来的数据不一致。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值