encontrar n palabras más frecuentes en un archivo

encontrar n palabras más frecuentes en un archivo

Quiero encontrar, digamos, las 10 palabras más comunes en un archivo de texto. En primer lugar, la solución debe optimizarse para las pulsaciones de teclas (en otras palabras, mi tiempo). En segundo lugar, por la actuación. Esto es lo que tengo hasta ahora para estar entre los 10 primeros:

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

Podría crear un programa java, python, etc. donde almaceno (palabra, número de ocurrencias) en un diccionario y ordene el valor o podría usar MapReduce, pero optimizo para las pulsaciones de teclas.

¿Hay algún falso positivo? ¿Existe una mejor manera?

Respuesta1

Esa es prácticamente la forma más común de encontrar "N cosas más comunes", excepto que te falta un sorty tienes un gratuito cat:

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

Si no coloca un sortantes, uniq -ci probablemente obtendrá muchas palabras únicas falsas. uniqsolo hace tiradas únicas de líneas, no unicidad general.

Quizás quieras utilizar un truco: "palabras vacías". Si estás mirando texto en inglés (lo siento, aquí es monolingüe norteamericano), palabras como "of", "and", "the" casi siempre ocupan los dos o tres primeros lugares. Probablemente quieras eliminarlos. La distribución GNU Groff tiene un archivo nombrado eignque contiene una lista bastante decente de palabras vacías. Mi distribución Arch tiene /usr/share/groff/current/eign, pero creo que también lo he visto /usr/share/dict/eignen /usr/dict/eignUnixes antiguos.

Puedes utilizar palabras vacías como esta:

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

Supongo que la mayoría de los idiomas humanos necesitan "palabras vacías" similares eliminadas de los recuentos de frecuencia de palabras significativas, pero no sé dónde sugerir que se obtengan listas de palabras vacías de otros idiomas.

La -wbandera activada fgreppermite la coincidencia de palabras completas. Esto evita falsos positivos en palabras que simplemente contienen palabras breves, como "a" o "i". La -ibandera está activada uniqe fgrepignora mayúsculas y minúsculas al comparar palabras.

Respuesta2

Esto funciona mejor con utf-8:

$ sed -e 's/\s/\n/g' < test.txt | sort | uniq -c | sort -nr | head  -10

Respuesta3

¡Usemos AWK!

Esta función enumera la frecuencia de cada palabra que aparece en el archivo proporcionado en orden descendente:

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
}

Puedes llamarlo en tu archivo de esta manera:

$ cat your_file.txt | wordfrequency

y para las 10 palabras principales:

$ cat your_file.txt | wordfrequency | head -10

Fuente:Ruby pupilo de AWK

Respuesta4

¡Usemos Haskell!

Esto se está convirtiendo en una guerra de idiomas, ¿no?

import Data.List
import Data.Ord

main = interact $ (=<<) (\x -> show (length x) ++ " - " ++ head x ++ "\n")
                . sortBy (flip $ comparing length)
                . group . sort
                . words

Uso:

cat input | wordfreq

Alternativamente:

cat input | wordfreq | head -10

información relacionada