如何从大文本文件中删除停用词?

Rad*_*adz 2 perl stop-words

我有一个十亿字的语料库,我用标量收集了它.我有一个.regex文件,其中包含我想从我的数据(文本)中消除的所有停用词.

我不知道如何使用这个.regex文件,所以我创建了一个数组并将.regex文件的所有停用词存储在我的停止字数组中.

要删除停用词我做这样的事情:

grep { $scalarText =~ s/\b\Q$_\E\b/ /g } @stopList;
Run Code Online (Sandbox Code Playgroud)

这需要很长时间才能执行.如何在Perl脚本中使用.regex文件来删除停用词?或者有没有更快的方法来删除停用词?

tch*_*ist 5

是的,我想你在那里做的事情非常缓慢,尽管有几个原因.我认为你需要在从语料库中构建十亿字的字符串之前处理你的停用词正则表达式.

我不知道.regex文件是什么,但我会假设它包含一个合法的Perl正则表达式,你可以使用不超过:

$stopword_string = `cat foo.regex`;
$stopword_rx     = qr/$stopword_string/;
Run Code Online (Sandbox Code Playgroud)

这可能假设(?x)在开始时有一个.

但是如果你的停用词文件是一个行列表,你需要做更多这样的事情:

chomp(@stopwords = `cat foo.regex`);

# if each stopword is an independent regex:
$stopword_string = join "|" => @stopwords;

# else if each stopword is a literal
$stopword_string = join "|" => map {quotemeta} @stopwords;

# now compile it (maybe add some qr//OPTS)
$stopword_rx     = qr/\b(?:$stopword_string)\b/;
Run Code Online (Sandbox Code Playgroud)

警告

非常小心\b:如果第一个单词中的第一个字符和最后一个单词中的最后一个字符是alphanumunder(一个\w字符),它只会按照你的想法去做.否则,它会断言你可能并不意味着什么.如果这可能是一种可能性,那么您需要更加具体.领导\b者需要成为(?:(?<=\A)|(?<=\s)),并且\b需要成为尾随(?=\s|\z).这是大多数人认为的 \b意思,但事实并非如此.

完成后,你应该在你读它时将停用词正则表达式应用于语料库.最好的方法是不要把这些东西放在你的字符串中,你只需要稍后取出.

所以不要这样做

$corpus_text = `cat some-giant-file`;
$corpus_text =~ s/$stopword_rx//g;
Run Code Online (Sandbox Code Playgroud)

相反

my $corpus_path = "/some/path/goes/here";
open(my $corpus_fh, "< :encoding(UTF-8)", $corpus_path)
    || die "$0: couldn't open $corpus_path: $!";

my $corpus_text = q##;

while (<$corpus_fh>) {
    chomp;  # or not
    $corpus_text .= $_ unless /$stopword_rx/;
}

close($corpus_fh)
    || die "$0: couldn't close $corpus_path: $!";
Run Code Online (Sandbox Code Playgroud)

这比把东西放在那里要快得多,你只需要稍后再清除.

我对cat上面的使用只是一个捷径.我不希望你实际上调用一个程序,最重要的cat是只读一个文件,未经处理和不受干扰.☺