特征工程
特征工程是什么
特征工程旨在去除原始数据中的杂质和冗余,设计更高效的特征以刻画求解问题与预测模型之间的关系
特征工程的意义
直接影响模型的预测结果
1.特征抽取
数据的特征抽取
须知:
- 特征抽取针对非连续型数据
- 特征抽取对文本等进行特征值化
注:特征值化是为了计算机更好的去理解数据
1.利用sklearn对字典数据进行特征值化
- 导入sklearn.feature_extraction模块中的DictVectorizer类
- 实例化类DictVectorizer
- 调用DictVectorizer类中的方法
1.DictVectorizer.fit_transform(X)
X:字典或者包含字典的迭代器
返回值:默认返回sparse矩阵(稀疏矩阵) 可通过创建\n
DictVectorizer(sparse=False)来改变默认返回
2.DictVectorizer.inverse_transform(X)
X:array数组或者sparse矩阵
返回值:转换之前数据格式
3.DictVectorizer.get_feature_names()返回类别名称
4.DictVectorizer.transform(X)按照原先的标准转换
实例方法一
from sklearn.feature_extraction import DictVectorizer
def dictvec():
"""
字典数据抽取
:return:
"""
#实例化
dict = DictVectorizer()
#dict = DictVectorizer(sparse=False)这样可以使默认返回为
#调用fit_transform
data = dict.fit_transform([{'city': '北京','temperature':100},
{'city': '上海','temperature':60},
{'city': '合肥','temperature':70}])
print(data)
if __name__== "__main__":
dictvec()
输出
用dict = DictVectorizer()实例化类时,默认返回sparse稀疏矩阵如下
用dict = DictVectorizer(sparse=False)实例化类时,返回ndarrayl类型的数组如下
总结: 可以看出sparse矩阵就是利用索引描述数组如sparse中(0,1)1.0 表示0行1列的地方数据为1.0
实例方法三
查看将那些数据抽取成了特征
print(dict.get_feature_names())
[{‘city’: ‘北京’,‘temperature’:100},
{‘city’: ‘上海’,‘temperature’:60},
{‘city’: ‘合肥’,‘temperature’:70}]
上海 北京 合肥 temperature 就变成了特征
可以看出字典数据抽取将字典中一些非数值型数据分别转化为了特征,数值型数据并不处理。如本例中特征temperature就不 处理,第一个样本为{‘city’: ‘北京’,‘temperature’:100} city=‘上海’ city='合肥’为否,所以特征抽取后第一行为0. 1. 0. 100.
1.2利用sklearn对文本数据进行特征值化
前言:方法一不常用、方法二常用。因为方法一只统计出现的个数,一个文本中某些词可能出现次数多但不重要(如:所以,我们)。方法二较好在方法一统计词的频率的基础上加入了逆文档频率。
方法一:Count统计次数不常用
- 导入sklearn.feature_extraction.text模块中CountVectorizer类
- 实例化类CountVectorizer
- 调用CountVectorizer类中的方法
CountVectorizer.fit_transform(X,y)
X:文本或者包含文本字符串的可迭代对象
返回值:返回sparse矩阵
CountVectorizer.inverse_transform(X)
X:array数组或者sparse矩阵
返回值:转换之前数据格式
CountVectorizer.get_feature_names()
返回值:单词列表
from sklearn.feature_extraction.text import CountVectorizer
def countvec():
"""
对文本进行特征值化
:return: None
"""
cv = CountVectorizer() #这里没有sparse=False的参数不能用
data = cv.fit_transform(["life is short,i like python","life is too long,i dislike python"])
print(cv.get_feature_names())
print(data.toarray()) #因为data为numpy的ndarray类型所以可以用ndarray类型自带的方法将其转化为数组。
return None
总结:
- 由get_feature_names()可知,抽取的特征是文章中所有的词,重复的只看做一次,且单个中文和字符都不统计,因为其无情感方向。
- 由data.toarray()可知,特征对应的特征值是对每篇文章,在词的列表里面进行统计每个词出现的次数。
- 当对中文文本进行特征抽取时需要进行分词,可用jieba分词对中文进行分词操作。
方法二:tfidf常用
TF-IDF的主要思想是: 如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
TF-IDF作用: 用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度
tf:term frequency词的频率 统计词出现的次数
idf:逆文档频率inverse document frequency 公式log(总文档数量/该词出现的数量)
tf*idf称为重要性
2.特征预处理
通过特定的统计方法(数学方法)将数据转换成算法要求的数据
- 归一化:
通过对原始数据进行变换把数据映射到(默认为[0,1])之间。
eg:
对于第一个样本,第一个特征90,我们来计算它归一化的结果。X1=(90-60)/(90-60)=1 x2=1*(1-0)+0=1
def mm():
"""
归一化处理
:return: NOne
"""
# feature_range参数为缩放范围,默认[0,1]
mm = MinMaxScaler(feature_range=(0, 1))
data = mm.fit_transform([[90,2,10,40],[60,4,15,45],[75,3,13,46]])
print(data)
return None
输出:
[[1. 0. 0. 0. ]
[0. 1. 1. 0.83333333]
[0.5 0.5 0.6 1. ]]
案例:
假如里程数、公升数、消耗时间比这三个特征影响相同试想如果不做归一化处理,由于里程数数据量大势必会对整个结果造成决定的影响。
归一化的目的: 使得某个特征不会对最终的结果造成决定性的影响。
归一化缺点: 注意在特定场景下最大值最小值是变化的,另外,最大值与最小值非常容易受异常点影响,所以这种方法鲁棒性(稳定性)较差,只适合传统精确小数据场景。
- 标准化
特点:通过对原始数据进行变换把数据变换到均值为0,方差为1范围内。
标准化API:
scikit-learn.preprocessing.StandardScaler
处理之后每列来说所有数据都聚集在均值0附近方差为1
- StandardScaler.fit_transform(X,y) X:numpy array格式的数据[n_samples,n_features]返回值:转换后的形状相同的array.
- StandardScaler.mean_原始数据中每列特征的平均值
- StandardScaler.std_原始数据每列特征的方差
def stand():
"""
标准化缩放
:return:
"""
std = StandardScaler()
data = std.fit_transform([[ 1., -1., 3.],[ 2., 4., 2.],[ 4., 6., -1.]])
print(data)
return None
输出:
[[-1.06904497 -1.35873244 0.98058068]
[-0.26726124 0.33968311 0.39223227]
[ 1.33630621 1.01904933 -1.37281295]]
- 对于归一化来说:如果出现异常点,影响了最大值和最小值,那么结果显然会发生改变。
- 对于标准化来说:如果出现异常点,由于具有一定数据量,少量的异常点对于平均值的影响并不大,从而方差改变较小。
在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据场景。
3.数据降维
1. 特征选择
特征选择是什么?
特征选择就是单纯地从提取到的所有特征中选择部分特征作为训练集特征,特征在选择前和选择后可以改变值、也不改变值,但是选择后的特征维数肯定比选择前小,毕竟我们只选择了其中的一部分特征。
特征选择原因:
冗余:部分特征的相关度高,容易消耗计算性能
噪声:部分特征对预测结果有负影响
特征选择的主要方法:
- Filter(过滤式):VarianceThreshold
- Embedded(嵌入式):正则化、决策树
- Wrapper(包裹式)
**Filter(过滤式)VarianceThreshold: 从方差大小考虑所有样本的特征情况,如果方差特别大说明特征不相关程度高,如果方差小说明特征相关程高。
1.导入sklearn.feature_selection.VarianceThreshold
2.指明方差大小VarianceThreshold(threshold = 0.0) threshold参数值就是指明删除的方差值
3.Variance.fit_transform(X,y) X:numpy array格式的数据[n_samples,n_features]返回值:训练集差异低于threshold的特征将被删除。默认值是保留所有非零方差特征,即删除所有样本中具有相同值的特征。
def var():
"""
特征选择-删除低方差的特征
:return: None
"""
var = VarianceThreshold(threshold=1.0)
data = var.fit_transform([[0, 2, 0, 3], [0, 1, 4, 3], [0, 1, 1, 3]])
print(data)
return None
输出:
[[0]
[4]
[1]]
2.主成分分析PCA:
即主成分分析技术,又称主分量分析技术,旨在利用降维的思想,把多指标转化为少数几个综合指标。假如某个样本有上百个特征值就要考虑利用PCA技术降维。
要求:将这个二维的数据简化成一维?
简化后的结果为:
假如找的这条直线再X轴或者Y轴,可以看出投影到直线上面的点有两个重合损失,最理想的理想的直线为上图所示,PCA不仅是降维而且还要保证数据的损失最小。
1.导入from sklearn.decomposition import PCA
2.PCA(n_components=None) n_components参数有两种形式。
- 小数形式:假如n_components=0.9则表示数据保留90%的信息,一般为90%-95%最好。
- 整数形式:假如n_components=10则表明数据的特征值减少到10个,一般不适用。因为无法确定减少到多少特征值最合适。
def pca():
"""
主成分分析进行特征降维
:return: None
"""
pca = PCA(n_components=0.9)
data = pca.fit_transform([[2,8,4,5],[6,3,0,8],[5,4,9,1]])
print(data)
return None
输出:
[[ 1.22879107e-15 3.82970843e+00]
[ 5.74456265e+00 -1.91485422e+00]
[-5.74456265e+00 -1.91485422e+00]]