¿Cómo calculo una matriz de co-ocurrencia palabra-palabra con sklearn?

Estoy buscando un módulo en sklearn que le permita derivar la matriz de co-ocurrencia palabra-palabra.

Puedo obtener la matriz del término del documento, pero no estoy seguro de cómo obtener una matriz palabra-palabra de co-ocurrencias.

Related of "¿Cómo calculo una matriz de co-ocurrencia palabra-palabra con sklearn?"

Aquí está mi ejemplo de solución utilizando CountVectorizer en scikit-learn. Y refiriéndose a esta publicación , simplemente puede usar la multiplicación de matrices para obtener una matriz de ocurrencia de palabra-palabra.

 from sklearn.feature_extraction.text import CountVectorizer docs = ['this this this book', 'this cat good', 'cat good shit'] count_model = CountVectorizer(ngram_range=(1,1)) # default unigram model X = count_model.fit_transform(docs) # X[X > 0] = 1 # run this line if you don't want extra within-text cooccurence (see below) Xc = (XT * X) # this is co-occurrence matrix in sparse csr format Xc.setdiag(0) # sometimes you want to fill same word cooccurence to 0 print(Xc.todense()) # print out matrix in dense format 

También puede referirse al diccionario de palabras en count_model ,

 count_model.vocabulary_ 

O, si desea normalizar por componente diagonal (se refirió a la respuesta en la publicación anterior).

 import scipy.sparse as sp Xc = (XT * X) g = sp.diags(1./Xc.diagonal()) Xc_norm = g * Xc # normalized co-occurence matrix 

Extra para anotar en la respuesta de @Federico Caccia, si no desea una coincidencia que sea falsa desde el propio texto, configure la aparición que sea mayor que 1 a 1, por ejemplo

 X[X > 0] = 1 # do this line first before computing cooccurrence Xc = (XT * X) ... 

Puede usar el parámetro ngram_range en el CountVectorizer o TfidfVectorizer

Ejemplo de código:

 bigram_vectorizer = CountVectorizer(ngram_range=(2, 2)) # by saying 2,2 you are telling you only want pairs of 2 words 

En caso de que quiera decir explícitamente qué co-ocurrencias de palabras quiere contar, use el vocabulary param, es decir: vocabulary = {'awesome unicorns':0, 'batman forever':1}

http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html

Código autoexplicativo y listo para usar con co-ocurrencias palabra-palabra predefinidas. En este caso, estamos rastreando las co-ocurrencias de awesome unicorns y batman forever :

 from sklearn.feature_extraction.text import CountVectorizer import numpy as np samples = ['awesome unicorns are awesome','batman forever and ever','I love batman forever'] bigram_vectorizer = CountVectorizer(ngram_range=(1, 2), vocabulary = {'awesome unicorns':0, 'batman forever':1}) co_occurrences = bigram_vectorizer.fit_transform(samples) print 'Printing sparse matrix:', co_occurrences print 'Printing dense matrix (cols are vocabulary keys 0-> "awesome unicorns", 1-> "batman forever")', co_occurrences.todense() sum_occ = np.sum(co_occurrences.todense(),axis=0) print 'Sum of word-word occurrences:', sum_occ print 'Pretty printig of co_occurrences count:', zip(bigram_vectorizer.get_feature_names(),np.array(sum_occ)[0].tolist()) 

La salida final es ('awesome unicorns', 1), ('batman forever', 2) , que corresponde exactamente a los datos proporcionados por nuestras samples .

@titipata Creo que su solución no es una buena métrica porque le estamos dando el mismo peso a las coincidencias reales y a las ocurrencias que son simplemente espurias. Por ejemplo, si tengo 5 textos y las palabras manzana y casa aparecen con esta frecuencia:

texto1: manzana : 10, “casa”: 1

texto2: manzana : 10, “casa”: 0

texto3: manzana : 10, “casa”: 0

texto4: manzana : 10, “casa”: 0

texto5: manzana : 10, “casa”: 0

La co-ocurrencia que vamos a medir es 10 * 1 + 10 * 0 + 10 * 0 + 10 * 0 + 10 * 0 = 10 , pero es espuria.

Y, en este otro caso importante, como los siguientes:

texto1: manzana : 1, “plátano”: 1

texto2: manzana : 1, “plátano”: 1

text3: manzana : 1, “banana”: 1

texto4: manzana : 1, “plátano”: 1

texto5: manzana : 1, “plátano”: 1

vamos a obtener solo una co-ocurrencia de 1 * 1 + 1 * 1 + 1 * 1 + 1 * 1 = 5 , cuando en realidad esa co-ocurrencia es realmente importante.

@Guiem Bosch En este caso, las co-ocurrencias se miden solo cuando las dos palabras son contiguas.

Propongo usar algo la solución @titipa para calcular la matriz:

 Xc = (YT * Y) # this is co-occurrence matrix in sparse csr format 

donde, en lugar de usar X, use una matriz Y con posiciones en posiciones mayores que 0 y ceros en otras posiciones.

Usando esto, en el primer ejemplo vamos a tener: co-ocurrencia : 1 * 1 + 1 * 0 + 1 * 0 + 1 * 0 + 1 * 0 = 1 y en el segundo ejemplo: co-ocurrencia : 1 * 1 + 1 * 1 + 1 * 1 + 1 * 1 + 1 * 0 = 5, que es lo que realmente estamos buscando.