使用NLP和TF-IDF查找最重要的句子

Pankaj PatelUnsplash拍摄的照片

我们将使用术语频率-逆文档频率(TF-IDF)来查找BBC新闻文章中最重要的句子。 然后,我们将将此算法实现为快速便捷的Fi​​refox扩展。

单击此处查看本文的更新版本:

w ^ e're要创建BBC新闻文章的摘要,并将其置于使用Firefox扩展的顶部。 本文是关于过时的术语频率倒文档频率(TF-IDF)算法。 我们将以Firefox扩展的形式创建实际用法。 我知道你在想什么 “ TF-IDF? 打哈欠😴”,但对我而言,这很有趣!

完成后,它将如下所示:

这里找到新闻文章。 红框突出显示最重要的句子。 红色框不在最终产品中,仅用于说明目的。

术语频率*反向凭证频率

不用担心,算法的名称也使我每次听到它大声说出来时就睡着了。 该算法是2个算法相乘而成。 让我们看看这两个如何工作:

词频

词频(TF)是单词在文档中出现的频率除以单词数。

术语t和文档d的术语频率(TF)。

假设您正在阅读有关英国退欧的新闻文章。 “ Brexit”一词会出现很多,因此“ Brexit”一词的使用频率很高。

通常,我们希望与该术语一起建立一个术语频率的字典(哈希图)。 类似于{word:该单词的词频} ,然后遍历该词典以找出哪个单词出现次数最多。

现在,如果我告诉您频率字典一词看起来像这样:

{"and": 0.87, "the": 0.73}

您会看到这些常见的英语单词对我们没有用。 当然,大多数英语文本中都包含这些单词,但是我们称这些单词为停用词 。 尽管没有一个单一的定义,但停用词通常是指一种语言中最常见的词。 您必须根据使用情况选择停用词。 您必须决定要使用的单词。 在处理某些文本之前,通常需要删除停用词以更好地处理文本。

其中带有大写字母的单词与没有大写字母的单词不同。 在编程中,“非洲”和“非洲”是两个不同的事物。 因此,我们希望将所有内容都转换为小写或大写形式,以更好地处理文本。 我们将把所有单词变成小写。

给定一个字符串,我们要删除停用词并将其变为小写。 我们的扩展名将为我们提供BBC新闻文章上所有文字的字符串。 不必担心我们从何处获取文本,这将在Firefox扩展部分稍后完成。 现在,假设我们的文本如下所示:

... These are external links and will open in a new windowA neat feature of many modern laptops is the ability to power them up through the USB port. Unlike the rectangular USB ports of old, the newer type - USB-C - can carry enough power to charge your 
machine.That’s great news: it means ...

缩短了上面的文字,以防止读者入睡。

此功能将“美化”我们的文档。 第3行是在StackOverflow上找到的停用词数组。 我添加了“ share ”和“ linkthese ”,因为这些是我们不希望的新闻文章中的常用词。

第5行是Regex 。 方括号表示或。 [,。]表示“以逗号或句号激活” 。 / g表示全局。 一旦找到一个',''。 不要停止,继续搜索字符串。 空字符串是我们要替换的字符串。 如果我们发现句号或逗号,则将其替换为任何内容-将其删除。 这是因为“非洲”一词。 如果没有,“非洲”和“非洲”将被分类为两个不同的词。

从我的Instagram @ Brandon.codes

第4行将文档拆分为单独的单词。 map函数将函数应用于数组中的每个元素。 将字符串分成单词数组后,我们将toLowerCase()方法应用于每个元素。 它使每个单词都小写。

从我的Instagram @ Brandon.codes 。 箭头是箭头函数 (Lambda /匿名函数)。

过滤掉停用词后,我们将返回小写字母。 Filter()仅使用内部函数为其返回True的元素创建一个新数组。
如果单词是停用词,则结果为True,这意味着我们将在文档中获得包含停用词的新数组。 我们使用否定运算符“!” 相反,这就是我们想要的。 返回单词列表,其中没有停用词。

现在我们要计算每个单词出现在文档中的次数。 这对于术语频率和反向文档频率都是有用的。 首先,我们要从一组单词中获取所有唯一的单词。

我们将数组转换为集合,因为集合没有重复。 这使我们仅获得数组中的唯一单词。 集合也没有顺序,因此我们不能使用数组索引访问元素。 我们需要将其直接变回数组。 有关集合论的更多信息,请查看我写的这篇文章

好的,现在是时候计算单词在单词数组中出现的次数了。

此函数遍历每个唯一单词,并计算该单词在单词数组中出现的次数。 术语频率函数很长,因此我将其分解。

