はい、いくつかの理由がありますが、あなたがそこでしていることは非常に遅いと思います。コーパスから数十億語の文字列を構築する前に、ストップワードの正規表現を処理する必要があると思います。
.regex ファイルが何であるかはわかりませんが、正当な Perl 正規表現が含まれていると推測します。
$stopword_string = `cat foo.regex`;
$stopword_rx = qr/$stopword_string/;
それはおそらく、最初に a があることを前提としてい(?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/;
警告
には非常に注意してください\b
。最初の単語の最初の文字と最後の単語の最後の文字が英数字 (\w
文字) である場合にのみ、上記のように動作すると考えられます。そうしないと、おそらく意味のない何かを主張することになります。その可能性がある場合は、より具体的にする必要があります。先頭\b
は になる必要が(?:(?<=\A)|(?<=\s))
あり、末尾\b
は になる必要があり(?=\s|\z)
ます。多くの人がそう思っ \b
ているようですが、実はそうではありません。
それを行ったら、コーパスを読み込んでいるときにストップワード正規表現をコーパスに適用する必要があります。これを行う最善の方法は、後で取り出す必要があるものを最初に文字列に入れないことです。 .
だから代わりに
$corpus_text = `cat some-giant-file`;
$corpus_text =~ s/$stopword_rx//g;
代わりに
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: $!";
これは、後で再び取り除かなければならないものをそこに入れるよりもはるかに高速です。
上記の私の使用cat
は単なるショートカットです。私はあなたが実際にプログラムを呼び出すとは思っていませんcat
。特に、処理も妨害もされていない単一のファイルを読み込むためだけです。☺</p>