4.中文特征提取
上一节我们讲到了英文特征提取的实现。
from sklearn.feature_extraction.text import CountVectorizer
def english_count():
# 1.获取数据
data = ["The more we do, the more we can do; the more busy we are, the more leisure we have."]
# 2.文本转换
transfer = CountVectorizer()
res = transfer.fit_transform(data)
# 3.查看
names = transfer.get_feature_names()
print("特征名字:\n",names)
print("最终结果: \n",res)
if __name__ == '__main__':
english_count()
思考:如果要实现中文特征提取,将data内容的英文改成中文可行吗?
二话不说,拿起键盘就是干!
data = ["我们总把人生想得太坏,像旁人不允许我们的怪。"]
运行结果:
发现这与我们平常划分词汇的方式不同…
原来,CountVectorizer()的方法是以空格来划分单词的。因此,我们通过人为加空格的方式将字符进行分隔。
data = ["我们 总 把 人生 想得 太坏,像 旁人 不允许 我们 的 怪。"]
运行结果:
思考:如果数据量大的时候通过加空格的方式去分隔,效率是不是太低下了呢?
解决方案: 通过终端安装jieba库
pip3 install jieba
举个🌰: 通过对以下数据进行特征提取,统计每个单词出现的频率。
数据:
data = [“我们总把人生想得太坏,像旁人不允许我们的怪。”,
“秋天的时候,柿子树一熟,够我们吃很久。”,
“容不下,我百无聊赖,不应该,一个人,发呆。”]
流程分析:
(1)准备句子,利用jieba.cut进行分词
(2)实例化CountVectorizer
(3)将分次结果变成字符串当作fit_transform的输入值
具体实现:
(1)cut_word(text)方法实现
import jieba
def cut_word(text):
res = " ".join(list(jieba.cut(text)))
print(res)
if __name__ == '__main__':
cut_word("我们总把人生想得太坏,像旁人不允许我们的怪。")
输出结果:
list方法将对象进行强制转换,而" ".join的方式通过空格实现字符连接。
(2)chinese_count()方法实现
from sklearn.feature_extraction.text import CountVectorizer
import jieba
def cut_word(text):
return " ".join(list(jieba.cut(text)))
def chinese_count():
# 1.获取数据
data = ["我们总把人生想得太坏,像旁人不允许我们的怪。",
"秋天的时候,柿子树一熟,够我们吃很久。",
"容不下,我百无聊赖,不应该,一个人,发呆。"]
# 2.内容分割
list = []
for temp in data:
list.append(cut_word(temp))
print(list)
# 3.文本特征转换
# 3.1 实例化+转化
transfer = CountVectorizer()
res = transfer.fit_transform(list)
# 3.2 查看特征名字
names = transfer.get_feature_names()
print("特征名字:\n",names)
print(res.toarray())
print(res)
if __name__ == '__main__':
chinese_count()
输出结果:
思考:特征提取只是针对某个词出现的数量,或者说频率进行统计,意义并不是很大。相对有意义的是通过某些高频词汇在整体出现的频率来判断文章的内容类型。
5.Tf-idf文本特征提取
(1)主要思想:
如果某个词或者短语在一篇文章中出现的概率高,而在其他文章中很少出现,则可以认为该词或短语有很好的类别区分能力,适合用来分类。
(2)作用:
用以评估某个字或者某个词语对于一个文件集或一个语料库中的其中一份文件的重要程度。
(3)公式:
tf: 词频,指的是某一个给定词语在文件中出现的频率。
idf: 逆向文档频率,是一个词语普遍重要性的度量。计算方式是log10(总文件数目 / 包含该词语的文件的数目)
tfidf: 可以理解为重要程度。
举个🌰:
假如一篇文章的总词语数是100个,而A词语出现了5次,那么A词语在文章中的词频tf = 5 / 100 = 0.05。
如果A词语在10,000篇文章中出现过,而文章总是是10,000,000份的话,其逆向文件频率就是log10(10,000,000 / 10,000)=3
所以,A词语对于这篇文章的tfidf = 0.05 × 3 = 0.15
(4)具体实现:
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba
def cut_word(text):
return " ".join(list(jieba.cut(text)))
def tfidf_count():
# 1.获取数据
data = ["我还是从前那个少年,没有一丝丝改变",
"人们都这样想,都这样迷失",
"夏天的风,我永远记得,清清楚楚的说你爱我"]
# 2.文章分割
list = []
for temp in data:
list.append(cut_word(temp))
# 3.文本特征转换
# 3.1 实例化+转化
transfer = TfidfVectorizer()
res = transfer.fit_transform(list)
# 3.2 查看特征名字
names = transfer.get_feature_names()
print("特征名字:\n",names)
print("\n")
print(res.toarray())
print("\n")
print(res)
if __name__ == '__main__':
tfidf_count()
(5)运行结果: