2012-11-08 7 views
6

Ich benutze die Python sklearn Bibliotheken. Ich habe 150.000+ Sätze.Zählen mit scipy.sparse

Ich brauche ein array-ähnliches Objekt, wobei jede Zeile für einen Satz ist, jede Spalte einem Wort entspricht und jedes Element die Anzahl der Wörter in diesem Satz ist.

Zum Beispiel: Wenn die beiden Sätze waren „Der Hund lief“ und „Der Junge lief“, ich brauche

[ [1, 1, 1, 0] 
, [0, 1, 1, 1] ] 

(die Reihenfolge der Spalten ist irrelevant, und hängt davon ab, welche Spalte zugeordnet ist welches Wort)

Mein Array wird spärlich (jeder Satz wird einen Bruchteil der möglichen Wörter haben), und so verwende ich scipy.sparse.

def word_counts(texts, word_map): 
    w_counts = sp.???_matrix((len(texts),len(word_map))) 

    for n in range(0,len(texts)-1): 
     for word in re.findall(r"[\w']+", texts[n]): 
      index = word_map.get(word) 
      if index != None: 
       w_counts[n,index] += 1 
    return w_counts 

... 
nb = MultinomialNB() #from sklearn 
words = features.word_list(texts) 
nb.fit(features.word_counts(texts,words), classes) 

Ich möchte wissen, welche spärliche Matrix am besten wäre.

Ich versuchte coo_matrix mit bekam aber einen Fehler:

TypeError: 'coo_matrix' object has no attribute '__getitem__'

ich am documentation für COO aussehen, aber wurde sehr verwirrt durch die folgenden:

Sparse matrices can be used in arithmetic operations ...
Disadvantages of the COO format ... does not directly support: arithmetic operations

I dok_matrix verwendet wird, und dass gearbeitet, aber ich weiß nicht, ob dies in diesem Fall am besten funktioniert.

Vielen Dank im Voraus.

Antwort

6

Versuchen Sie entweder lil_matrix oder dok_matrix; diese sind leicht zu konstruieren und zu inspizieren (aber im Fall von lil_matrix, möglicherweise sehr langsam, da jede Einfügung lineare Zeit benötigt). Scikit-learn-Schätzer, die dünn besetzte Matrizen akzeptieren, akzeptieren jedes Format und konvertieren sie intern in ein effizientes Format (normalerweise csr_matrix). Sie können die Konvertierung auch selbst mit den Methoden tocoo, todok, tocsr usw. unter scipy.sparse Matrizen durchführen.

Oder verwenden Sie einfach die Klassen CountVectorizer oder DictVectorizer, die scikit-learn genau für diesen Zweck bereitstellt. CountVectorizer nimmt ganze Dokumente als Eingabe:

>>> from sklearn.feature_extraction.text import CountVectorizer 
>>> documents = ["The dog ran", "The boy ran"] 
>>> vectorizer = CountVectorizer(min_df=0) 
>>> vectorizer = CountVectorizer(min_df=0, stop_words=[]) 
>>> X = CountVectorizer.fit_transform(documents) 
>>> X = vectorizer.fit_transform(documents) 
>>> X.toarray() 
array([[0, 1, 1, 1], 
     [1, 0, 1, 1]]) 

... während DictVectorizer geht davon aus, Sie haben bereits getan tokenization und Zählen, mit dem Ergebnis, dass in einer dict pro Probe:

>>> from sklearn.feature_extraction import DictVectorizer 
>>> documents = [{"the":1, "boy":1, "ran":1}, {"the":1, "dog":1, "ran":1}] 
>>> X = vectorizer.fit_transform(documents) 
>>> X.toarray() 
array([[ 1., 0., 1., 1.], 
     [ 0., 1., 1., 1.]]) 
>>> vectorizer.inverse_transform(X[0]) 
[{'ran': 1.0, 'boy': 1.0, 'the': 1.0}] 

(Die min_df Argument zu CountVectorizer wurde vor ein paar Releases hinzugefügt.Wenn Sie eine alte Version verwenden, lassen Sie sie weg, oder besser, upgraden.)

EDIT Nach den FAQ, ich muss meine Zugehörigkeit offen zu legen, also hier geht: Ich bin der Autor von DictVectorizer und ich schrieb auch Teile von CountVectorizer.

+0

+1 ich wollte nur CountVectorizer vorschlagen –

+0

+1 für CountVectorizer –

+0

Akzeptierte Antwort, weil CountVectorizer die echte Antwort hier war. (Vielleicht DictVectorizer auch, aber ich habe es noch nicht ausprobiert.) –