TF-IDF
信息检索中最常用的一种文本关键信息表示法基本思想:若在一个文档中出现的频率高,且在语料库中其它文本中很少出现,则人文这个词库有很好的区分能力。词频TF:Term Frequency,衡量一个term在文档中出现的有多频繁,越频繁,其重要性可能越高。考虑到文章长度差异,需要对词频做标准化: TF(t)=(t出现在文档中的次数)/(文档中term总数)TF(t)=(t出现在文档中的次数)/(文档中出现最多的term的次数)逆文档频率IDF:Inverse Document Frequency,用于模拟在该语料库的实际使用环境中,某一个term有多重要
有些词到处出现,但是明显没什么用。比如各种停用词,过渡句用词之类的。
因此把罕见的词的重要性(weight)调高,把常见词的重要性调低。
IDF具体算法:
IDF(t) = log(语料库中的文档总数/(含有该term的文档总数+1))
TF-IDF=TF*IDF
TF-IDF与一个词在文档中的出现次数成正比。与该词在整个语料中的出现次数成反比。
TF-IDF
优点 简单快速结果也比较符合实际情况 缺点 单纯以“词频”衡量一个词的重要性,不够全面,有时重要的词可能出现次数并不多无法考虑词与词之间的相互关系这种算法无法体现词的位置信息,出现位置靠前的词与出现位置靠后的词都被视为重要性相同,这是不正确的。 一种解决方法是,对全文的第一段和每一段的第一句话,给予较大的权重。TF-IDF的具体实现
jieba、NLTK、sklearn、gensim等程序都可以实现TF-IDF的计算。除算法细节上会有差异外,更多的是数据输入/输出格式上的不同。
TD-IDF的jieba实现
输出结果会自动按照TF-IDF值降序排列,并且直接给出的是字条而不是字典ID,便于阅读使用。可在计算TF-IDF时直接完成分词,并使用停用词表和自定义词库,非常放便。有默认的IDF语料库,可以不训练模型,直接进行计算。以单个文本为单位进行分析。
jieba.analyse.extract_tags(sentence : 为待提取的文本topK = 20 :返回几个 TF/IDF 权重最大的关键词withWeight = False : 是否一并返回关键词权重值allowPOS = () : 仅包括指定词性的词,默认值为空,既不筛选)
import jiebaimport jieba.analysejieba.analyse.extract_tags("""故今日之责任,不在他人,而全在我少年。少年智则国智,少年富则国富,少年强则国强,少年独立则国独立,少年自由则国自由,少年进步则国进步,少年胜于欧洲,则国胜于欧洲,少年雄于地球,则国雄于地球。红日初升,其道大光;河出伏流,一泻汪洋;潜龙腾渊,鳞爪飞扬;乳虎啸谷,百兽震惶;鹰隼试翼,风尘翕张;奇花初胎,矞矞皇皇;干将发硎,有作其芒;天戴其苍,地履其黄;纵有千古,横有八荒;前途似海,来日方长。美哉,我少年中国,与天不老!壮哉,我中国少年,与国无疆!""")
结果:
[‘少年’,
‘国强’,
‘鳞爪’,
‘进步’,
‘八荒’,
‘地球’,
‘大光’,
‘而全’,
‘智则’,
‘国智’,
‘富则’,
‘强则’,
‘国胜于’,
‘雄于’,
‘初升’,
‘其道’,
‘河出伏流’,
‘一泻’,
‘龙腾渊’,
‘乳虎啸’]
应用自定义词典改善分词效果
我定义的词库截图:
#应用自定义词典改善分词效果jieba.load_userdict("C:\\Users\\Dell\\Desktop\\词库.txt")jieba.lcut("""故今日之责任,不在他人,而全在我少年。少年智则国智,少年富则国富,少年强则国强,少年独立则国独立,少年自由则国自由,少年进步则国进步,少年胜于欧洲,则国胜于欧洲,少年雄于地球,则国雄于地球。红日初升,其道大光;河出伏流,一泻汪洋;潜龙腾渊,鳞爪飞扬;乳虎啸谷,百兽震惶;鹰隼试翼,风尘翕张;奇花初胎,矞矞皇皇;干将发硎,有作其芒;天戴其苍,地履其黄;纵有千古,横有八荒;前途似海,来日方长。美哉,我少年中国,与天不老!壮哉,我中国少年,与国无疆!""")
结果:
[‘故今日之责任’,
‘,’,
‘不在他人’,
‘,’,
‘而全在我少年’,
‘。’,
·····省略一部分··············
‘壮哉’,
‘,’,
‘我中国少年’,
‘,’,
‘与国无疆’,
‘!’]
在TF-IDF计算中直接应用停用词表
s = """故今日之责任,不在他人,而全在我少年。少年智则国智,少年富则国富,少年强则国强,少年独立则国独立,少年自由则国自由,少年进步则国进步,少年胜于欧洲,则国胜于欧洲,少年雄于地球,则国雄于地球。红日初升,其道大光;河出伏流,一泻汪洋;潜龙腾渊,鳞爪飞扬;乳虎啸谷,百兽震惶;鹰隼试翼,风尘翕张;奇花初胎,矞矞皇皇;干将发硎,有作其芒;天戴其苍,地履其黄;纵有千古,横有八荒;前途似海,来日方长。美哉,我少年中国,与天不老!壮哉,我中国少年,与国无疆!"""jieba.analyse.set_stop_words("F:\\HMM\\stopwords.txt")jieba.analyse.extract_tags(s,withWeight = True) #返回权重值
结果:
[(‘故今日之责任’, 0.30653250007435895),
(‘不在他人’, 0.30653250007435895),
(‘而全在我少年’, 0.30653250007435895),
(‘少年智则国智’, 0.30653250007435895),
(‘少年富则国富’, 0.30653250007435895),
(‘少年强则国强’, 0.30653250007435895),
(‘少年独立则国独立’, 0.30653250007435895),
(‘少年自由则国自由’, 0.30653250007435895),
(‘少年进步则国进步’, 0.30653250007435895),
(‘少年胜于欧洲’, 0.30653250007435895),
(‘则国胜于欧洲’, 0.30653250007435895),
(‘少年雄于地球’, 0.30653250007435895),
(‘则国雄于地球’, 0.30653250007435895),
(‘红日初升’, 0.30653250007435895),
(‘其道大光’, 0.30653250007435895),
(‘河出伏流’, 0.30653250007435895),
(‘一泻汪洋’, 0.30653250007435895),
(‘潜龙腾渊’, 0.30653250007435895),
(‘鳞爪飞扬’, 0.30653250007435895),
(‘乳虎啸谷’, 0.30653250007435895)]
关键词提取时使用自定义逆向文件频率(IDF)语料库
jieba.analyse.set_idf_path(file_name)
新建TF-IDF模型实例
jieba.analyse.TFIDF(idf_path = None)新建TFIDF模型实例idf_path : 读取已有的TFIDF频率文件(即已有模型)使用该实例提取关键词:TFIDF实例.extract_tags()
TD-IDF的sklearn实现
输出格式为矩阵,直接为后续的sklearn建模服务需要先使用背景语料库进行模型训练结果中给出的是字典ID而不是具体词条,直接阅读结果比较困难class sklearn.feature_extraction.text.TfidfTransformer()
import pandas as pds = pd.read_csv('F:\\HMM\\射雕_chapter.csv',engine='python',encoding='utf-8',index_col=0)s.head()
结果:
from sklearn.feature_extraction.text import TfidfTransformer
txt_5 = [" ".join(jieba.lcut(w)) for w in s.txt.iloc[:5]]txt_5
结果:
分词去停用词
stop_raw = pd.read_csv("F:\\HMM\\stopwords.txt",names=['w'],sep='abc',encoding='utf-8',engine='python')stopwords=list(stop_raw.w)def m_cut(txt):return [w for w in jieba.cut(txt) if w not in stopwords and len(w)>1]txt_5 = [' '.join(m_cut(w)) for w in s.txt.iloc[:5]]txt_5
结果:
将txt_5转换为词频矩阵
from sklearn.feature_extraction.text import CountVectorizervectorizer = CountVectorizer()words_frec = vectorizer.fit_transform(txt_5) #将txt_5转换为词频矩阵
s_tfidf = TfidfTransformer()s_tfidf = s_tfidf.fit_transform(words_frec)s_tfidf
结果:
<5x11684 sparse matrix of type ‘<class ‘numpy.float64’>’
with 16982 stored elements in Compressed Sparse Row format>
转换为数组
s_tfidf.toarray()
结果:
转换为矩阵
s_tfidf.todense()
结果:
s_tfidf.todense().shape
结果:
(5, 11684)
每列对应的词
vectorizer.get_feature_names()
结果:
len(vectorizer.get_feature_names())
结果:
11684
词条字典
vectorizer.vocabulary_
结果: