草庐IT

中文标题相似度检测

zh-jp 2023-03-28 原文

前言

对中文标题使用余弦相似度算法编辑距离相似度分析进行相似度分析。

准备数据集part1

本次使用的数据集来源于前几年的硕士学位论文,可根据实际需要更换。结构如下所示:

学位论文题名
基于卷积神经网络的人脸识别研究
P2P流媒体视频点播系统设计和研究
校园网安全体系的设计与实现
无线传感器网络中基于多中继切换的CARQ方案性能分析
RFID和VLPR技术在酒钢智能门禁系统中的应用

...

基于MapReduce的Web链接结构分析算法研究
环形交叉口混合交通流元胞自动机模型研究
细菌觅食算法的优化及其在车间调度中的应用研究
基于多载体图像的通用隐写分析方法研究
基于加权网络的传染病免疫策略研究

文件名:data.csv

编码格式:UTF-8

import pandas as pd
data = pd.read_csv('data.csv')
data = data['学位论文题名']

准备数据集part2

分词是一种常用的文本预处理技术,它可以为后续的文本分析和处理提供便利。例如,对于文本分类任务,可以使用分词将文本转换为词的序列,然后训练分类器来对词的序列进行分类。

在进行分词时,通常会去掉一些无意义的词,称为停词。停词是指那些对文本分析没有太多意义的词,例如,冠词、连词、介词等。去除停词可以提高分词的准确性,并使文本分析的结果更加清晰明了。
停词文本集结构如下所示,停词库根据文件名在网上很容易找到:

$
0
1
2
3
4

...

顺
顺着
首先
!
,
:
;
?

文件名:cn_stopwords.txt

编码格式:UTF-8

with open('cn_stopwords.txt', 'r', encoding='utf-8') as f: 
    stop_words = [word.strip() for word in f.readlines()]
  • 执行分词和去停词
import jieba
res = []
for i in data:
    ii = i
    wordCut = list(jieba.cut(ii))
    for j in wordCut:
        if j in stop_words:
            wordCut.remove(j)
    res.append(wordCut)
  • 保存结果
import pickle
with open('word_cut.dat', mode='wb') as f:
    pickle.dump(res, f)

这里使用pickle保存,是因为如果使用pandas,保存的数据是带了双引号的(代表字符串),后续处理不便,因此采用序列化存储。

余弦相似度算法

余弦相似度算法是一种计算两个向量之间相似度的方法,常用于自然语言处理和推荐系统等领域。

余弦相似度算法的基本思想:计算两个向量的夹角余弦值,作为它们的相似度。两个向量的夹角余弦值越接近1,它们的相似度就越高;反之,如果两个向量的夹角余弦值接近0,它们的相似度就越低。

加载数据

with open('word_cut.dat', mode='rb') as f:
    dwc = pickle.load(f) # dwc 意为 Data of Word Cut

使用Word2Vec模型生成单词向量

在Word2Vec模型中,单词被表示为一个向量,并且这些向量是通过学习单词在上下文中的出现概率而生成的。skip-gram和CBOW是用于训练Word2Vec模型的两种不同的算法,它们都可以用来生成单词向量。

在使用Word2Vec模型进行自然语言处理任务时,可以使用余弦相似度算法来计算单词向量之间的相似度。例如,可以使用余弦相似度算法来寻找与给定单词最相似的其他单词,或者用来比较两个文本之间的相似度。

需要注意的是,Word2Vec模型和余弦相似度算法在不同的级别上操作。Word2Vec模型生成单词向量,而余弦相似度算法用于比较单词向量之间的相似度。因此,它们通常被结合使用来解决自然语言处理任务。

from gensim.models import Word2Vec
model = Word2Vec(dwc, sg=1, vector_size=100, window=5, min_count=1, negative=3, sample=0.001, hs=1,
                         workers=4)

Word2Vec模型有着众多参数,这里仅介绍用到的一部分,详情见官方文档

参数名 描述
sg {0, 1}, 可选 训练算法:1为skip-gram;否则为CBOW
vector_size int, 可选 单词向量的维数
windows int, 可选 句中当前单词和预测单词之间最大距离
min_count int, 可选 忽略总频率低于此值的所有单词
negative int, 可选 如果>0,将使用负采样,负的int指定应绘制多少个“噪声词”(通常在5-20之间)。如果设置为0,则不使用负采样
sample float, 可选 用于配置被随机采样的高频词,有效范围:(0,1e-5)
hs {0, 1}, 可选 如果为1,则分层softmax将用于模型训练。如果0,且负值为非零,则将使用负采样
workers int, 可选 使用这些工作线程来训练模型(相当于多核机器的更快训练)。

