1 数据的特征抽取
数据的特征抽取:将文本等数据进行特征值化(转换成计算机可以理解的数字类型)
DictVectorizer类可以用来把标准Python dict对象表示的特征数组转换成Numpy/Scipy的表示形式,以便于scikit-learn estimators的使用。
DictVectorizer实现了one-of-K或者叫“one-hot”编码对标称型特征。标称型特征(Categorical feature)是“attribute-value”pairs,其中value是属性的可能的取值列表,必须是有限的离散的没有大小顺序的。
代码:
measurements = [
{'city':'Dubai','temperature':33.0},
{'city':'London','temperature':12.0},
{'city':'San Fransisco','temperature':18.0},
]
from sklearn.feature_extraction import DictVectorizer
vec = DictVectorizer()
print(vec.fit_transform(measurements).toarray())
print(vec.get_feature_names())
输出:

2 统计词频
绝大多数的文档都只使用了一个词汇子集,与整个语料的词汇集合相比起来,是非常小的。所以最终的特征向量矩阵中有很多的特征取值是0(通常是99%)。
例如: 对于一个有10000个短文本的集合来来说,它可能包含的所有的独立的词汇量是100000个,但是其中的任意一个独立的文档可能只有100到1000个词汇量。
为了存储这样的稀疏矩阵而且不影响矩阵/向量的运算速度,特征向量矩阵通常会使用稀疏矩阵来存储。
代码:
from sklearn.feature_extraction.textimport CountVectorizer
vectorizer = CountVectorizer(min_df=1)
print(vectorizer)
corpus = [
'This is the first documents.',
'This is the second documents.',
'And the third document.',
'Is this the first documents?',
]
X = vectorizer.fit_transform(corpus)
print(X)
结果:

3 中文分词处理
# 中文分词
from sklearn.feature_extraction.textimport CountVectorizer
import jieba# 中文分词 需要pip3安装
# 文本数据抽取(将字符串类型的数据转换成数字类型)
# 三个样本(中文文章) jieba分词
con1 = jieba.cut("今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。")
con2 = jieba.cut("我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。")
con3 = jieba.cut("如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。")
# 转换成列表
content1 =list(con1)
content2 =list(con2)
content3 =list(con3)
# 把列表转换成字符串 (CountVectorizer默认以空格进行分词,单个字母或汉字会忽略)
c1 =' '.join(content1)
c2 =' '.join(content2)
c3 =' '.join(content3)
# 特征抽取,特征值化
cv = CountVectorizer()
data = cv.fit_transform([c1, c2, c3])
print(cv.get_feature_names())# ['一种', '不会', '不要', ... , '美好', '联系', '过去', '这样']
print(data.toarray())
输出:

4 TF-IDF
在文本向量化之后一般都伴随着TF-IDF的处理,那么什么是TF-IDF,为什么一般我们要加这一步预处理呢?这里就对TF-IDF的原理做一个总结。
1)文本向量化特征的不足
在将文本分词并向量化后,我们可以得到词汇表中每个词在各个文本中形成的词向量,我们将下面4个短文本做了词频统计:
corpus=["I come to China to travel",
"This is a car polupar in China",
"I love tea and Apple ",
"The work is to write some papers in science"]
不考虑停用词,处理后得到的词向量如下:
[[0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 2 1 0 0]
[0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0]
[1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0]
[0 0 0 0 0 1 1 0 1 0 1 1 0 1 0 1 0 1 1]]
如果我们直接将统计词频后的19维特征做为文本分类的输入,会发现有一些问题。比如第一个文本,我们发现"come","China"和“Travel”各出现1次,而“to“出现了两次。似乎看起来这个文本与”to“这个特征更关系紧密。但是实际上”to“是一个非常普遍的词,几乎所有的文本都会用到,因此虽然它的词频为2,但是重要性却比词频为1的"China"和“Travel”要低的多。如果我们的向量化特征仅仅用词频表示就无法反应这一点。因此我们需要进一步的预处理来反应文本的这个特征,而这个预处理就是TF-IDF。
2) TF-IDF概述
TF-IDF是Term Frequency - Inverse Document Frequency的缩写,即“词频-逆文本频率”。它由两部分组成,TF和IDF。
前面的TF也就是我们前面说到的词频,我们之前做的向量化也就是做了文本中各个词的出现频率统计,并作为文本特征,这个很好理解。关键是后面的这个IDF,即“逆文本频率”如何理解。在上一节中,我们讲到几乎所有文本都会出现的"to"其词频虽然高,但是重要性却应该比词频低的"China"和“Travel”要低。我们的IDF就是来帮助我们来反应这个词的重要性的,进而修正仅仅用词频表示的词特征值。
概括来讲, IDF反应了一个词在所有文本中出现的频率,如果一个词在很多的文本中出现,那么它的IDF值应该低,比如上文中的“to”。而反过来如果一个词在比较少的文本中出现,那么它的IDF值应该高。比如一些专业的名词如“Machine Learning”。这样的词IDF值应该高。一个极端的情况,如果一个词在所有的文本中都出现,那么它的IDF值应该为0。
上面是从定性上说明的IDF的作用,那么如何对一个词的IDF进行定量分析呢?这里直接给出一个词xx的IDF的基本公式如下:

其中,N代表语料库中文本的总数,而N(x)代表语料库中包含词xx的文本总数。
上面的IDF公式已经可以使用了,但是在一些特殊的情况会有一些小问题,比如某一个生僻词在语料库中没有,这样我们的分母为0, IDF没有意义了。所以常用的IDF我们需要做一些平滑,使语料库中没有出现的词也可以得到一个合适的IDF值。平滑的方法有很多种,最常见的IDF平滑后的公式之一为:

有了IDF的定义,我们就可以计算某一个词的TF-IDF值了:

其中TF(x)指词xx在当前文本中的词频
3)代码:
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba# 中文分词
# 文本数据抽取(将字符串类型的数据转换成数字类型)
# 三个样本(中文文章) jieba分词
con1 = jieba.cut("今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。")
con2 = jieba.cut("我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。")
con3 = jieba.cut("如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。")
# 转换成列表
content1 =list(con1)
content2 =list(con2)
content3 =list(con3)
# 把列表转换成字符串 (TfidfVectorizer默认以空格进行分词,单个字母或汉字会忽略)
c1 =' '.join(content1)
c2 =' '.join(content2)
c3 =' '.join(content3)
# 特征抽取,特征值化
tf = TfidfVectorizer()# stop_words=None可以指定排除的关键词
data = tf.fit_transform([c1, c2, c3])
print(tf.get_feature_names())# ['一种', '不会', '不要', '之前', ... , '美好', '联系', '过去', '这样']
print(data.toarray())# 数字越大表示重要程度越高(tf*idf:词的频率 × log(总文档数/出现该词的文档数))
结果:

4)TF-IDF小结
TF-IDF是非常常用的文本挖掘预处理基本步骤,但是如果预处理中使用了Hash Trick,则一般就无法使用TF-IDF了,因为Hash Trick后我们已经无法得到哈希后的各特征的IDF的值。使用了IF-IDF并标准化以后,我们就可以使用各个文本的词特征向量作为文本的特征,进行分类或者聚类分析。
网友评论