基于 TF-IDF 计算古诗之间的文本相似度

步骤

  1. 对每一首古诗进行分词
  2. 计算每一个词的 tfidf 值
  3. 利用每首古诗的词向量计算两首古诗之间的余弦相似度
import pandas as pd
import numpy as np
import pickle

path = 'F:/1.csv'
df = pd.read_csv(path)
df.head()
_id标题诗人诗人id朝代内容译文鉴赏背景古诗标签古诗star数
01关雎佚名0先秦关关雎鸠,在河之洲。窈窕淑女,君子好逑。\n参差荇菜,左右流之。窈窕淑女,寤寐求之。\n求之...译文\n关关和鸣的雎鸠,相伴在河中的小洲。那美丽贤淑的女子,是君子的好配偶。\n参差不齐的荇...《国风·周南·关雎》这首短小的诗篇,在中国文学史上占据着特殊的位置。它是《诗经》的第一篇,而...写作手法\n\n  这诗的主要表现手法是兴寄,《毛传》云:“兴也。”什么是“兴”?孔颖达的解...古诗三百首,初中古诗,诗经,爱情14233
110汝坟佚名0先秦遵彼汝坟,伐其条枚。未见君子,惄如调饥。\n遵彼汝坟,伐其条肄。既见君子,不我遐弃。\n鲂鱼...译文\n沿着汝河大堤走,采伐山楸那枝条。还没见到我夫君,忧如忍饥在清早。\n沿着汝河大堤走,...鉴赏\n\n  这在诗之首章,“遵彼汝坟,伐其条枚”——在高高的汝河大堤上,有一位凄苦的妇女...影响\n\n  相传为孔子编辑成书,集入西周至春秋中叶五百多年的作品305篇,分为风雅颂三个...诗经,思念330
2100南山佚名0先秦南山崔崔,雄狐绥绥。鲁道有荡,齐子由归。既曰归止,曷又怀止?\n葛屦五两,冠緌双止。鲁道有荡...译文\n南山巍峨高峻,雄狐缓步独行。鲁国大道宽阔,文姜由此嫁人。既然嫁给鲁君,为何思念难禁?...鉴赏\n\n  作者开篇描写雄狐对伴侣的渴望,用意在于影射齐襄公对文姜的觊觎之心。作者以南山...创作背景\n\n  春秋时期,齐国和鲁国联姻,齐襄公的同父异母妹妹文姜被嫁给了鲁桓公,但文姜...诗经,怨刺72
31000舞曲歌辞。中和乐舞词佚名0唐代芳岁肇佳节,物华当仲春。乾坤既昭泰,烟景含氤氲。 \n德浅荷玄贶,乐成思治人。前庭列钟鼓,广...NaNNaNNaNNaN2
410000与从弟正字、从兄兵曹宴集林园李嘉祐760唐代竹窗松户有佳期,美酒香茶慰所思。辅嗣外生还解易, \n惠连群从总能诗。檐前花落春深后,谷里莺...NaNNaNNaNNaN1

数据清洗

content_s = df['内容']
content_s.head()
0    关关雎鸠,在河之洲。窈窕淑女,君子好逑。\n参差荇菜,左右流之。窈窕淑女,寤寐求之。\n求之...
1    遵彼汝坟,伐其条枚。未见君子,惄如调饥。\n遵彼汝坟,伐其条肄。既见君子,不我遐弃。\n鲂鱼...
2    南山崔崔,雄狐绥绥。鲁道有荡,齐子由归。既曰归止,曷又怀止?\n葛屦五两,冠緌双止。鲁道有荡...
3    芳岁肇佳节,物华当仲春。乾坤既昭泰,烟景含氤氲。 \n德浅荷玄贶,乐成思治人。前庭列钟鼓,广...
4    竹窗松户有佳期,美酒香茶慰所思。辅嗣外生还解易, \n惠连群从总能诗。檐前花落春深后,谷里莺...
Name: 内容, dtype: object
def _filter(arg):
    arg = arg.replace('\n', '')
    return arg

content_s = content_s.apply(_filter)
content_s.head()
0    关关雎鸠,在河之洲。窈窕淑女,君子好逑。参差荇菜,左右流之。窈窕淑女,寤寐求之。求之不得,寤...
1    遵彼汝坟,伐其条枚。未见君子,惄如调饥。遵彼汝坟,伐其条肄。既见君子,不我遐弃。鲂鱼赪尾,王...
2    南山崔崔,雄狐绥绥。鲁道有荡,齐子由归。既曰归止,曷又怀止?葛屦五两,冠緌双止。鲁道有荡,齐...
3    芳岁肇佳节,物华当仲春。乾坤既昭泰,烟景含氤氲。 德浅荷玄贶,乐成思治人。前庭列钟鼓,广殿延...
4    竹窗松户有佳期,美酒香茶慰所思。辅嗣外生还解易, 惠连群从总能诗。檐前花落春深后,谷里莺啼日...
Name: 内容, dtype: object