保存/加载训练结果

model.save('model.dat')             # 保存模型
model = Word2Vec.load('model.dat')  # 加载模型

计算相似度

limit = 0.99    # 相似度阈值
k = len(dwc)
st = [] # 意为Similar Title
for i in range(k):
    for j in range(i + 1, k):
        sim = model.wv.n_similarity(dwc[i], dwc[j])  # 计算两个标题间的相似度
        if sim > limit:     # 相似度高于阈值的加入结果
            temp = [dwc[i], dwc[j], sim]
            st.append(temp)
for i in st:
    print(i)

部分结果如下:

['卷积,神经网络,人脸识别,研究', '双目,测距,机器人,研究', 0.99172336]
['P2P,流媒体,视频点播,系统,设计,研究', '部队,数字化,营区,设计,实现', 0.9933342]
['P2P,流媒体,视频点播,系统,设计,研究', '属性,环,签密,NDN,敏感,信息,保护,方案', 0.99131924]
['P2P,流媒体,视频点播,系统,设计,研究', '社交,关系,流行病,传播,免疫,机制,研究', 0.9944775]
['P2P,流媒体,视频点播,系统,设计,研究', 'WSN,节能型,数据压缩,方法,研究', 0.99563485]

编辑距离相似度算法

算法介绍
编辑距离相似度算法是一种计算两个字符串之间相似度的方法,常用于自然语言处理和信息检索等领域。

编辑距离相似度算法的基本思想是,计算两个字符串之间的最小编辑次数,作为它们的相似度。两个字符串之间的最小编辑次数越少,它们的相似度就越高;反之,如果两个字符串之间的最小编辑次数越多,它们的相似度就越低。

import Levenshtein
limit2 = 5     # 相似度阈值
k = len(dwc)
st2 = dict()
for i in range(k):
    for j in range(i + 1, k):
        title1 = ''.join(dwc[i])
        title2 = ''.join(dwc[j])
        sim = Levenshtein.distance(title1, title2)
        if sim < limit2:    # 相似度低于阈值的加入结果
            key = title1 + ' ' + title2
            st2[key] = sim
sim_rk = sorted(st2.items(), key=lambda x: x[1])   # 根据相似度增序排序
for i in sim_rk:
    print(i)

结果如下:

('稀疏,表示,目标,跟踪,算法,研究 稀疏,表示,目标,跟踪,算法,研究', 0)
('稀疏,表示,目标,跟踪,算法,研究 稀疏,表示,目标,跟踪,方法,研究', 1)
('稀疏,表示,目标,跟踪,方法,研究 稀疏,表示,目标,跟踪,算法,研究', 1)
('自,适应,有限元,方法,三维,相场,模型模拟,研究 自,适应,有限元,方法,相场,模型模拟,研究', 3)
('多,特征,融合,粒子,滤波,跟踪,算法,研究 特征,适应,融合,粒子,滤波,跟踪,算法,研究', 4)
('模糊,软集,多,属性,决策,方法,研究 软集,理论,多,属性,决策,方法,研究', 4)

总结

在Python中,使用这两种算法能够简单实现文本分析。

