Procesamiento de texto en Python: NLTK y pandas

Estoy buscando una manera efectiva de construir una Matriz de Documentos de Término en Python que pueda usarse junto con datos adicionales.

Tengo algunos datos de texto con algunos otros atributos. Me gustaría realizar algunos análisis sobre el texto y me gustaría poder correlacionar las características extraídas del texto (como tokens de palabras individuales o temas de LDA) con los otros atributos.

Mi plan fue cargar los datos como un dataframe de pandas y luego cada respuesta representará un documento. Desafortunadamente, me encontré con un problema:

import pandas as pd import nltk pd.options.display.max_colwidth = 10000 txt_data = pd.read_csv("data_file.csv",sep="|") txt = str(txt_data.comment) len(txt) Out[7]: 71581 txt = nltk.word_tokenize(txt) txt = nltk.Text(txt) txt.count("the") Out[10]: 45 txt_lines = [] f = open("txt_lines_only.txt") for line in f: txt_lines.append(line) txt = str(txt_lines) len(txt) Out[14]: 1668813 txt = nltk.word_tokenize(txt) txt = nltk.Text(txt) txt.count("the") Out[17]: 10086 

Tenga en cuenta que, en ambos casos, el texto se procesó de tal manera que solo el espacio, las letras y … ¡! Fue eliminado (por simplicidad).

Como puede ver, un campo de pandas convertido en una cadena devuelve menos coincidencias y la longitud de la cadena también es más corta.

¿Hay alguna manera de mejorar el código anterior?

Además, str(x) crea una cadena grande de los comentarios, mientras que [str(x) for x in txt_data.comment] crea un objeto de lista que no se puede dividir en una bolsa de palabras. ¿Cuál es la mejor manera de producir un objeto nltk.Text que retendrá índices de documentos? En otras palabras, estoy buscando una manera de crear una Matriz de Documentos de Término, el equivalente de R de TermDocumentMatrix() del paquete tm .

Muchas gracias.

El beneficio de usar un DataFrame pandas sería aplicar la funcionalidad nltk a cada row manera:

 word_file = "/usr/share/dict/words" words = open(word_file).read().splitlines()[10:50] random_word_list = [[' '.join(np.random.choice(words, size=1000, replace=True))] for i in range(50)] df = pd.DataFrame(random_word_list, columns=['text']) df.head() text 0 Aaru Aaronic abandonable abandonedly abaction ... 1 abampere abampere abacus aback abalone abactor... 2 abaisance abalienate abandonedly abaff abacina... 3 Ababdeh abalone abac abaiser abandonable abact... 4 abandonable abandon aba abaiser abaft Abama ab... len(df) 50 txt = df.text.apply(word_tokenize) txt.head() 0 [Aaru, Aaronic, abandonable, abandonedly, abac... 1 [abampere, abampere, abacus, aback, abalone, a... 2 [abaisance, abalienate, abandonedly, abaff, ab... 3 [Ababdeh, abalone, abac, abaiser, abandonable,... 4 [abandonable, abandon, aba, abaiser, abaft, Ab... txt.apply(len) 0 1000 1 1000 2 1000 3 1000 4 1000 .... 44 1000 45 1000 46 1000 47 1000 48 1000 49 1000 Name: text, dtype: int64 

Como resultado, obtienes el .count() para cada entrada de row :

 txt = txt.apply(lambda x: nltk.Text(x).count('abac')) txt.head() 0 27 1 24 2 17 3 25 4 32 

Luego puedes sumr el resultado usando:

 txt.sum() 1239