たとえば、テキスト ファイル内で最も一般的な 10 個の単語を見つけたいとします。まず、ソリューションはキーストローク (つまり、私の時間) に合わせて最適化する必要があります。次に、パフォーマンスに合わせて最適化する必要があります。これまでにトップ 10 を取得するために行ったことは次のとおりです。
cat test.txt | tr -c '[:alnum:]' '[\n*]' | uniq -c | sort -nr | head -10
6 k
2 g
2 e
2 a
1 r
1 k22
1 k
1 f
1 eeeeeeeeeeeeeeeeeeeee
1 d
Java、Python などのプログラムを作成して (単語、出現回数) を辞書に保存し、値を並べ替えることも、MapReduce を使用することもできますが、キーストロークを最適化します。
誤検知はありますか? もっと良い方法はあるでしょうか?
答え1
これは、「N 個の最も一般的なもの」を見つける最も一般的な方法ですが、 が欠落しておりsort
、不必要な が生成されますcat
。
tr -c '[:alnum:]' '[\n*]' < test.txt | sort | uniq -ci | sort -nr | head -10
sort
の前に を入れないと、uniq -ci
おそらく誤った単一単語が多数生成されます。 は、 uniq
行の連続のみが一意であり、全体的な一意性は保証されません。
「ストップワード」というトリックを使うといいかもしれません。英語のテキスト (申し訳ありませんが、ここでは北米の単一言語です) を見ている場合、「of」、「and」、「the」などの単語がほぼ常に上位 2 位または 3 位を占めます。おそらく、これらを削除したほうがよいでしょう。GNU Groff ディストリビューションeign
には、ストップワードのかなり適切なリストを含む という名前のファイルがあります。私の Arch ディストリビューションには がありますが、古い Unix ではまたは/usr/share/groff/current/eign
も見られたと思います。/usr/share/dict/eign
/usr/dict/eign
ストップワードは次のように使用できます。
tr -c '[:alnum:]' '[\n*]' < test.txt |
fgrep -v -w -f -i /usr/share/groff/current/eign |
sort | uniq -ci | sort -nr | head -10
私の推測では、ほとんどの人間の言語では、意味のある単語の頻度カウントから同様の「ストップワード」を削除する必要があると思いますが、他の言語のストップワード リストをどこで入手できるかはわかりません。
フラグを-w
オンにするとfgrep
、単語全体の一致が有効になります。これにより、「a」や「i」などの短い終止符だけを含む単語の誤検出を回避できます。フラグをオンにすると、単語の比較時に大文字と小文字が無視され-i
ますuniq
。fgrep
答え2
これは utf-8 でより適切に動作します:
$ sed -e 's/\s/\n/g' < test.txt | sort | uniq -c | sort -nr | head -10
答え3
AWKを使ってみましょう!
この関数は、指定されたファイル内で出現する各単語の頻度を降順でリストします。
function wordfrequency() {
awk '
BEGIN { FS="[^a-zA-Z]+" } {
for (i=1; i<=NF; i++) {
word = tolower($i)
words[word]++
}
}
END {
for (w in words)
printf("%3d %s\n", words[w], w)
} ' | sort -rn
}
次のようにファイル上で呼び出すことができます:
$ cat your_file.txt | wordfrequency
上位10単語は次のとおりです。
$ cat your_file.txt | wordfrequency | head -10
ソース:AWK ワード ルビー
答え4
Haskellを使ってみましょう!
これは言語戦争になりつつあるのではないですか?
import Data.List
import Data.Ord
main = interact $ (=<<) (\x -> show (length x) ++ " - " ++ head x ++ "\n")
. sortBy (flip $ comparing length)
. group . sort
. words
使用法:
cat input | wordfreq
あるいは:
cat input | wordfreq | head -10