如何从句子向量中删除停用词?

时间:2019-05-10 18:40:50

标签: c++ text

我正在处理一些要求从句子中删除停用词的代码。我当前的解决方案不起作用。

我有两个测试句子的向量:
std::vector<std::string> sentences = {"this is a test", "another a test"};

我有一组包含停用词的无序字符串:
 std::unordered_set<std::string> stopwords;

现在,我尝试遍历向量中的句子,检查每个单词并将其与停用词进行比较,如果是停用词,则应将其删除。

    sentences.erase(std::remove_if(sentences.begin(), sentences.end(),
        [](const std::string &s){return stopwords.find(s) != stopwords.end();}),
        sentences.end());

这个想法是,我的向量-在删除停用词之后-包含不包含停用词的句子,但是现在,我又得到了完全相同的句子。知道为什么吗?

我的无序集合充满了以下功能:

void load() {
    std::ifstream file;
    file.open ("stopwords.txt");
    if(!file.is_open()) {return;}
    std::string stopword;
        while (file >> stopword) {
            stopwords.insert(stopword);
        }
}

1 个答案:

答案 0 :(得分:0)

您当前的代码无效,因为您没有从每个字符串中删除单词。您的INT(5)调用将使用整个字符串,并尝试将集合中的单词与整个字符串匹配。

首先,您应该编写一个简单的函数,当给定erase/remove_if和要删除的单词映射时,返回包含已删除单词的字符串。

这是一个使用std::string的小功能,可以做到这一点:

std::istringstream

输出:

#include <unordered_set>
#include <sstream>
#include <string>
#include <iostream>

std::string remove_stop_words(const std::string& src, const std::unordered_set<std::string>& stops)
{
   std::string retval;
   std::istringstream strm(src);
   std::string word;
   while (strm >> word)
   {
     if ( !stops.count(word) )
        retval += word + " ";
   }
   if ( !retval.empty())
      retval.pop_back();
   return retval;
}

int main()
{
  std::string test = "this is a test";
  std::unordered_set<std::string> stops = {"is", "test"};
  std::cout << "Changed word:\n" << remove_stop_words(test, stops) << "\n";
}

因此,一旦您可以正常使用此功能, Changed word: this a 版本就是在向量中的每个项目之间循环并调用std::vector函数:

remove_stop_words

输出:

int main()
{
  std::vector<std::string> test = {"this is a test", "another a test"};
  std::unordered_set<std::string> stops = {"is", "test"};
  for (size_t i = 0; i < test.size(); ++i)
      test[i] = remove_stop_words(test[i], stops); 
  std::cout << "Changed words:\n";
  for ( auto& s : test )
    std::cout << s << "\n";
}

请注意,在上面的示例中,您可以利用Changed words: this a another a 函数来删除手卷循环:

std::transform