![](https://i-blog.csdnimg.cn/blog_migrate/7807a5ad25201e47859b6f0bf7c6d85c.png)
我们将使用术语频率-逆文档频率(TF-IDF)来查找BBC新闻文章中最重要的句子。 然后,我们将将此算法实现为快速便捷的Firefox扩展。
单击此处查看本文的更新版本:
w ^ e're要创建BBC新闻文章的摘要,并将其置于使用Firefox扩展的顶部。 本文是关于过时的术语频率倒文档频率(TF-IDF)算法。 我们将以Firefox扩展的形式创建实际用法。 我知道你在想什么 “ TF-IDF? 打哈欠😴”,但对我而言,这很有趣!
完成后,它将如下所示:
![](https://i-blog.csdnimg.cn/blog_migrate/018b1399ce3e563e0e6b28bd4853ea36.png)
术语频率*反向凭证频率
不用担心,算法的名称也使我每次听到它大声说出来时就睡着了。 该算法是2个算法相乘而成。 让我们看看这两个如何工作:
词频
词频(TF)是单词在文档中出现的频率除以单词数。
![](https://i-blog.csdnimg.cn/blog_migrate/e1e7c6cb8deb0372a5e722c09089f2c8.png)
假设您正在阅读有关英国退欧的新闻文章。 “ 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表示全局。 一旦找到一个','或'。 不要停止,继续搜索字符串。 空字符串是我们要替换的字符串。 如果我们发现句号或逗号,则将其替换为任何内容-将其删除。 这是因为“非洲”一词。 如果没有,“非洲”和“非洲”将被分类为两个不同的词。
![](https://i-blog.csdnimg.cn/blog_migrate/8ed16a75be887b62678c81282752da0a.png)
第4行将文档拆分为单独的单词。 map函数将函数应用于数组中的每个元素。 将字符串分成单词数组后,我们将toLowerCase()方法应用于每个元素。 它使每个单词都小写。
![](https://i-blog.csdnimg.cn/blog_migrate/bb600ace7dc2ada7320f6d80a6eb16c9.png)
过滤掉停用词后,我们将返回小写字母。 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"
还记得这个公式吗?
![](https://i-blog.csdnimg.cn/blog_migrate/e1e7c6cb8deb0372a5e722c09089f2c8.png)
变量“ TFVals ”正在计算此公式。 如果我们运行“你好,我叫布兰登。 布兰登布兰登。 大象通过频率函数跳上月球,我们将得到如下所示的内容:
![](https://i-blog.csdnimg.cn/blog_migrate/0c6daf70e1f6856d014dfd2e01e20ca1.png)
我们有单词频率这个词,但是我们想计算最重要的句子 ,而不是单词。 为此,我们遍历每个句子,然后查看该句子中出现在TFVals中的单词 。
![](https://i-blog.csdnimg.cn/blog_migrate/a97bed0e44bf813f3d06e28d9b6f7c36.png)
我们只需要将它们全部加起来,然后除以我们有多少个单词即可。 由于我们仅累加不停词的TF值,因此,如果我们除以不停词的个数而不是一个句子中有多少个词,那是很公平的。 如果我们不除以有多少个单词,长句子比短句子有优势。
![](https://i-blog.csdnimg.cn/blog_migrate/3b70632b031033ea2f1380c6adba2acd.png)
这就是下面的第20行。 和上面一样,我们遍历每个句子并计算每个句子的TF值。
就是这样。 但是我们仅使用术语频率有一个问题。 正如您之前所看到的,在我们查看的所有3个句子中,“布兰登·布兰登”是得分最高的TF。
受欢迎程度还不够。 我们不希望句子中包含最多关键字,因为它们可能没有意义,或者它们可能是重复的。 例如在“布兰登”布兰登”一句中。 它具有较高的TF值,但内容不多。
它包含的信息不多,也没有用。 我们想要一个既罕见又独特并且包含文章中常见关键字的句子。 这是反向文档频率出现的地方。
反文档频率
术语频率是单词的常见程度,逆文档频率(IDF)是单词的独特性或稀有性。 IDF的公式是:
![](https://i-blog.csdnimg.cn/blog_migrate/913bfc5f9b3f2c1675fd2e3fb3f7c211.png)
IDF用于许多文档,而TF是为一个文档构建的。 您可以决定什么是文档。 在本文中,每个句子都是其自己的文档。
IDF的前几个步骤与TF相同。 我们对文档进行美化,对文档中的单词进行计数并获得所有唯一的单词。
第1至6行并不新鲜。 第17行的for循环遍历文档中的每个句子。 由于每个句子都是新的“文档”,因此我们需要分别计算每个句子的单词数。 我们必须美化它们以消除停用词,并将其变成单词数组。 我们将每个新句子的wordcount对象推送到wordCountSentences中 。
![](https://i-blog.csdnimg.cn/blog_migrate/c0a96608f72c71849e609ac094f8b38d.png)
现在,我们将遍历每个单词,计算每个单词中该单词出现的次数,并使用以下公式计算IDF得分。
![](https://i-blog.csdnimg.cn/blog_migrate/ae3586d86f47e2acee7260af567d99e9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b48b77c99c1a283527c3aa7da389303f.png)
现在,我们只对每个不停的单词执行此操作。
![](https://i-blog.csdnimg.cn/blog_migrate/92fb0b127d13c4a3e10f9be888bd9742.png)
的代码是:
现在我们要获取所有句子的IDF值,我们在这里使用TF中的相同代码,但是替换一些东西以使其起作用。
如果我对您如实,我做了一个简单的“查找并替换”变量。 我没有在评论中使用“ TF”,而是将其替换为IDF。 相反,“TFVals”中,我用“IDFVals”取而代之。 这里没有发生任何重要的事情,因此请随时跳过此部分。
![](https://i-blog.csdnimg.cn/blog_migrate/9dc06a3ace35a60187ae56436cd31025.png)
现在我们知道一个句子的独特性或罕见性。 这并不是很有用,因为我们也希望句子包含丰富的信息。 我们想要某种方式将TF的普及与IDF的独特性相结合。 这将引导我们进入下一部分……
重新访问了TF-IDF
![](https://i-blog.csdnimg.cn/blog_migrate/8bea81e0400dcb155eea05e3abda767f.gif)
现在,我们实现了TF和IDF功能。 剩下要做的唯一一件事就是将它们相乘。
对象TF和IDF都源自同一数据,因此TF不会包含IDF中没有的内容。 因此,我们可以遍历一个对象并使用相同的键。 我们将TFVals中的值乘以IDFVals中的值。
下一步是计算TF-IDF对象中最重要的3个句子。 使用几个if语句在对象的[key,value]上进行迭代。
您会在底部看到我们返回格式化的字符串。 我们对它进行格式化,以便在将其插入网页时看起来不错。 每个<br>都是一个换行符,即文本中的空格。 黑点是项目符号点。 现在,我们将在Firefox扩展中实现此算法。 🔥🦊
在BBC新闻文章中获取和更改文字
转到任何BBC新闻文章,右键单击并按“检查元素”。 您将在屏幕底部看到一个漂亮的框。 使用左上角的元素选择器工具,将鼠标悬停在文章上方。 我们可以看到整篇文章都包含在“ story-body”的CSS类中。
![](https://i-blog.csdnimg.cn/blog_migrate/f649e67c90b49f42c51c7dc249540956.png)
如果进一步,我们可以看到文章中的所有实际文本都被该CSS类内的段落标记所包围。
![](https://i-blog.csdnimg.cn/blog_migrate/c411b495f8f5e87ea96db1f078ba68d2.png)
我们将使用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个特殊字符:
- “ * ”匹配零个或多个字符。 在这种情况下,我不知道用户将加载HTTP还是HTTPS,所以我要一步一步地加载两者。 我也不知道用户会看什么确切的文章,因此我将其设置为可在任何文章上激活。
2.“ ? ”正好匹配一个字符。
Mozilla开发人员网络对此有很好的解释:
例如: "*na?i"
将匹配"illuminati"
和"annunaki"
,但不匹配"sagnarelli"
。
由于我们将使用jQuery,因此在执行脚本之前,还将jQuery JS文件也导入网站。 您可以从此处获取jQuery文件。 复制并粘贴到名为“ jquery.js”的文件中。
在Firefox URL中输入“ about:debugging ”以加载此页面:
![](https://i-blog.csdnimg.cn/blog_migrate/ead27829959e656258b5d54d45d8a93f.png)
在这里,单击“加载临时附件……” ,然后单击扩展名中的任何文件。 完成后,您应该看到以下内容:
![](https://i-blog.csdnimg.cn/blog_migrate/63660c6f0e696b2ccb5c86312c86ee93.png)
Mozilla的对Firefox扩展的基础知识一个很好的文章, 在这里 。
现在加载任何BBC新闻文章来玩!
结论
您现在已经看到了TF-IDF的强大功能以及它的实际应用程序。 我想到这个主意是因为我有电子邮件焦虑症。 我对阅读电子邮件感到非常紧张,以至于我希望对它们进行快速总结以平息我的想法。 las,这是我第一次编写Javascript。 我从BBC新闻文章开始比较容易。
如果您愿意,可以通过以下几种方法来改进此代码:
- 动态选择摘要中需要多少个句子。 您可以在整篇文章中找到平均TF * IDF值,并且可以在摘要中找到超过X的任何值。 这使得较长的文章与较短的文章一样被对待。
- 将此扩展到您想要的任何其他网站上。
GitHub仓库在这里 。
你喜欢这篇文章吗? 在社交媒体上与我联系,讨论与计算机科学相关的所有事物😁
推特 | Instagram的 | 领英
我写这篇文章没有得到报酬。 如果您想支持我或喜欢这篇文章,请随时给我买一杯茶或below以下的东西。
转到paypal.me/BrandonSkerritt并输入金额。 由于是PayPal,因此既简单又安全。 没有PayPal… www.paypal.me
From: https://hackernoon.com/finding-the-most-important-sentences-using-nlp-tf-idf-3065028897a3