全栈工程师开发手册 (作者:栾鹏)
python数据挖掘系列教程
注意:特征特征提取与 特征选择 有很大的不同:前者包括将任意数据(如文本或图像)转换为可用于机器学习的数值特征。后者是将这些特征应用到机器学习中。
从字典类型加载特征
类 DictVectorizer 可用于将标准的Python字典(dict)对象列表的要素数组转换为 scikit-learn 估计器使用的 NumPy/SciPy 表示形式。
# ===========从字典类型加载特征。形成系数矩阵结构==========
from sklearn.feature_extraction import DictVectorizer
measurements = [
{'name': 'student1', 'age': 12},
{'boy':True, 'parents': 'baba'},
{'size':16},
]
vec = DictVectorizer().fit(measurements) # 定义一个加载器,后对一个字典对象提取特征。(值为数值型、布尔型的属性为单独的属性。值为字符串型的属性,形成"属性=值"的新属性)
print('提取的特征:',vec.get_feature_names()) # 查看提取的新属性
print('稀疏矩阵形式:\n',vec.transform(measurements))
print('二维矩阵形式:\n',vec.transform(measurements).toarray())
输出结果为
提取的特征: ['age', 'boy', 'name=student1', 'parents=baba', 'size']
稀疏矩阵形式:
(0, 0) 12.0
(0, 2) 1.0
(1, 1) 1.0
(1, 3) 1.0
(2, 4) 16.0
二维矩阵形式:
[[ 12. 0. 1. 0. 0.]
[ 0. 1. 0. 1. 0.]
[ 0. 0. 0. 0. 16.]]
类 DictVectorizer 也是对自然语言处理模型中训练序列分类器的有用的表示变换,通常通过提取围绕感兴趣的特定的词的特征窗口来工作。
如果一个文本语料库的每一个单词都提取了这样一个上下文,那么所得的矩阵将会非常宽(许多 one-hot-features),其中大部分通常将会是0。 为了使结果数据结构能够适应内存,该类DictVectorizer
的 scipy.sparse 默认使用一个矩阵而不是一个 numpy.ndarray。
文本特征提取
文本分词有个比较好的库,结巴分词,可以参考:https://blog.csdn.net/luanpeng825485697/article/details/78757563
类 CountVectorizer 在单个类中实现了 tokenization (词语切分)和 occurrence counting (出现频数统计):
# =================文本特征提取==============
from sklearn.feature_extraction.text import CountVectorizer
corpus = ['This is the first document.',
'This is the second second document.',
'And the third one.',
'Is this the first document?',]
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus) # 默认提取至少 包含2个字母的单词
print('所有特征:',vectorizer.get_feature_names())
print('样本特征向量:\n',X.toarray()) # X本身为稀疏矩阵存储形式,toarray转换为二维矩阵形式
print('document属性的列索引:',vectorizer.vocabulary_.get('document')) # 从 特征 名称到矩阵的(列索引)
# 提取一个单词或两个单词形成的词组。这样就能识别“is this”和“this is”这两种词汇了
bigram_vectorizer = CountVectorizer(ngram_range=(1, 2),token_pattern=r'\b\w+\b', min_df=1)
analyze = bigram_vectorizer.build_analyzer()
print('所有分词:',analyze('Bi-grams are cool!'))
Tf–idf 项加权
在一个大的文本语料库中,一些单词将出现很多次(例如 “the”, “a”, “is” 是英文),因此对文档的实际内容没有什么有意义的信息。 如果我们将直接计数数据直接提供给分类器,那么这些频繁词组会掩盖住那些我们关注但很少出现的词。
为了为了重新计算特征权重,并将其转化为适合分类器使用的浮点值,因此使用 tf-idf 变换是非常常见的。
Tf表示术语频率,而 tf-idf 表示术语频率乘以转制文档频率: tf-idf(t,d) = tf(t,d) × idf(t) . \text{tf-idf(t,d)}=\text{tf(t,d)} \times \text{idf(t)}. tf-idf(t,d)=tf(t,d)×idf(t).
使用 TfidfTransformer 的默认设置,TfidfTransformer(norm='l2', use_idf=True, smooth_idf=True, sublinear_tf=False)
术语频率,一个术语在给定文档中出现的次数乘以 idf 组件, 计算为
idf ( t ) = l o g 1 + n d 1 + df ( d , t ) + 1 , \text{idf}(t) = log{\frac{1 + n_d}{1+\text{df}(d,t)}} + 1, idf(t)=log1+df(d,t)1+nd+1,
其中 n_d 是文档的总数, df ( d , t ) \text{df}(d,t) df(d,t) 是包含术语 t 的文档数。 然后,所得到的 tf-idf 向量通过欧几里得范数归一化:
v n o r m = v ∣ ∣ v ∣ ∣ 2 = v v 1 2 + v 2 2 + ⋯ + v n 2 . v_{norm} = \frac{v}{||v||_2} = \frac{v}{\sqrt{v{_1}^2 + v{_2}^2 + \dots + v{_n}^2}}. vnorm=∣∣v∣∣2v=v12+v22+⋯+vn2v.
它源于一个词权重的信息检索方式(作为搜索引擎结果的评级函数),同时也在文档分类和聚类中表现良好。
以下部分包含进一步说明和示例,说明如何精确计算 tf-idfs 以及如何在 scikit-learn 中计算 tf-idfs, TfidfTransformer 并 TfidfVectorizer 与定义 idf 的标准教科书符号略有不同
idf ( t ) = l o g n d 1 + df ( d , t ) . \text{idf}(t) = log{\frac{n_d}{1+\text{df}(d,t)}}. idf(t)=log1+df(d,t)nd.
在 TfidfTransformer 和 TfidfVectorizer 中 smooth_idf=False,将 “1” 计数添加到 idf 而不是 idf 的分母:
idf ( t ) = l o g n d df ( d , t ) + 1 \text{idf}(t) = log{\frac{n_d}{\text{df}(d,t)}} + 1 idf(t)=logdf(d,t)nd+1
# ===================Tf–idf 项加权===================
from sklearn.feature_extraction.text import TfidfTransformer
transformer = TfidfTransformer(smooth_idf=False) # smooth_idf=False,将 “1” 计数添加到 idf 而不是 idf 的分母
# transformer = TfidfTransformer()
# 第一个特征经常出现,所以作用不大,第二个特征和第三个特征不经常出现,所以比较重要
counts = [[3, 0, 1],
[2, 0, 0],
[3, 0, 0],
[4, 0, 0],
[3, 2, 0],
[3, 0, 2]]
tfidf = transformer.fit_transform(counts)
print('稀疏矩阵存储:\n',tfidf)
print('二维矩阵存储:\n',tfidf.toarray())
print('特征权重:',transformer.idf_)
图像特征提取
参考python中opencv的使用:https://blog.csdn.net/luanpeng825485697/article/details/79509870