第6行将文档分成句子。 有时句子前面有空格。 “布兰登。 小狗。” 在“狗”之前有空格。 我们对每个项目应用trim()方法来摆脱这些尾随的空格。

关于第7行,第一个单词的前146个字符是社交媒体链接。 该词的其余部分为标题或副标题。 在这里,看看:

Share this withEmailFacebookMessengerMessengerTwitterPinterestWhatsAppLinkedInCopy this linkThese are external links and will open in a new window Ryanair is tightening the rules on what passengers pay to take luggage onto the plane, in order to "speed up boarding". 

这很烦人,因为标题是故事的重要组成部分,需要加以考虑。 因此,我们删除第一个单词的前146个字符以得到:

Ryanair is tightening the rules on what passengers pay to take luggage onto the plane, in order to "speed up boarding"

还记得这个公式吗?

术语t和文档d的术语频率(TF)。

变量“ TFVals ”正在计算此公式。 如果我们运行“你好,我叫布兰登。 布兰登布兰登。 大象通过频率函数跳上月球,我们将得到如下所示的内容:

TF仅返回1个“ Brandon”,因此并非每个Brandon都有TF得分。 对于此示例,请记住,TF仅返回1布兰登,因为我们正在计算单数(单词)频率。

我们有单词频率这个词,但是我们想计算最重要的句子 ,而不是单词。 为此,我们遍历每个句子,然后查看该句子中出现在TFVals中的单词

还记得以前我怎么说我们不算所有3个“布兰登”吗? 我已经做到了。 另外,请注意,我们将其分为句子。 此图像中有3个句子。

我们只需要将它们全部加起来,然后除以我们有多少个单词即可。 由于我们仅累加不停词的TF值,因此,如果我们除以不停词的个数而不是一个句子中有多少个词,那是很公平的。 如果我们不除以有多少个单词,长句子比短句子有优势。

TF最高的句子是“ Brandon Brandon”。

这就是下面的第20行。 和上面一样,我们遍历每个句子并计算每个句子的TF值。

就是这样。 但是我们仅使用术语频率有一个问题。 正如您之前所看到的,在我们查看的所有3个句子中,“布兰登·布兰登”是得分最高的TF。

受欢迎程度还不够。 我们不希望句子中包含最多关键字,因为它们可能没有意义,或者它们可能是重复的。 例如在“布兰登”布兰登”一句中。 它具有较高的TF值,但内容不多。

它包含的信息不多,也没有用。 我们想要一个既罕见又独特并且包含文章中常见关键字的句子。 这是反向文档频率出现的地方。

反文档频率

术语频率是单词的常见程度,逆文档频率(IDF)是单词的独特性或稀有性。 IDF的公式是:

t是项,d是文档。 我们有多个文档,我们将每个句子视为自己的文档。

IDF用于许多文档,而TF是为一个文档构建的。 您可以决定什么是文档。 在本文中,每个句子都是其自己的文档。

IDF的前几个步骤与TF相同。 我们对文档进行美化,对文档中的单词进行计数并获得所有唯一的单词。

第1至6行并不新鲜。 第17行的for循环遍历文档中的每个句子。 由于每个句子都是新的“文档”,因此我们需要分别计算每个句子的单词数。 我们必须美化它们以消除停用词,并将其变成单词数组。 我们将每个新句子的wordcount对象推送到wordCountSentences中

这里有3个句子。 我们不在乎Brandon在整个文档中出现多少次。 我尝试挑选单词来给您一些有趣的东西,而又不会使数学过大,但是在此过程中我发展出自恋的感觉。

现在,我们将遍历每个单词,计算每个单词中该单词出现的次数,并使用以下公式计算IDF得分。

我在这里使用日志10。 注意:所有对数均会不断缩放 ,因此使用什么对数并不重要。
一个有关如何使用IDF的小例子。

现在,我们只对每个不停的单词执行此操作。

的代码是:

现在我们要获取所有句子的IDF值,我们在这里使用TF中的相同代码,但是替换一些东西以使其起作用。

如果我对您如实,我做了一个简单的“查找并替换”变量。 我没有在评论中使用“ TF”,而是将其替换为IDF。 相反,“TFVals”中,我用“IDFVals”取而代之。 这里没有发生任何重要的事情,因此请随时跳过此部分。

现在我们已经编写了代码来计算句子的IDF值; 我们已经完成了较早的公式。 “是狗”具有最高IDF值。

