利用Python过滤相似文本的简单方法示例


Posted in Python onFebruary 03, 2021

问题

假设你在存档中有成千上万的文档,其中许多是彼此重复的,即使文档的内容相同,标题不同。 现在想象一下,现在老板要求你通过删除不必要的重复文档来释放一些空间。

问题是:如何过滤标题足够相似的文本,以使内容可能相同? 接下来,如何实现此目标,以便在完成操作时不会删除过多的文档,而保留一组唯一的文档? 让我们用一些代码使它更清楚:

titles = [
 "End of Year Review 2020",
 "2020 End of Year",
 "January Sales Projections",
 "Accounts 2017-2018",
 "Jan Sales Predictions"
]

# Desired output
filtered_titles = [
 "End of Year Review 2020",
 "January Sales Projections",
 "Accounts 2017-2018",
]

根据以上的问题,本文适合那些希望快速而实用地概述如何解决这样的问题并广泛了解他们同时在做什么的人!

接下来,我将介绍我为解决这个问题所采取的不同步骤。下面是控制流的概要:

预处理所有标题文本

生成所有标题成对

测试所有对的相似性

如果一对文本未能通过相似性测试,则删除其中一个文本并创建一个新的文本列表

继续测试这个新的相似的文本列表,直到没有类似的文本留下

用Python表示,这可以很好地映射到递归函数上!

代码

下面是Python中实现此功能的两个函数。

import spacy
from itertools import combinations


# Set globals
nlp = spacy.load("en_core_web_md")

def pre_process(titles):
 """
 Pre-processes titles by removing stopwords and lemmatizing text.
 :param titles: list of strings, contains target titles,.
 :return: preprocessed_title_docs, list containing pre-processed titles.
 """

 # Preprocess all the titles
 title_docs = [nlp(x) for x in titles]
 preprocessed_title_docs = []
 lemmatized_tokens = []
 for title_doc in title_docs:
  for token in title_doc:
   if not token.is_stop:
    lemmatized_tokens.append(token.lemma_)
  preprocessed_title_docs.append(" ".join(lemmatized_tokens))
  del lemmatized_tokens[
   :
   ] # empty the lemmatized tokens list as the code moves onto a new title

 return preprocessed_title_docs

def similarity_filter(titles):
 """
 Recursively check if titles pass a similarity filter.
 :param titles: list of strings, contains titles.
 If the function finds titles that fail the similarity test, the above param will be the function output.
 :return: this method upon itself unless there are no similar titles; in that case the feed that was passed
 in is returned.
 """

 # Preprocess titles
 preprocessed_title_docs = pre_process(titles)

 # Remove similar titles
 all_summary_pairs = list(combinations(preprocessed_title_docs, 2))
 similar_titles = []
 for pair in all_summary_pairs:
  title1 = nlp(pair[0])
  title2 = nlp(pair[1])
  similarity = title1.similarity(title2)
  if similarity > 0.8:
   similar_titles.append(pair)

 titles_to_remove = []
 for a_title in similar_titles:
  # Get the index of the first title in the pair
  index_for_removal = preprocessed_title_docs.index(a_title[0])
  titles_to_remove.append(index_for_removal)

 # Get indices of similar titles and remove them
 similar_title_counts = set(titles_to_remove)
 similar_titles = [
  x[1] for x in enumerate(titles) if x[0] in similar_title_counts
 ]

 # Exit the recursion if there are no longer any similar titles
 if len(similar_title_counts) == 0:
  return titles

 # Continue the recursion if there are still titles to remove
 else:
  # Remove similar titles from the next input
  for title in similar_titles:
   idx = titles.index(title)
   titles.pop(idx)
   
  return similarity_filter(titles)

if __name__ == "__main__":
 your_title_list = ['title1', 'title2']
 similarty_filter(your_title_list)

第一个是预处理标题文本的简单函数;它删除像' the ', ' a ', ' and '这样的停止词,并只返回标题中单词的引理。

如果你在这个函数中输入“End of Year Review 2020”,你会得到“end year review 2020”作为输出;如果你输入“January Sales Projections”,你会得到“january sale projection”。

它主要使用了python中非常容易使用的spacy库.

第二个函数(第30行)为所有标题创建配对,然后确定它们是否通过了余弦相似度测试。如果它没有找到任何相似的标题,那么它将输出一个不相似标题的列表。但如果它确实找到了相似的标题,在删除没有通过相似度测试的配对后,它会将这些过滤后的标题再次发送给它自己,并检查是否还有相似的标题。

这就是为什么它是递归的!简单明了,这意味着函数将继续检查输出,以真正确保在返回“最终”输出之前没有类似的标题。

什么是余弦相似度?

但简而言之,这就是spacy在幕后做的事情……

首先,还记得那些预处理过的工作吗?首先,spacy把我们输入的单词变成了一个数字矩阵。

一旦它完成了,你就可以把这些数字变成向量,也就是说你可以把它们画在图上。

一旦你这样做了,计算两条直线夹角的余弦就能让你知道它们是否指向相同的方向。

利用Python过滤相似文本的简单方法示例

所以,在上图中,想象一下,A线代表“闪亮的橙色水果”,B线代表“闪亮的红苹果是一种水果”。