分词测试

first = content_s[0]
first

import jieba
import re

stop_words = ['而', '何', '乎', '乃', '其', '且', '若', '所', '为', '焉', '以', 
              '因', '于', '与','也','则','者','之','不','自','得','一','来','去',
              '无', '可', '是', '已', '此', '的', '上', '中', '兮', '三']

# 因为要对古诗进行分词,尽量把有歧义句子进行更多的多分解
temp = ' '.join(jieba.cut(first, cut_all=True))
temp = re.sub('[,。]', ' ', temp)
temp
Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\Liang\AppData\Local\Temp\jieba.cache
Loading model cost 0.677 seconds.
Prefix dict has been built successfully.





'关关 关关雎 雎鸠   在 河之洲   窈窕 窈窕淑女 淑女   君子 君子好逑 好逑   参差 荇 菜   左右 流 之   窈窕 窈窕淑女 淑女   寤寐 寤寐求之   求之不得 不得   寤寐 思 服   悠哉 悠哉悠哉 悠哉   辗转 辗转反侧 反侧   参差 荇 菜   左右 采 之   窈窕 窈窕淑女 淑女   琴瑟 友 之   参差 荇 菜   左右 芼 之   窈窕 窈窕淑女 淑女   钟鼓 鼓乐 之  '

分词

def fenci(arg):
#     arg = ' '.join(jieba.cut(arg, cut_all=True))
    arg = ' '.join(jieba.cut(arg, cut_all=True))
    arg = re.sub('[,。]', ' ', arg)
    return arg

content_s = content_s.apply(fenci)
content_s.head()
0    关关 关关雎 雎鸠   在 河之洲   窈窕 窈窕淑女 淑女   君子 君子好逑 好逑   ...
1    遵 彼 汝 坟   伐 其 条 枚   未 见 君子   惄 如 调 饥   遵 彼 汝 坟...
2    南山 崔 崔   雄 狐 绥 绥   鲁 道 有 荡   齐 子 由 归   既 曰 归 止...
3    芳 岁 肇 佳节   物华 当 仲春   乾坤 既 昭 泰   烟 景 含 氤氲      ...
4    竹 窗 松 户 有 佳期   美酒 酒香 香茶 慰 所思   辅 嗣 外生 生还 解 易  ...
Name: 内容, dtype: object

计算每一个词的 tfidf 值

from sklearn.feature_extraction.text import TfidfVectorizer
documents = content_s
tfidf_model = TfidfVectorizer(token_pattern=r'(?u)\b\w+\b', stop_words=stop_words).fit(documents)
tfidf_mat = tfidf_model.transform(documents)
tfidf_mat
<72417x81052 sparse matrix of type '<class 'numpy.float64'>'
	with 4077824 stored elements in Compressed Sparse Row format>
tfidf_mat[0].nonzero() # 不要问我这个方法是怎么找出来的,dir(),然后人肉搜索。。
(array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
 array([80677, 76265, 73843, 73014, 70526, 70525, 64226, 63791, 63332,
        57493, 57492, 52190, 48145, 47330, 46554, 45842, 41379, 33000,
        32999, 32458, 28844, 26860, 26859, 24332, 21150, 18702, 18697,
        16807, 16660, 16610, 11379, 11378,  3195]))
# [i for i in content_s[0].split() if i not in stop_words].__len__()
content_s[0].split()
['关关',
 '关关雎',
 '雎鸠',
 '在',
 '河之洲',
 '窈窕',
 '窈窕淑女',
 '淑女',
 '君子',
 '君子好逑',
 '好逑',
 '参差',
 '荇',
 '菜',
 '左右',
 '流',
 '之',
 '窈窕',
 '窈窕淑女',
 '淑女',
 '寤寐',
 '寤寐求之',
 '求之不得',
 '不得',
 '寤寐',
 '思',
 '服',
 '悠哉',
 '悠哉悠哉',
 '悠哉',
 '辗转',
 '辗转反侧',
 '反侧',
 '参差',
 '荇',
 '菜',
 '左右',
 '采',
 '之',
 '窈窕',
 '窈窕淑女',
 '淑女',
 '琴瑟',
 '友',
 '之',
 '参差',
 '荇',
 '菜',
 '左右',
 '芼',
 '之',
 '窈窕',
 '窈窕淑女',
 '淑女',
 '钟鼓',
 '鼓乐',
 '之']
tfidf_mat[0, 80677]
numpy.float64
tfidf_mat[72416, 47377]
0.1403098208087779