有关中文标题相似度检测的更多相关文章

  1. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  2. ruby-on-rails - 使用 Rmagick 或 ImageMagick 在背景上放置标题 - 2

    我有一张背景图片,我想在其中添加一个文本框。我想弄清楚如何将标题放置在其顶部的正确位置。(我使用标题是因为我需要自动换行功能)。现在,我只能让文本显示在左上角,但我需要能够手动定位它的开始位置。require'RMagick'require'Pry'includeMagicktext="Loremipsumdolorsitamet"img=ImageList.new('template001.jpg')img 最佳答案 这是使用convert的ImageMagick命令行的答案。如果你想在Rmagick中使用这个方法,你必须自己移植

  3. 亚特兰蒂斯的回声(中文版): chatGPT 的杰作 - 2

    英文版英文链接关注公众号在“亚特兰蒂斯的回声”中踏上一段难忘的冒险之旅,深入未知的海洋深处。足智多谋的考古学家AriaSeaborne偶然发现了一件古代神器,揭示了一张通往失落之城亚特兰蒂斯的隐藏地图。在她神秘的导师内森·兰登教授的指导和勇敢的冒险家亚历克斯·默瑟的帮助下,阿丽亚开始了一段危险的旅程,以揭开这座传说中城市的真相。他们的冒险之旅带领他们穿越险恶的大海、神秘的岛屿和充满陷阱和谜语的致命迷宫。随着Aria潜在的魔法能力的觉醒,她被睿智勇敢的QueenNeria的幻象所指引,她让她为即将到来的挑战做好准备。三人组揭开亚特兰蒂斯令人惊叹的隐藏文明,并了解到邪恶的巫师马拉卡勋爵试图利用其古

  4. ruby-on-rails - 需要帮助最大化多个相似对象中的 3 个因素并适当排序 - 2

    我需要用任何语言编写一个算法,根据3个因素对数组进行排序。我以度假村为例(如Hipmunk)。假设我想去度假。我想要最便宜的地方、最好的评论和最多的景点。但是,显然我找不到在所有3个中都排名第一的方法。Example(assumingthereare20importantattractions):ResortA:$150/night...98/100infavorablereviews...18of20attractionsResortB:$99/night...85/100infavorablereviews...12of20attractionsResortC:$120/night

  5. ruby - 如何跳过 CSV 文件的第一行并将第二行作为标题 - 2

    有没有办法跳过CSV文件的第一行,让第二行作为标题?我有一个CSV文件,第一行是日期,第二行是标题,所以我需要能够在遍历它时跳过第一行。我尝试使用slice但它会将CSV转换为数组,我真的很想将其读取为CSV,以便我可以利用header。 最佳答案 根据您的数据,您可以使用另一种方法和skip_lines-option此示例跳过所有以#开头的行require'csv'CSV.parse(DATA.read,:col_sep=>';',:headers=>true,:skip_lines=>/^#/#Markcomments!)do|

  6. ruby - 检测由 RSpec、Ruby 运行的代码 - 2

    我想知道我的代码是否在rspec下运行。这可能吗?原因是我正在加载一些错误记录器,这些记录器在测试期间会被故意错误(expect{x}.toraise_error)弄得乱七八糟。我查看了我的ENV变量,没有(明显的)测试环境变量的迹象。 最佳答案 在spec_helper.rb的开头添加:ENV['RACK_ENV']='test'现在您可以在代码中检查RACK_ENV是否经过测试。 关于ruby-检测由RSpec、Ruby运行的代码,我们在StackOverflow上找到一个类似的问题

  7. ruby - 使用 Ruby Daemons gem 检测停止 - 2

    我正在使用rubydaemongem。想知道如何向停止操作添加一些额外的步骤?希望我能检测到停止被调用,并向其添加一些额外的代码。任何人都知道我如何才能做到这一点? 最佳答案 查看守护程序gem代码,它似乎没有用于此目的的明显扩展点。但是,我想知道(在守护进程中)您是否可以捕获守护进程在发生“停止”时发送的KILL/TERM信号...?trap("TERM")do#executeyourextracodehereend或者你可以安装一个at_exit钩子(Hook):-at_exitdo#executeyourextracodehe

  8. ruby - Ruby 脚本如何检测到它正在 irb 中运行? - 2

    我有一个定义类的Ruby脚本。我希望脚本执行语句BoolParser.generate:file_base=>'bool_parser'仅当脚本作为可执行文件被调用时,而不是当它被irbrequire(或通过-r在命令行上传递)时。我可以用什么来包装上面的语句,以防止它在我的Ruby文件加载时执行? 最佳答案 条件$0==__FILE__...!/usr/bin/ruby1.8classBoolParserdefself.generate(args)p['BoolParser.generate',args]endendif$0==_

  9. Ruby 无法检测字符串中的换行符 - 2

    我有以下字符串,我想检测那里的换行符。但是Ruby的字符串方法include?检测不到它。我正在运行Ruby1.9.2p290。我哪里出错了?"/'ædres/\nYour".include?('\n')=>false 最佳答案 \n需要在双引号内,否则无法转义。>>"\n".include?'\n'=>false>>"\n".include?"\n"=>true 关于Ruby无法检测字符串中的换行符,我们在StackOverflow上找到一个类似的问题: h

  10. 【自动驾驶环境感知项目】——基于Paddle3D的点云障碍物检测 - 2

    文章目录1.自动驾驶实战:基于Paddle3D的点云障碍物检测1.1环境信息1.2准备点云数据1.3安装Paddle3D1.4模型训练1.5模型评估1.6模型导出1.7模型部署效果附录show_lidar_pred_on_image.py1.自动驾驶实战:基于Paddle3D的点云障碍物检测项目地址——自动驾驶实战:基于Paddle3D的点云障碍物检测课程地址——自动驾驶感知系统揭秘1.1环境信息硬件信息CPU:2核AI加速卡:v100总显存:16GB总内存:16GB总硬盘:100GB环境配置Python:3.7.4框架信息框架版本:PaddlePaddle2.4.0(项目默认框架版本为2.3

随机推荐