¿Cómo encontrar el conjunto de pares de palabras que ocurren con mayor frecuencia en un archivo usando python?

Tengo un conjunto de datos de la siguiente manera:

"485","AlterNet","Statistics","Estimation","Narnia","Two and half men" "717","I like Sheen", "Narnia", "Statistics", "Estimation" "633","MachineLearning","AI","I like Cars, but I also like bikes" "717","I like Sheen","MachineLearning", "regression", "AI" "136","MachineLearning","AI","TopGear" 

y así

Quiero descubrir los pares de palabras más frecuentes, por ejemplo,

 (Statistics,Estimation:2) (Statistics,Narnia:2) (Narnia,Statistics) (MachineLearning,AI:3) 

Las dos palabras pueden estar en cualquier orden y a cualquier distancia entre sí.

¿Alguien puede sugerir una posible solución en python? Este es un conjunto de datos muy grande.

    Cualquier sugerencia es muy apreciada

    Así que esto es lo que intenté después de las sugerencias de @ 275365

    @ 275365 Intenté lo siguiente con la entrada de lectura de un archivo

      def collect_pairs(file): pair_counter = Counter() for line in open(file): unique_tokens = sorted(set(line)) combos = combinations(unique_tokens, 2) pair_counter += Counter(combos) print pair_counter file = ('myfileComb.txt') p=collect_pairs(file) 

    el archivo de texto tiene el mismo número de líneas que el original, pero solo tiene tokens únicos en una línea en particular. No sé qué estoy haciendo mal, ya que cuando lo ejecuto, divide las palabras en letras en lugar de dar salida como combinaciones de palabras. Cuando ejecuto este archivo, genera letras divididas en lugar de combinaciones de palabras como se esperaba. No sé dónde me estoy equivocando.

    Puede comenzar con algo como esto, dependiendo de qué tan grande es su cuerpo:

     >>> from itertools import combinations >>> from collections import Counter >>> def collect_pairs(lines): pair_counter = Counter() for line in lines: unique_tokens = sorted(set(line)) # exclude duplicates in same line and sort to ensure one word is always before other combos = combinations(unique_tokens, 2) pair_counter += Counter(combos) return pair_counter 

    El resultado:

     >>> t2 = [['485', 'AlterNet', 'Statistics', 'Estimation', 'Narnia', 'Two and half men'], ['717', 'I like Sheen', 'Narnia', 'Statistics', 'Estimation'], ['633', 'MachineLearning', 'AI', 'I like Cars, but I also like bikes'], ['717', 'I like Sheen', 'MachineLearning', 'regression', 'AI'], ['136', 'MachineLearning', 'AI', 'TopGear']] >>> pairs = collect_pairs(t2) >>> pairs.most_common(3) [(('MachineLearning', 'AI'), 3), (('717', 'I like Sheen'), 2), (('Statistics', 'Estimation'), 2)] 

    ¿Quieres números incluidos en estas combinaciones o no? Como no mencionó específicamente la exclusión de ellos, los he incluido aquí.

    EDITAR: Trabajar con un objeto de archivo

    La función que publicaste como tu primer bash anterior está muy cerca de funcionar. Lo único que debe hacer es cambiar cada línea (que es una cadena) en una tupla o lista. Suponiendo que sus datos se vean exactamente como los datos que publicó anteriormente (con comillas alrededor de cada término y comas que los separan), sugeriría una solución simple: puede usar ast.literal_eval . (De lo contrario, es posible que necesite usar una expresión regular de algún tipo). Vea a continuación una versión modificada con ast.literal_eval :

     from itertools import combinations from collections import Counter import ast def collect_pairs(file_name): pair_counter = Counter() for line in open(file_name): # these lines are each simply one long string; you need a list or tuple unique_tokens = sorted(set(ast.literal_eval(line))) # eval will convert each line into a tuple before converting the tuple to a set combos = combinations(unique_tokens, 2) pair_counter += Counter(combos) return pair_counter # return the actual Counter object 

    Ahora puedes probarlo así:

     file_name = 'myfileComb.txt' p = collect_pairs(file_name) print p.most_common(10) # for example 

    No hay mucho que puedas hacer, excepto contar todos los pares.

    Las optimizaciones obvias consisten en eliminar tempranamente las palabras y sinónimos duplicados, realizar la derivación (¡todo lo que reduce el número de tokens distintos es bueno!), Y solo contar pares (a,b) donde a (en su ejemplo, solo statistics,narnia conteo statistics,narnia , o narnia,statistics , pero no ambas!).

    Si te quedas sin memoria, realiza dos pases. En la primera pasada, use una o varias funciones hash para obtener un filtro candidato. En la segunda pasada, solo cuente las palabras que pasan este filtro (filtro de estilo MinHash / LSH).

    Es un problema paralelo ingenuo, por lo tanto, también es fácil de distribuir a múltiples subprocesos o computadoras.