【问题标题】:Most effective way to create a naive text summaring algorithm创建简单文本摘要算法的最有效方法
【发布时间】:2014-04-26 03:13:47
【问题描述】:

我正在构建一个简单的简单文本摘要算法。该算法的工作原理如下:

  • 我算法的第一步是删除所有停用词(stop words in English)。
  • 在我的文本仅包含具有实际含义的单词后,我将查看每个单词在文本中使用了多少次,以查找该单词的频率。例如,如果“超级计算机”这个词被使用了 5 次,它就会有 frequency = 5
  • 然后我将通过将sum of the frequencies of all words in the sentence 除以number of the words in the sentence 来计算每个句子的权重。
  • 在最后一步,我将按句子的长度对句子进行排序。

我需要用 C++ 编写这个算法(作为 V8 NodeJS 模块),但问题是在过去几年中,我主要使用 Javascript 等高级脚本语言工作,而我在这方面的经验并不丰富C++。在 javascript 中,我可以使用正则表达式删除所有停用词,然后找到频率,但在 C++ 中似乎要复杂得多。

我想出了以下想法:

struct words {
    string word;
    int freq;
}

std::vector<words> Words;
  • 停用词将被预加载到 V8 本地数组或 std::vector 中。
  • 对于文本中的每个单词,我将遍历所有停用词,如果当前单词不是停用词,则检查其是否在结构中,如果不是 -> 将新的 word 添加到Words vector,如果存在则将频率增加 1。
  • 找到所有单词的所有频率后,我将再次循环遍历文本以找到每个句子的权重。

有了这个想法,我想到了几个问题:

  1. 我的文本大多是 1000+ 字。对于每个循环超过 100 个停用词的单词,将进行 100000 次迭代以找出停用词。这似乎真的无效。
  2. 获得频率后,我需要在文本 1000 多个单词和 300 多个单词(在向量频率中)再循环一次,以计算每个句子的权重。

我的想法似乎无效,但我对 C++ 不是很熟悉。

所以我的问题是有没有更好的方法来做到这一点或优化我的算法,尤其是我上面列出的问题?

我担心我的算法的性能,任何提示/建议将不胜感激。

【问题讨论】:

  • 在蝙蝠的右边,你可以设置一个unordered_map 来保存停用词而不是std::vector,因此检查一个单词是否是停用词是O(1),而不是循环遍历 100 + 停用词,如您所说。
  • 您也可以将找到的单词存储在binary search tree 中,大部分时间为 O(log n)。
  • 或者同时使用unordered_map。每次你找到一个词,更新它的频率。这将花费O(n) 时间。计算句子的权重只需查找单词的频率,即O(1)unordered_mapO(n)vector
  • 感谢您的建议!我真的很感激他们。我还想问一下拆分单词的最佳方法是什么?我想到的是while ((pos = input.find(' ', pos)) != std::string::npos) {,而我保留了最后一场比赛的位置,然后是str.substr他们。有效吗?
  • @RSahu,这是一个很好的观点,但我认为它并不太宽泛,OP 只是在寻求优化他的检索和扫描的提示

标签: c++ performance algorithm parsing summarization


【解决方案1】:

对于停用词,请查看std::unordered_set。您可以将所有停用词字符串存储在std::unordered_set&lt;string&gt; 中,然后当您有要比较的字符串时,调用count(string) 以查看它是否存在。

对于单词/频率对,使用 std::unordered_map,就像在某些 cmets 中一样。如果您在单个地图查找中同时执行查找和插入,这将是最快的。试试这样的:

struct Frequency
{
    int val;
    Frequency() : val(0) {}
    void increment()
    {
        ++val;
    }
};

std::unordered_map<std::string, Frequency> words;

void processWord(const std::string str)
{
    words[str].increment();
}

words[str] 在地图中搜索单词,如果不存在则添加。新词将调用 Frequency 的构造函数,该构造函数初始化为零。所以你所要做的就是在每个字上都调用processWord

【讨论】:

    猜你喜欢
    • 2015-12-05
    • 2014-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 2021-11-07
    相关资源
    最近更新 更多