赞
踩
TF-IDF方法的主要思想是:如果某个词或短语在一篇文章中出现的频率(TF) 高,并且在其他文章中很少出现(IDF高),则认为此词或者短语具有很好的类别区分能力。
首先对文档进行特征提取操作:
(1)分割句子:按照空格进行分割,去除数字以及标点符号,并将所有字符全部小写;
(2)去除词汇:去除代词、冠词等功能词;
(3)词干提取:去除单词的复数、过去式、比较级、最高级等形式。
然后对生成的语料库进行每个文档的词频计算、反文档频率计算操作,从而构建出TF-IDF映射表。此时,每个文档都能够用一个单词向量表示。
最终对两个文档的单词向量使用余弦公式进行相似度计算即可。流程图如下所示:
我们需要将待处理的文本数据,全部用txt格式保存。如果原始数据是doc或者docx文件,建议先使用word的替换功能,替换掉原始文本数据中的换行符、段落标记等,替换成空格,再保存到txt文件里,常用特殊符号的替换方法如下:
输入符号 | 含义 |
^p | 段落标记 |
^l | 手动换行符 |
^m | 手动分页符 |
^s | 不间断空格 |
^+ | 长划线 |
^= | 短划线 |
^~ | 不间断连字符 |
- import re
- import nltk.stem.snowball as sb
- import pandas as pd
- import math
- from scipy import spatial
包名 | 用途 |
re | 正则表达式 |
nltk.stem.snowball | 词干提取 |
pandas | 输出格式控制 |
math | 数学计算 |
spatial | 计算余弦相似度 |
- pd.set_option('display.max_columns', 1000)
- pd.set_option('display.width', 1000)
- pd.set_option('display.max_colwidth', 1000)
注意:用于控制台输出多行多列数据,而不是省略号,更方便我们确定数据的正确性和完整性。
- def sentence_divide(path):
- data = []
- with open(path, "r", encoding='utf-8') as f:
- for line in f.readlines():
- # 1.去除数字,标点,且所有字符全部小写
- line = re.sub(r'[.,"\'-?:!;]', '', line).lower()
- line = line.strip("\n")
- # 2.按照空格分隔
- line = line.split()
- data.append(line)
- return data[0]
注意:这里最后return data[0],因为我提前将文本存储为一行,如果你的txt自动换行,可以关闭这个功能,或者把return data[0]改为return data。
- def delete_word(wordlist):
- stop_words = ['i', 'me', 'my', 'myself', 'we', 'is', 'for', 'the', 'those', 'a', 'of', 'he', 'so', 'they', 'may',
- 'all', 'which', 'shall', 'towards', 'being', 'been', 'had', 'have', 'having', 'whose', 'was',
- 'she', 'it', 'then', 'and', 'by', 'if', 'where', 'when', 'how', 'would', 'not', 'such', 'through',
- 'do', 'their', 'be', 'were', 'an',
- 'as', 'this', 'that', 'in', 'on', 'to', 'but', 'there', 'into', 'or', 'should']
- words = []
- for word in wordlist:
- if word not in stop_words:
- words.append(word)
- return words
注意:这里的stop_words相当与nltk库里的stop_words停止词,就是过滤掉我们原始文档中存在的这些没有实际意义的介词、连词等。下载nltk库里的stop_words会出问题,建议和我一样,自己制定就行。
- def standard_word(wordlist):
- words = []
- # 词干提取
- sb_stemmer = sb.SnowballStemmer('english')
- for word in wordlist:
- words.append(sb_stemmer.stem(word))
- return words
- def word_lib(wordlist1, wordlist2, wordlist3, wordlist4):
- lib = wordlist1+wordlist2+wordlist3+wordlist4
- lib = set(lib)
- return lib
注意:这里的wordlist1, wordlist2, wordlist3, wordlist4,是因为我有四个文档需要对比,因此就放在了一起,你有几个文档,就写几个。
- def token_fre(wordlist, wordslib):
- d = {}
- corpusCount = len(wordlist)
- for w in wordslib:
- d[w] = 0
- for word in wordlist:
- d[word] += 1
- for word, c in d.items():
- d[word] = c / float(corpusCount)
- return d
注意:词频计算,n为该词在当前文本中出现的次数,sum为当前文本的总词数。实质就是就是计算文档中每个词汇在单个文本中出现的频率。
- def idf_fre(wordlist):
- idfDict = {}
- N = len(wordlist)
- idfDict = dict.fromkeys(wordlist[0].keys(), 0)
- for word, val in idfDict.items():
- idfDict[word] = math.log10(N / (float(val) + 1))
- return (idfDict)
注意:文档频率计算。其中N为文档总个数,n为包含该词的文档个数,加1是为了防止分母为0。
- def computeTFIDF(tfBow, idfs):
- tfidf = {}
- for word, val in tfBow.items():
- tfidf[word] = val * idfs[word]
- return tfidf
注意:。
- def cosine_cal(v1, v2):
- cos_sim = 1 - spatial.distance.cosine(v1, v2)
- return cos_sim
文本相似度分析的方法还有其他,以后有机会再学习
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。