参考书目《Python数据挖掘入门与实践》
学习目的及意义
大多数数据挖掘算法都依赖于数值或类别型特征。所以,如何从数据集中抽取数值和类别型特征,并选出最佳特征,成为数据挖掘任务最为重要的一个环节。
降低特征数量的优点
- 降低复杂度:随着特征数量的增加,很多数据挖掘算法需要更多的时间和资源。减少特征数量,是提高算法运行速度,减少资源使用的好方法。
- 降低噪音:增加额外特征并不总会提升算法的表现。额外特征可能扰乱算法的正常工作,这些额外特征间的相关性和模式没有实际应用价值(这种情况在小数据集上很常见)。只选择合适的特征有助于减少出现没有实际意义的相关性的几率。
- 增加模型可读性:根据成千上万个特征创建的模型来解答一个问题,对计算机来说很容易,但模型对我们自己来说就晦涩无比。因此,使用更少的特征,创建我们自己可以理解的模型,就很有必要。
数据来源及解释
http://archive.ics.uci.edu/ml/datasets/Adult
点击Data Folder链接。下载adult.data和adult.names文件。其中,adult.names文件中包含对数据的解释。(adult.data没有表头,需要参照adult.names)
读入数据并加入表头信息
import pandas as pd
adult = pd.read_csv('adult.csv', header=None, names=["Age", "Work-Class", "fnlwgt", "Education",
"Education-Num", "Marital-Status", "Occupation",
"Relationship", "Race", "Sex", "Capital-gain",
"Capital-loss", "Hours-per-week", "Native-Country",
"Earnings-Raw"])
去除包含na空值所在的行
adult.dropna(how='all', inplace=True)
设置inplace参数为真,表示改动当前数据框,而不是新建一个
数据处理和简单描述
- 连续型数据
adult["Hours-per-week"].describe()
count 32561.000000
mean 40.437456
std 12.347429
min 1.000000
25% 40.000000
50% 40.000000
75% 45.000000
max 99.000000
Name: Hours-per-week, dtype: float64
- 类别型特征
类别型特征二值化后就变成了数值型特征
二值化,例如:网球的话特征向量是[1, 0, 0],棒球[0, 1, 0],足球[0, 0, 1]。这些特征都只有两个取值,很多算法都可以把它们作为连续型特征使用。二值化的好处是,便于直接进行数字上的比较(例如计算个体之间的距离)。 - 得到列的所有取值(不重复)
adult["Work-Class"].unique()
array([' State-gov', ' Self-emp-not-inc', ' Private', ' Federal-gov',
' Local-gov', ' ?', ' Self-emp-inc', ' Without-pay', ' Never-worked'], dtype=object)
数据集部分数据缺失,但不会影响这里的计算。
- 离散化
数值型特征可以通过离散化过程转换为类别型特征。但是,细节的丢失是离散化不好的一面,也是建模时需要考虑解决的问题。
确保特征值是不同的(基础性测试之一)
scikit-learn中的VarianceThreshold转换器可用来删除特征值的方差达不到最低标准的特征。
具体用法如下:
import numpy as np
X = np.arange(30).reshape((10, 3))
X
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17],
[18, 19, 20],
[21, 22, 23],
[24, 25, 26],
[27, 28, 29]])
X[:,1] = 1
X
array([[ 0, 1, 2],
[ 3, 1, 5],
[ 6, 1, 8],
[ 9, 1, 11],
[12, 1, 14],
[15, 1, 17],
[18, 1, 20],
[21, 1, 23],
[24, 1, 26],
[27, 1, 29]])
from sklearn.feature_selection import VarianceThreshold
vt = VarianceThreshold()
Xt = vt.fit_transform(X)
Xt
array([[ 0, 2],
[ 3, 5],
[ 6, 8],
[ 9, 11],
[12, 14],
[15, 17],
[18, 20],
[21, 23],
[24, 26],
[27, 29]])
print(vt.variances_)
[ 74.25 0. 74.25]
选择最佳特征
- 选取下述特征,从pandas数据框中抽取一部分数据。
X = adult[["Age", "Education-Num", "Capital-gain", "Capital-loss",
"Hours-per-week"]].values
- 创建目标类别列表,判断Earnings-Raw(税前收入)是否达到五万美元。
y = (adult["Earnings-Raw"] == ' >50K').values
计算相关性有两种方法
1.使用SelectKBest转换器类,用卡方函数打分,初始化转换器。
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
transformer = SelectKBest(score_func=chi2, k=3)
- 调用fit_transform方法,对相同的数据集进行预处理和转换。结果为分类效果较好的三个特征。
Xt_chi2 = transformer.fit_transform(X, y)
- 得到每一列的相关性,可以知道都使用了哪些特征。
print(transformer.scores_)
[ 8.60061182e+03 2.40142178e+03 8.21924671e+07 1.37214589e+06
6.47640900e+03]
相关性最好(值最大)的分别是第一、三、四列,分别对应着Age(年龄)、Capital-Gain(资本收益)和Capital-Loss(资本损失)三个特征。从单变量特征选取角度来说,这些就是最佳特征。
2.皮尔逊(Pearson)相关系数
- 从SciPy导入pearsonr函数
from scipy.stats import pearsonr
SciPy的pearsonr函数参数为两个数组,但要注意的是第一个参数x为一维数组。我们来实现一个包装器函数,这样就能像前面那样处理多维数组。
def multivariate_pearsonr(X, y):
scores, pvalues = [], []
for column in range(X.shape[1]):
cur_score, cur_p = pearsonr(X[:,column], y)
scores.append(abs(cur_score))
pvalues.append(cur_p)
return (np.array(scores), np.array(pvalues))
- 使用转换器类,根据皮尔逊相关系数对特征进行排序。
transformer = SelectKBest(score_func=multivariate_pearsonr, k=3)
Xt_pearson = transformer.fit_transform(X, y)
print(transformer.scores_)
[ 0.2340371 0.33515395 0.22332882 0.15052631 0.22968907]
返回的特征跟用卡方检验计算相关性得到的特征不一样!这回得到的是第一、二、五列:Age、Education和Hours-per-week。
特征是最好的这个问题没有标准答案——取决于度量标准。
比较两种方法
from sklearn.tree import DecisionTreeClassifier
from sklearn.cross_validation import cross_val_score
clf = DecisionTreeClassifier(random_state=14)
scores_chi2 = cross_val_score(clf, Xt_chi2, y, scoring='accuracy')
scores_pearson = cross_val_score(clf, Xt_pearson, y, scoring='accuracy')
print("Chi2 performance: {0:.3f}".format(scores_chi2.mean()))
print("Pearson performance: {0:.3f}".format(scores_pearson.mean()))
Chi2 performance: 0.829
Pearson performance: 0.771
请注意实验结果也只表明对于特定分类器和(或)特征子集效果更好——在数据挖掘领域,一种方法在任何情况下都比另一种方法好的情况几乎没有!
比较结果:chi2方法的平均正确率为0.83,而皮尔逊相关系数正确率为0.77。用卡方检验得到的特征组合效果更好!
网友评论