计算两首诗的文本相似度

在这里插入图片描述

df[df['_id'] == 10]
_id标题诗人诗人id朝代内容译文鉴赏背景古诗标签古诗star数
110汝坟佚名0先秦遵彼汝坟,伐其条枚。未见君子,惄如调饥。\n遵彼汝坟,伐其条肄。既见君子,不我遐弃。\n鲂鱼...译文\n沿着汝河大堤走,采伐山楸那枝条。还没见到我夫君,忧如忍饥在清早。\n沿着汝河大堤走,...鉴赏\n\n  这在诗之首章,“遵彼汝坟,伐其条枚”——在高高的汝河大堤上,有一位凄苦的妇女...影响\n\n  相传为孔子编辑成书,集入西周至春秋中叶五百多年的作品305篇,分为风雅颂三个...诗经,思念330
def cosine_similarity(id1, id2):
    '''根据两首古诗的id,计算出两首古诗的文本相似度'''
    # 从df中找到古诗id对应的在稀疏矩阵csr_matrix中的行索引
    # 会有缺失数据,处理一下
    try:
        index1 = df[df['_id'] == id1].index[0]
        index2 = df[df['_id'] == id2].index[0]
    except IndexError:
        return 0
    vector1 = tfidf_mat[index1].nonzero()[1]
    vector2 = tfidf_mat[index2].nonzero()[1]
    sum1, sum2, sum3 = 0, 0, 0
#     list1 = [i for i in ]
    for i in vector1:
        sum1 += tfidf_mat[index1, i]**2
        
    for j in vector2:
        sum2 += tfidf_mat[index2, j]**2
    
    for i in vector1:
        for j in vector2:
            if i == j:
                sum3 += tfidf_mat[index1, i]*tfidf_mat[index2, j]

#     print(locals())
    # 防止除 0,分母 +1
    return sum3/(np.sqrt(sum1*sum2)+1)
cosine_similarity(1, 2)
0.002923082839826352
'''
38204,小松,杜荀鹤,291,唐代
"咏物,讽喻,励志,哲理"
'''
from tqdm import tqdm

memory_list = []

for i in tqdm(range(1, 72417)):
    if i == 38204:
        continue
    sim = cosine_similarity(38204, i)
    memory_list.append((i, sim))

sorted(memory_list, key=lambda x:x[1],reverse=True)[:30]
100%|███████████████████████████████████████████████████████████████████████████| 72416/72416 [03:38<00:00, 331.48it/s]





[(42874, 0.08509635072406553),
 (25639, 0.07460172500593244),
 (19933, 0.07360265190423064),
 (13015, 0.07288387200145184),
 (12268, 0.06855823342195577),
 (24698, 0.06828669346676121),
 (11915, 0.06725844588564495),
 (15639, 0.06722002679024024),
 (8525, 0.06493546565747446),
 (962, 0.06334195607525453),
 (5838, 0.06316798198371498),
 (29091, 0.061948842869898796),
 (43175, 0.06068527155624073),
 (41581, 0.060285572253107704),
 (11809, 0.06022838400815675),
 (39570, 0.060142458480599424),
 (44562, 0.06001648813693223),
 (20642, 0.05925593090394182),
 (41664, 0.05881530250459235),
 (71968, 0.05772367696380888),
 (26726, 0.057529621355982885),
 (26888, 0.057529621355982885),
 (37002, 0.057056093152641256),
 (5246, 0.05700072408859219),
 (41484, 0.0568877395309903),
 (39116, 0.05678664339524122),
 (39023, 0.05669148933184754),
 (12621, 0.056382011763703686),
 (27120, 0.055758229911533785),
 (14859, 0.055241489261179846)]
df[df['_id'] == 38204]
_id标题诗人诗人id朝代内容译文鉴赏背景古诗标签古诗star数
3095738204小松杜荀鹤291唐代自小刺头深草里,而今渐觉出蓬蒿。 \n时人不识凌云木,直待凌云始道高。译文\n松树小的时候长在很深很深的草中,埋没看不出来,\n到现在才发现已经比那些野草(蓬蒿)...鉴赏\n\n  《小松》借松写人,托物讽喻,寓意深长。\n\n  松,树木中的英雄、勇士。数...NaN咏物,讽喻,励志,哲理388
df[df['_id'] == 25639]
_id标题诗人诗人id朝代内容译文鉴赏背景古诗标签古诗star数
1710325639玩手植松施肩吾773唐代却思毫末栽松处,青翠才将众草分。 \n今日散材遮不得,看看气色欲凌云。NaNNaNNaNNaN1
m_list = memory_list.copy()
m_list = sorted(m_list, key=lambda x:x[1],reverse=True)[:30]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值