上小节我们讲解了对于字典的特征抽取,特征抽取的目的是什么,在我们的数据集中,有的是使用字符串标识出来的,我们需要把其数值化,即特征值化。
下面我们讲解文本特征抽取,他有狠毒的应用场景(后面我们会提到),文本特征抽取就是对文本数据进行特征值化,注意了,他的类为sklearn.feature_extraction. .CountVectorizer,比之前的要多一个text。
首先我们看看其语法:
CountVectorizer(max_df=1.0,min_df=1,…)
返回词频矩阵
CountVectorizer.fit_transform(X,y)
X:文本或者包含文本字符串的可迭代对象
返回值:返回sparse矩阵
CountVectorizer.inverse_transform(X)
X:array数组或者sparse矩阵
返回值:转换之前数据格式
CountVectorizer.get_feature_names()
返回值:单词列表
注意,这里的CountVectorizer中是没有参数的,上小节我们可以在其中选择sparse为Flase或者True,他们的方法是一模一样的,都存在fit_transform,inverse_transform,get_feature_names。
使用方法和之前字典的流程也是一样:
1.实例化类CountVectorizer
2.调用fit_transform方法输入数据并转换
返回格式,利用toarray()进行sparse矩阵转换array数组
下面是我们实验的文本:
[“life is short,i like python”,
“life is too long,i dislike python”]
编写函数如下:
from sklearn.feature_extraction.text import CountVectorizer
def countvec():
"""
对文本进行特征值化
:return:None
"""
cv = CountVectorizer()
data = cv.fit_transform(["life is short ,i like python","life is too long,i dislike python"])
print(data)
print(cv.get_feature_names())
print(data.toarray())
return None
if __name__ == '__main__':
countvec()
详细过程就不讲解了,我们直接讲解结果,不过要注意,前面提到过CountVectorizer这里没有参数sparse可以选择,只能通过toarray()去把sparse格式数据转化为ndarray格式(二维数组平面格式),然后在打印出来,执行结果如下:
(0, 5) 1
(0, 3) 1
(0, 6) 2
(0, 1) 1
(0, 2) 1
(1, 0) 1
(1, 4) 1
(1, 7) 1
(1, 5) 1
(1, 1) 1
(1, 2) 1
/*所有文本出现的词*/
['dislike', 'is', 'life', 'like', 'long', 'python', 'short', 'too']
/*对每篇文章词出现的数据*/
[[0 1 1 1 0 1 1 0] //
[1 1 1 0 1 1 0 1]]
其中[[0 1 1 1 0 1 2 0]与[1 1 1 0 1 1 0 1]]是统计[‘dislike’, ‘is’, ‘life’, ‘like’, ‘long’, ‘python’, ‘short’, ‘too’]中每个单词的数量,如果把"life is short short,i like python"改成"life is is short short,i like python"(多添加一个is),重新运行,我们可以看到:
['dislike', 'is', 'life', 'like', 'long', 'python', 'short', 'too']
[[0 2 1 1 0 1 1 0]
[1 1 1 0 1 1 0 1]]
注意,在统计的时候,单个字母是不会进行统计的,如单个的a,有兴趣的同学可以自己去进行试验。因为一个字母不会反应出一遍文章的主题,或者情感的。
文件特征的抽取应用是十分的广泛的,如文本分类,情感分析(后面有案例)等等。这些都是文本,情感分析时,就是对一些敏感词汇进行统计,然后在进行分类。
前面的例子我们使用到的是Count,是统计次数的。现在我们用中文,看起会是什么现象:
- data = cv.fit_transform(["life is short ,i like python","life is too long,i dislike python"])
+ data = cv.fit_transform(["人生苦短,我喜欢python", "人生漫长,不用 python"])
然后重新执行程序:
['python', '不用', '人生漫长', '人生苦短', '我喜欢python']
[[0 0 0 1 1]
[1 1 1 0 0]]
可以看到结果,但是这不是我们想要的,应该人生,漫长,苦短,喜欢等等为一个词,而不是四个字 '人生苦短’为一个词,重新改写代码如下:
- data = cv.fit_transform(["人生苦短,我喜欢python", "人生漫长,不用 python"])
- data = cv.fit_transform(["人生 苦短,我 喜欢 python", "人生 漫长,不用 python"])
然后执行代码如下:
['python', '不用', '人生', '喜欢', '漫长', '苦短']
[[1 0 1 1 0 1]
[1 1 1 0 1 0]]
这样就大达到了我们想要的效果,其中我们注意到单个汉字,也不会去统计,因为一个汉字也表达不了实质的意义。可以看出,只要一空格分开,其就能更加好的去分析文章的主题了。
所以在对中文进行处理的时候,先要去进行分词,在进行统计。下面为大家介绍一个分词的工具jieba:
pip3 install jieba
import jieba
jieba.cut(“我是一个好程序员”)
返回值:词语生成器
详细细节就不做介绍了。
下面我们做一个简单的案例,比如对下面的3段话进行分词:
1、今天很残酷,明天更残酷,后天很美好,
但绝对大部分是死在明天晚上,所以每个人不要放弃今天。
2、我们看到的从很远星系来的光是在几百万年之前发出的,
这样当我们看到宇宙时,我们是在看它的过去。
3、如果只用一种方式了解某样事物,你就不会真正了解它。
了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。
编写如下代码:
import jieba
def cutword():
con1 = jieba.cut("今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。")
con2 = jieba.cut("我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。")
con3 = jieba.cut("如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。")
#转化成一个列表
conren1 = list(con1)
conren2 = list(con2)
conren3 = list(con3)
c1 = ' '.join(conren1)
c2 = ' '.join(conren2)
c3 = ' '.join(conren3)
return c1,c2,c3
def hanzivec():
"""
中文特征值化
:return: None
"""
c1,c2,c3 = cutword()
print(c1,c2,c3)
cv = CountVectorizer()
data = cv.fit_transform([c1,c2,c3])
print(data)
print(cv.get_feature_names())
print(data.toarray())
if __name__ == '__main__':
hanzivec()
执行代码结果如下
今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。 我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。 如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。
['一种', '不会', '不要', '之前', '了解', '事物', '今天', '光是在', '几百万年', '发出', '取决于', '只用', '后天', '含义', '大部分', '如何', '如果', '宇宙', '我们', '所以', '放弃', '方式', '明天', '星系', '晚上', '某样', '残酷', '每个', '看到', '真正', '秘密', '绝对', '美好', '联系', '过去', '这样']
[[0 0 1 0 0 0 2 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 2 0 1 0 2 1 0 0 0 1 1 0 0 0]
[0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 1 3 0 0 0 0 1 0 0 0 0 2 0 0 0 0 0 1 1]
[1 1 0 0 4 3 0 0 0 0 1 1 0 1 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 2 1 0 0 1 0 0]]
假设两篇文章比较相近,那么出现某些词,也会比较相似的。这个就是文章的特征抽取。当然这个文本特征抽取的第一种方式,后续还会讲解其他的方式。