现在我们知道一个句子的独特性或罕见性。 这并不是很有用,因为我们也希望句子包含丰富的信息。 我们想要某种方式将TF的普及与IDF的独特性相结合。 这将引导我们进入下一部分……

重新访问了TF-IDF

“我们完成了吗? 我现在可以醒吗?” 是的,差不多完成了! 来自Giphy的 Gif。

现在,我们实现了TF和IDF功能。 剩下要做的唯一一件事就是将它们相乘。

对象TF和IDF都源自同一数据,因此TF不会包含IDF中没有的内容。 因此,我们可以遍历一个对象并使用相同的键。 我们将TFVals中的值乘以IDFVals中的值。

下一步是计算TF-IDF对象中最重要的3个句子。 使用几个if语句在对象的[key,value]上进行迭代。

您会在底部看到我们返回格式化的字符串。 我们对它进行格式化,以便在将其插入网页时看起来不错。 每个<br>都是一个换行符,即文本中的空格。 黑点是项目符号点。 现在,我们将在Firefox扩展中实现此算法。 🔥🦊

在BBC新闻文章中获取和更改文字

转到任何BBC新闻文章,右键单击并按“检查元素”。 您将在屏幕底部看到一个漂亮的框。 使用左上角的元素选择器工具,将鼠标悬停在文章上方。 我们可以看到整篇文章都包含在“ story-body”的CSS类中。

如果进一步,我们可以看到文章中的所有实际文本都被该CSS类内的段落标记所包围。

我们将使用JQuery选择文本。

该行选择了Story-body类中的所有<p>标签。 现在我们要获取文本,我们可以通过应用.text()方法来实现。

我们想要将文本添加到文章的顶部。 JQuery有一个称为prepend的方法,它使我们可以将数据添加到对象的顶部。

我们完成了! 现在,我们可以识别BBC新闻文章中最重要的句子,并将其显示在顶部。 只是时间把它变成一个扩展。

Firefox扩展基础

Firefox扩展有2个主要部分。 您编写的Javascript和manifest.json文件(该文件告诉Mozilla您的扩展程序做什么)。 我们现在要遍历manifest.json

manifest_version告诉Firefox您正在使用的清单版本。 名称告诉Firefox您的扩展名是什么。 版本告诉Firefox您的扩展名是什么版本号。 这三个是强制性的。

description告诉Firefox您的扩展程序做什么。

content_scripts告诉Firefox当URL与您输入的内容匹配时要加载哪些脚本。 为了使您指定的脚本运行,当前URL必须至少与您指定的URL之一匹配。 您可以在此处使用2个特殊字符:

  1. * ”匹配零个或多个字符。 在这种情况下,我不知道用户将加载HTTP还是HTTPS,所以我要一步一步地加载两者。 我也不知道用户会看什么确切的文章,因此我将其设置为可在任何文章上激活。

2.“ ”正好匹配一个字符。

Mozilla开发人员网络对此有很好的解释:

例如: "*na?i"将匹配"illuminati""annunaki" ,但不匹配"sagnarelli"

由于我们将使用jQuery,因此在执行脚本之前,还将jQuery JS文件也导入网站。 您可以从此处获取jQuery文件。 复制并粘贴到名为“ jquery.js”的文件中。

在Firefox URL中输入“ about:debugging ”以加载此页面:

在这里,单击“加载临时附件……” ,然后单击扩展名中的任何文件。 完成后,您应该看到以下内容:

Mozilla的对Firefox扩展的基础知识一个很好的文章, 在这里

现在加载任何BBC新闻文章来玩!

结论

您现在已经看到了TF-IDF的强大功能以及它的实际应用程序。 我想到这个主意是因为我有电子邮件焦虑症。 我对阅读电子邮件感到非常紧张,以至于我希望对它们进行快速总结以平息我的想法。 las,这是我第一次编写Javascript。 我从BBC新闻文章开始比较容易。

如果您愿意,可以通过以下几种方法来改进此代码:

  • 动态选择摘要中需要多少个句子。 您可以在整篇文章中找到平均TF * IDF值,并且可以在摘要中找到超过X的任何值。 这使得较长的文章与较短的文章一样被对待。
  • 将此扩展到您想要的任何其他网站上。

GitHub仓库在这里

你喜欢这篇文章吗? 在社交媒体上与我联系,讨论与计算机科学相关的所有事物😁

推特 | Instagram的 | 领英

我写这篇文章没有得到报酬。 如果您想支持我或喜欢这篇文章,请随时给我买一杯茶或below以下的东西。

From: https://hackernoon.com/finding-the-most-important-sentences-using-nlp-tf-idf-3065028897a3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值