这是我参与8月更文挑战的第20天,活动详情查看:8月更文挑战
什么是特征提取?
特征提取就是将一些原始的输入的数据维度减少或者将原始的特征进行重新组合以便于后续的使用。
比如: 我们知道有的时候原始数据的特征很多,而且有的高度相关,有的却又和最终的目的没有关系。我们需要去除没有关系的特征。(减少数据维度) 对于图像来说,每个图像有很多数据,这时候如果直接拿这些原始数据去计算则会非常缓慢,这对我们实时运行没有好处,我们需要提取出新的特征。(减少数据维度) 我们通过原始数据很多维特征,得到一个新的特征,最后通过这个新的特征来指导做决策。(整理已有的数据特征)
特征提取有什么作用?
- 减少数据维度
- 提取或整理出有效的特征供后续使用
sklearn中的特征提取方法
sklearn目前包括从文本和图像中提取特征的方法。
方法 | 说明 |
---|---|
feature_extraction.DictVectorizer(*[, …]) | 对字典进行特征的提取 |
feature_extraction.FeatureHasher([…]) | 特征哈希 |
文本特征提取
方法 | 说明 |
---|---|
feature_extraction.text.CountVectorizer(*[, …]) | 将文本文档集合转换为词频矩阵 |
feature_extraction.text.HashingVectorizer(*) | 使用哈希技巧向量化文本文档集合 |
feature_extraction.text.TfidfTransformer(*) | 将CountVectorizer生成的稀疏矩阵转换成TF-IDF特征矩阵 |
feature_extraction.text.TfidfVectorizer(*[, …]) | 将原始文档集合转换为 TF-IDF特征矩阵 |
DictVectorizer-从字典加载特征
DictVectorizer类可用于将以标准Python dict
对象列表为表示形式的要素数组转换为scikit-learn估计器使用的NumPy / SciPy形式。
尽管处理速度不是特别快,但是Python dict
具有以下优点:易于使用,稀疏(缺少的特征不需要存储)以及除了特征值之外还存储特征名称。
DictVectorizer通过实现“独热”编码用于分类特征。分类特征是成对的“属性--值”形式,其中值被限制为不定序的符合要求的列表(例如主题标识符,对象类型,标签,名称等)。
以下示例中,“city”是分类属性,而“temperature”是传统的数字特征:
>>> measurements = [
... {'city': 'Dubai', 'temperature': 33.},
... {'city': 'London', 'temperature': 12.},
... {'city': 'San Francisco', 'temperature': 18.},
... ]
>>> from sklearn.feature_extraction import DictVectorizer
>>> vec = DictVectorizer()
>>> vec.fit_transform(measurements).toarray()
array([[ 1., 0., 0., 33.],
[ 0., 1., 0., 12.],
[ 0., 0., 1., 18.]])
>>> vec.get_feature_names()
['city=Dubai', 'city=London', 'city=San Francisco', 'temperature']
FeatureHasher-特征哈希
FeatureHasher是一个高速的,低存储的向量化的类。它使用一种被称为特征哈希(或称为“哈希技巧”)的技术。
这个类是对DictVectorizer和CountVectorizer的低内存替代,用于大规模(在线)学习和内存紧张的情况。
FeatureHasher 的输出始终是 CSR 格式的 scipy.sparse 矩阵。
>>> from sklearn.feature_extraction import FeatureHasher
>>> hasher = FeatureHasher(n_features=10)
>>> D = [{'dog': 1, 'cat':2, 'elephant':4},{'dog': 2, 'run': 5}]
>>> f = hasher.transform(D)
>>> f.toarray()
array([[ 0., 0., -4., -1., 0., 0., 0., 0., 0., 2.],
[ 0., 0., 0., -2., -5., 0., 0., 0., 0., 0.]])
参数:n_features为输出矩阵中的特征数(列)。在线性学习中,特征数小容易引起哈希冲突,而特征数大则系数维数大。
文本特征提取
CountVectorizer-词频矩阵
CountVectorizer是一个文本特征提取方法。对于每一个训练文本,它只考虑每种词汇在该训练文本中出现的频率。
CountVectorizer类的参数很多,分为三个处理步骤:preprocessing、tokenizing、n-grams generation.
>>> from sklearn.feature_extraction.text import CountVectorizer
>>> texts=["dog cat fish","dog cat cat","fish bird", 'bird']
>>> cv = CountVectorizer() # 创建词袋数据结构
>>> cv_fit=cv.fit_transform(texts)
>>> print(cv.get_feature_names()) # 列表形式呈现文章生成的词典
['bird', 'cat', 'dog', 'fish']
>>> print(cv.vocabulary_) # 字典形式呈现,key:词,value:词频
{'dog': 2, 'cat': 1, 'fish': 3, 'bird': 0}
>>> print(cv_fit.toarray()) # 词频矩阵
array([[0, 1, 1, 1],
[0, 2, 1, 0],
[1, 0, 0, 1],
[1, 0, 0, 0]])
CountVectorizer是通过fit_transform函数将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在第i个文本下的词频,即各个词语出现的次数。通过get_feature_names()可看到所有文本的关键字,通过toarray()可看到词频矩阵的结果。
HashingVectorizer
HashingVectorizer使用哈希技巧向量化文本。
特点
普通的CountVectorizer存在但词库很大时,占用大内存,因此,HashingVectorizer使用hash技巧,并用稀疏矩阵存储编译后的矩阵,能很好解决这个问题。
>>> from sklearn.feature_extraction.text import HashingVectorizer
>>> corpus = [
... 'This is the first document.',
... 'This document is the second document.',
... 'And this is the third one.',
... 'Is this the first document?',
... ]
>>> vectorizer = HashingVectorizer(n_features=2**4)
>>> X = vectorizer.fit_transform(corpus)
>>> X
<4x16 sparse matrix of type '<class 'numpy.float64'>'
with 16 stored elements in Compressed Sparse Row format>
>>> X.toarray()
array([[-0.57735027, 0. , 0. , 0. , 0. ,
0. , 0. , 0. , -0.57735027, 0. ,
0. , 0. , 0. , 0.57735027, 0. ,
0. ],
[-0.81649658, 0. , 0. , 0. , 0. ,
0. , 0. , 0. , 0. , 0. ,
0. , 0.40824829, 0. , 0.40824829, 0. ,
0. ],
[ 0. , 0. , 0. , 0. , -0.70710678,
0.70710678, 0. , 0. , 0. , 0. ,
0. , 0. , 0. , 0. , 0. ,
0. ],
[-0.57735027, 0. , 0. , 0. , 0. ,
0. , 0. , 0. , -0.57735027, 0. ,
0. , 0. , 0. , 0.57735027, 0. ,
0. ]])
TfidfTransformer
TfidfTransformer是统计CountVectorizer生产的词频矩阵中每个词语的tf-idf权值。
TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
>>> from sklearn.feature_extraction.text import TfidfTransformer
>>> transformer = TfidfTransformer(smooth_idf=False)
>>> transformer
TfidfTransformer(smooth_idf=False)
>>>
>>> counts = [[3, 0, 1],
... [2, 0, 0],
... [3, 0, 0],
... [4, 0, 0],
... [3, 2, 0],
... [3, 0, 2]]
>>>
>>> tfidf = transformer.fit_transform(counts)
>>> tfidf
<6x3 sparse matrix of type '<class 'numpy.float64'>'
with 9 stored elements in Compressed Sparse Row format>
>>>
>>> tfidf.toarray()
array([[0.81940995, 0. , 0.57320793],
[1. , 0. , 0. ],
[1. , 0. , 0. ],
[1. , 0. , 0. ],
[0.47330339, 0.88089948, 0. ],
[0.58149261, 0. , 0.81355169]])
TfidfVectorizer
TfidfVectorizer接受文本数据并完成词袋特征提取与 TF-IDF变换。
TfidfVectorizer 相当于 CountVectorizer 和 TfidfTransformer 的结合使用。
>>> corpus = [
... 'This is the first document.',
... 'This is the second second document.',
... 'And the third one.',
... 'Is this the first document?',
... ]
>>> from sklearn.feature_extraction.text import TfidfVectorizer
>>> vectorizer = TfidfVectorizer()
>>> result = vectorizer.fit_transform(corpus)
>>> result.toarray()
array([[0. , 0.43877674, 0.54197657, 0.43877674, 0. ,
0. , 0.35872874, 0. , 0.43877674],
[0. , 0.27230147, 0. , 0.27230147, 0. ,
0.85322574, 0.22262429, 0. , 0.27230147],
[0.55280532, 0. , 0. , 0. , 0.55280532,
0. , 0.28847675, 0.55280532, 0. ],
[0. , 0.43877674, 0.54197657, 0.43877674, 0. ,
0. , 0.35872874, 0. , 0.43877674]])
总结
sklearn支持将文本转换成词频矩阵(CountVectorizer)、TF-IDF矩阵(TfidfVectorizer)、Hash矩阵(HashingVectorizer),这三种都是词袋模型的方法,其中,TfidfVectorizer
这种方法可以降低高频信息量少词语的干扰,应用得更多。