在这种情况下,行A和行B都对应于空格为这两个句子创建的数字矩阵。这两条线之间的角度——在上面的图表中由希腊字母theta表示——是非常有用的!你可以计算余弦来判断这两条线是否指向同一个方向。

这听起来似乎是显而易见的,难以计算,但关键是,这种方法为我们提供了一种自动化整个过程的方法。

总结

回顾一下,我已经解释了递归python函数如何使用余弦相似性和spacy自然语言处理库来接受相似文本的输入,然后返回彼此不太相似的文本。

可能有很多这样的用例……类似于我在本文开头提到的归档用例,你可以使用这种方法在数据集中过滤具有惟一歌词的歌曲,甚至过滤具有惟一内容类型的社交媒体帖子。

到此这篇关于利用Python过滤相似文本的简单方法的文章就介绍到这了,更多相关Python过滤相似文本内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
利用python程序生成word和PDF文档的方法
Feb 14 Python
一道python走迷宫算法题
Jan 22 Python
Python实现的将文件每一列写入列表功能示例【测试可用】
Mar 19 Python
unittest+coverage单元测试代码覆盖操作实例详解
Apr 04 Python
pandas DataFrame 根据多列的值做判断,生成新的列值实例
May 18 Python
Python运维自动化之nginx配置文件对比操作示例
Aug 29 Python
PyTorch搭建多项式回归模型(三)
May 22 Python
python中时间、日期、时间戳的转换的实现方法
Jul 06 Python
python实现修改固定模式的字符串内容操作示例
Dec 30 Python
利用Tensorflow的队列多线程读取数据方式
Feb 05 Python
Python实现钉钉/企业微信自动打卡的示例代码
Feb 02 Python
只用20行Python代码实现屏幕录制功能
Jun 02 Python
python time.strptime格式化实例详解
Feb 03 #Python
Python字符串的15个基本操作(小结)
Feb 03 #Python
python调用百度AI接口实现人流量统计
Feb 03 #Python
在python3.9下如何安装scrapy的方法
Feb 03 #Python
Pycharm创建python文件自动添加日期作者等信息(步骤详解)
Feb 03 #Python
python3.9和pycharm的安装教程并创建简单项目的步骤
Feb 03 #Python
Python实现区域填充的示例代码
Feb 03 #Python
You might like
要会喝咖啡也要会知道咖啡豆
2021/03/03 咖啡文化
mayfish 数据入库验证代码
2010/04/30 PHP
在VS2008中编译MYSQL5.1.48的方法
2010/07/03 PHP
PHP入门教程之面向对象的特性分析(继承,多态,接口,抽象类,抽象方法等)
2016/09/11 PHP
php修改数组键名的方法示例
2017/04/15 PHP
浅析PHP中的闭包和匿名函数
2017/12/25 PHP
Laravel 添加多语言提示信息的方法
2019/09/29 PHP
PHP中类与对象功能、用法实例解读
2020/03/27 PHP
Avengerls vs Newbee BO3 第二场2.18
2021/03/10 DOTA
跟随鼠标旋转的文字
2006/11/30 Javascript
『jQuery』名称冲突使用noConflict方法解决
2013/04/22 Javascript
Node.js 服务器端应用开发框架 -- Hapi.js
2014/07/29 Javascript
js文件包含的几种方式介绍
2014/09/28 Javascript
js实现模拟银行卡账号输入显示效果
2015/11/18 Javascript
原生js编写autoComplete插件
2016/04/13 Javascript
Windows 系统下设置Nodejs NPM全局路径
2016/04/26 NodeJs
解读ES6中class关键字
2017/11/20 Javascript
详解vuex之store拆分即多模块状态管理(modules)篇
2018/11/13 Javascript
vscode下的vue文件格式化问题
2018/11/28 Javascript
jQuery Raty星级评分插件使用方法实例分析
2019/11/25 jQuery
Nuxt v-bind绑定img src不显示的解决
2019/12/05 Javascript
vue导入.md文件的步骤(markdown转HTML)
2020/12/31 Vue.js
[01:31:03]DOTA2完美盛典全回顾 见证十五项大奖花落谁家
2017/11/28 DOTA
[01:20:05]DOTA2-DPC中国联赛 正赛 Ehome vs VG BO3 第二场 2月5日
2021/03/11 DOTA
Python编程之gui程序实现简单文件浏览器代码
2017/12/08 Python
Python实现可设置持续运行时间、线程数及时间间隔的多线程异步post请求功能
2018/01/11 Python
python求解数组中两个字符串的最小距离
2018/09/27 Python
Python Pillow Image Invert
2019/01/22 Python
python实现跨年表白神器--你值得拥有
2021/01/04 Python
详解Python模块化编程与装饰器
2021/01/16 Python
Expedia马来西亚旅游网站:廉价酒店,度假村和航班预订
2016/07/26 全球购物
家乐福巴西网上超市:Carrefour巴西
2016/10/31 全球购物
工地门卫岗位职责
2013/12/30 职场文书
政治思想表现评语
2014/05/04 职场文书
趵突泉导游词
2015/02/03 职场文书
Python3.10的一些新特性原理分析
2021/09/15 Python