前言
- 在对文本信息处理得过程中,我们会使用分词工具对文本字符串进行分词处理,然后进行频率统计,就会明白文本字符串中关键词的重要性占比。
- 但是,问题来了,难道,诸如:“所以”、“也许”、“或者”… 这样的词能说明其很重要?答案当然是否!
- 所以,TF-IDF算法就来解决了这一问题。
原理
- Tf,也就是term frequency,它代表了词的频率(“词频”);
可以这样计算 :词频 = 某词在文章中出现的次数/文章中总词的次数 - idf,也就是inverse document frequency,代表了逆文档频率
可以这样计算:逆文档频率 = log(总文档数/出现该词的文档数) - 该词的重要性就是:拿词频*逆文档频率即可。
也就是:词的重要性 = Tf * idf - ps: 关于log,我多介绍一下,请先看这个链接:对数函数(log):
根据log函数的单调性(此时e=a>1),它是单调递增的,于是得出,当一个词在所有文档中出现的次数越多,其越不重要,也就是诸如“所以”、“也许”、“或者”…会在数据分析的权重中被稀释掉。
实际应用
- TfidfVectorizer()这个类实现了该算法
没有表现出“重要性”的代码片
# coding: utf-8
import jieba
from sklearn.feature_extraction.text import CountVectorizer
def cut_word():
"""
使用jieba分词,实现中文特征值化
:return: 分词之后的结果,list,
"""
con1 = jieba.cut("胆小鬼连幸福都会害怕,碰到棉花都会受伤,有时还被幸福所伤。") # 返回分词后的生成器
con2 = jieba.cut("人啊,明明一点儿也不了解对方,错看对方,却视彼此为独一无二的挚友,一生不解对方的真性情,待一方撒手西去,还要为其哭泣,念诵悼词。")
con3 = jieba.cut(
"早晨,我睁眼醒来翻身下床,又变成了原来那个浅薄无知、善于伪装的滑稽角色。胆小鬼连幸福都会惧怕,碰到棉花都会受伤,有时也会被幸福所伤。趁着还没有受伤,我想就这样赶快分道扬镳。我又放出了惯用的逗笑烟幕弹。")
# 转换成列表
content1 = list(con1)
content2 = list(con2)
content3 = list(con3)
# 把列表转化成以空格隔开的字符串
c1 = ' '.join(content1)
c2 = ' '.join(content2)
c3 = ' '.join(content3)
return c1, c2, c3
def hanzivec():
"""
中文特征值化:普通的
:return: None
"""
c1, c2, c3 = cut_word()
# print(c1, c2, c3)
cv = CountVectorizer()
data = cv.fit_transform([c1, c2, c3])
# print(cv.get_feature_names())
print(data.toarray())
return None
if __name__ == '__main__':
hanzivec() # 普通的
# ['一方', '一点儿', '一生', '不解', '了解', '伪装', '分道扬镳', '却视', '原来', '受伤', '变成', '哭泣', '善于', '害怕', '对方', '幸福', '彼此', '念诵', '悼词', '惧怕', '惯用', '挚友', '撒手', '放出', '无知', '早晨', '明明', '有时', '棉花', '没有', '浅薄', '滑稽角色', '烟幕弹', '独一无二', '真性情', '睁眼', '碰到', '翻身', '胆小鬼', '赶快', '趁着', '还要', '这样', '逗笑', '那个', '醒来', '错看']
# [[0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 2 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0
# 1 0 1 0 0 0 0 0 0 0 0]
# [1 1 1 1 1 0 0 1 0 0 0 1 0 0 3 0 1 1 1 0 0 1 1 0 0 0 1 0 0 0 0 0 0 1 1 0
# 0 0 0 0 0 1 0 0 0 0 1]
# [0 0 0 0 0 1 1 0 1 2 1 0 1 0 0 2 0 0 0 1 1 0 0 1 1 1 0 1 1 1 1 1 1 0 0 1
# 1 1 1 1 1 0 1 1 1 1 0]]
表现出“重要性”的代码片
# coding: utf-8
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
def cut_word():
"""
使用jieba分词,实现中文特征值化
:return: 分词之后的结果,list,
"""
con1 = jieba.cut("胆小鬼连幸福都会害怕,碰到棉花都会受伤,有时还被幸福所伤。") # 返回分词后的生成器
con2 = jieba.cut("人啊,明明一点儿也不了解对方,错看对方,却视彼此为独一无二的挚友,一生不解对方的真性情,待一方撒手西去,还要为其哭泣,念诵悼词。")
con3 = jieba.cut(
"早晨,我睁眼醒来翻身下床,又变成了原来那个浅薄无知、善于伪装的滑稽角色。胆小鬼连幸福都会惧怕,碰到棉花都会受伤,有时也会被幸福所伤。趁着还没有受伤,我想就这样赶快分道扬镳。我又放出了惯用的逗笑烟幕弹。")
# 转换成列表
content1 = list(con1)
content2 = list(con2)
content3 = list(con3)
# 把列表转化成以空格隔开的字符串
c1 = ' '.join(content1)
c2 = ' '.join(content2)
c3 = ' '.join(content3)
return c1, c2, c3
def tfidfvec():
"""
中文特征值化:重要性
:return: None
"""
c1, c2, c3 = cut_word()
# print(c1, c2, c3)
tf = TfidfVectorizer()
data = tf.fit_transform([c1, c2, c3])
print(tf.get_feature_names())
print(data.toarray()) # 此处得出来得值便是重要性了
return None
if __name__ == '__main__':
tfidfvec()
# 输出
# ['一方', '一点儿', '一生', '不解', '了解', '伪装', '分道扬镳', '却视', '原来', '受伤', '变成', '哭泣', '善于', '害怕', '对方', '幸福', '彼此', '念诵', '悼词', '惧怕', '惯用', '挚友', '撒手', '放出', '无知', '早晨', '明明', '有时', '棉花', '没有', '浅薄', '滑稽角色', '烟幕弹', '独一无二', '真性情', '睁眼', '碰到', '翻身', '胆小鬼', '赶快', '趁着', '还要', '这样', '逗笑', '那个', '醒来', '错看']
# [[0. 0. 0. 0. 0. 0.
# 0. 0. 0. 0.30529678 0. 0.
# 0. 0.40142857 0. 0.61059355 0. 0.
# 0. 0. 0. 0. 0. 0.
# 0. 0. 0. 0.30529678 0.30529678 0.
# 0. 0. 0. 0. 0. 0.
# 0.30529678 0. 0.30529678 0. 0. 0.
# 0. 0. 0. 0. 0. ]
# [0.19611614 0.19611614 0.19611614 0.19611614 0.19611614 0.
# 0. 0.19611614 0. 0. 0. 0.19611614
# 0. 0. 0.58834841 0. 0.19611614 0.19611614
# 0.19611614 0. 0. 0.19611614 0.19611614 0.
# 0. 0. 0.19611614 0. 0. 0.
# 0. 0. 0. 0.19611614 0.19611614 0.
# 0. 0. 0. 0. 0. 0.19611614
# 0. 0. 0. 0. 0.19611614]
# [0. 0. 0. 0. 0. 0.18588519
# 0.18588519 0. 0.18588519 0.28274095 0.18588519 0.
# 0.18588519 0. 0. 0.28274095 0. 0.
# 0. 0.18588519 0.18588519 0. 0. 0.18588519
# 0.18588519 0.18588519 0. 0.14137048 0.14137048 0.18588519
# 0.18588519 0.18588519 0.18588519 0. 0. 0.18588519
# 0.14137048 0.18588519 0.14137048 0.18588519 0.18588519 0.
# 0.18588519 0.18588519 0.18588519 0.18588519 0. ]]
补充
- 代码片的输出是基于one-hot编码的,如果不了解的话,请参考:one-hot
来源:CSDN
作者:如厮__
链接:https://blog.csdn.net/rusi__/article/details/103647358