利用TF-IDF及余弦公式处理文本相似性的计算
1 思路
要计算相似性,首先将文本转换成可计算的数。
比较简单的一种方式是把所有文章中的词作为坐标,在一篇文章上,对应词的词频作为在该坐标上的值,即可将一篇文章按词频转换成词向量——有了向量,相似性就好算了:距离公式、余弦都可以直接用。
更进一步:词频作权重过于简单,TF-IDF更有代表性。使用TF-IDF相当于考虑了词的重要性,计算出的相似性效果有使用价值了。
后续:要更精确,就需要考虑词与词之间相对位置的影响,涉及语义模型了,本篇暂不涉及。
2 处理过程
前置过程:已爬取约100篇文本存入MongoDB中,通过访问数据库直接取用对应文本。
2.1 首先要把文章分词
直接用大名顶顶的jiba分词,并使用哈工大停用词表+部分手工整理的停用词进行无效词剔除。
最终:将每篇文章转换成一个有分割符的词列(str),把词列并至一个list变量中输出待用。
def stopWords():
stopwords = []
for line in open('C:\\Users\\chai\\Documents\\哈工大停用词表.txt'):
stopwords = stopwords + list(line)
return stopwords
def get_corpus():
corpus = []
for item in article_content.find().limit(5):
seg = jieba.lcut(item['article_text'],cut_all=False)
seg_text = ""
for words in seg:
if words not in stopWords():
seg_text = seg_text + words
seg_text += " "
corpus.append(seg_text)
return corpus
展示几篇文章词列表:
新生儿 降生 后先 啼哭 数声 开始 肺 呼吸 头 两周 每分钟 呼吸 40 50 新生儿 脉搏 每分钟 120 140 次为 正常 新生儿 正常 体重 3000 4000 克 低于 2500 克 属于 未成熟 新生儿 头 两天 大便 呈 黑色 绿粘笛状 无气味 喂奶 逐渐 转为 黄色 金黄色 浅黄色 新生儿 出生 24 小时 内 开始 排尿 超过 第一周 内 每日 排尿 30 以上 异常 新生儿 体温 37 37.5 摄氏度 之间 政治 注意 保暖 体重 降低 36 摄氏度 以下 多数 新生儿 出生 皮肤 轻微 发黄 出生 黄疸 不退 加深 病态 新生儿 出生 觅食 吸允 伸舌 右咽 拥抱 反射 新生儿 照射 光可 引起 眼 反射 第二个 月 开始 视线 追随 活动 玩具 10 出生 新生儿 听觉 逐渐 增强 听见 响声 引起 眨眼 动作
机会 现在 开始 接触 宝宝 即可 发现 小宝宝 自己 肢体 语言 透过 表情 动作 说话 从中 得到 相当 高 乐趣 帮助 宝宝 智能 情绪 发展 增进 亲子 互动 减低 照顾 宝宝 挫折感 宁静 睡眠期 双眼 闭着 呼吸 平稳 规则 没有 自发性 运动 外观 一看 睡觉 阶段 不易 叫醒 宝宝 活动 型 睡眠期 双眼 闭着 呼吸 快 不规则 偶尔 手脚 会动 眼睛 微 睁开 笑 作出 表情 照顾 常 以为 宝宝 并未 睡着 阶段 不易 叫醒 宝宝 昏昏欲睡 期 想 睡 样子 眼睛 半睁 目光 迟滞 呈 迷糊 状态 通常 反应 给予 刺激 容易 改变 动态 时期 叫醒 宝宝 ………………
2.2 计算TF-IDF 生成向量
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
def tfidf():
corpus = get_corpus()
vectorizer=CountVectorizer()#该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频
transformer=TfidfTransformer()#该类会统计每个词语的tf-idf权值
tfidf=transformer.fit_transform(vectorizer.fit_transform(corpus))#第一个fit_transform是计算tf-idf,第二个fit_transform是将文本转为词频矩阵
word=vectorizer.get_feature_names()#获取词袋模型中的所有词语
weight=tfidf.toarray()#将tf-idf矩阵抽取出来,元素a[i][j]表示j词在i类文本中的tf-idf权重
return weight
2.3 余弦相似性计算
向量余弦公式:
余弦相似性
#余弦相似性转换成python
def dot_product(v1, v2):
return sum(a * b for a, b in zip(v1, v2))
def magnitude(vector):
return math.sqrt(dot_product(vector, vector))
def similarity(v1, v2):
return dot_product(v1, v2) / (magnitude(v1) * magnitude(v2) + .00000000001)
def sim(weight):
#计算两两余弦:
for i in range(len(weight)):
sim_list = []
print('----这是第', i, u"类文本的相似性计算")
for j in range(len(weight)):
if j != i:
sim = similarity(weight[i],weight[j])
print(u'和第',j,u"篇文章的相似性为",sim)
输出结果示例
----这是第 0 类文本的相似性计算
和第 1 篇文章的相似性为 0.152645600023
和第 2 篇文章的相似性为 0.131098394898
和第 3 篇文章的相似性为 0.301936590914
和第 4 篇文章的相似性为 0.0276679076045
3 未决问题
- 数据处理完善:相似性排序、输出时保留文章序号
- 计算结果检查、调优;
- 不同部分的权重处理:标题(这次计算未纳入标题词)应该赋予更高权重。