查找文件中 n 个最常见的单词

查找文件中 n 个最常见的单词

我想在文本文件中查找 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 等程序,将(单词、numberOfOccurences)存储在字典中并对值进行排序,或者我可以使用 MapReduce,但我会针对击键进行优化。

是否存在误报?有没有更好的办法?

答案1

这几乎是查找“N 个最常见的事物”的最常见方法,除了您缺少 a sort,并且您有一个免费的cat

tr -c '[:alnum:]' '[\n*]' < test.txt | sort | uniq -ci | sort -nr | head  -10

sort如果你不在 the之前添加 a ,uniq -ci 你可能会得到很多错误的单例单词。 uniq只有独特的线条,而不是整体的独特性。

您可能想使用一个技巧,“停止词”。如果您正在查看英语文本(抱歉,这里是单语北美语),像“of”、“and”、“the”这样的词几乎总是占据前两到三个位置。您可能想消除它们。 GNU Groff 发行版有一个名为eign其中的文件,其中包含相当不错的停用词列表。我的 Arch 发行版有/usr/share/groff/current/eign,但我想我也见过/usr/share/dict/eign/usr/dict/eign在旧的 Unix 中。

您可以像这样使用停用词:

tr -c '[:alnum:]' '[\n*]' < test.txt |
fgrep -v -w -f -i /usr/share/groff/current/eign |
sort | uniq -ci | sort -nr | head  -10

我的猜测是,大多数人类语言需要从有意义的词频计数中删除类似的“停用词”,但我不知道在哪里建议获取其他语言的停用词列表。

-won 标志启用fgrep全字匹配。这可以避免仅包含短暂停止词的单词(例如“a”或“i”)出现误报。该-i标志打开uniqfgrep在比较单词时忽略大小写。

答案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 病态 Ruby

答案4

让我们使用哈斯克尔吧!

这正在变成一场语言战争,不是吗?

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

相关内容