2015-06-04 4 views
15

Ich versuche, die Punktzahl, die ein Beitrag erhält, basierend auf dem Text des Beitrags und andere Features (Tageszeit, Länge der Post, etc.)Kombinieren Tasche von Wörtern und anderen Funktionen in einem Modell mit Sklearn und Pandas

Ich frage mich, wie man diese verschiedenen Arten von Eigenschaften am besten in einem Modell kombiniert. Im Moment habe ich etwas wie folgt (gestohlen von here und here).

import pandas as pd 
... 

def features(p): 
    terms = vectorizer(p[0]) 
    d = {'feature_1': p[1], 'feature_2': p[2]} 
    for t in terms: 
     d[t] = d.get(t, 0) + 1 
    return d 

posts = pd.read_csv('path/to/csv') 

# Create vectorizer for function to use 
vectorizer = CountVectorizer(binary=True, ngram_range=(1, 2)).build_tokenizer() 
y = posts["score"].values.astype(np.float32) 
vect = DictVectorizer() 

# This is the part I want to fix 
temp = zip(list(posts.message), list(posts.feature_1), list(posts.feature_2)) 
tokenized = map(lambda x: features(x), temp) 
X = vect.fit_transform(tokenized) 

Es scheint sehr albern alle Funktionen zu extrahieren ich aus dem Pandas Datenrahmen wollen, nur um sie alle wieder zusammen sehen lassen. Gibt es einen besseren Weg, diesen Schritt zu tun?

Die CSV sieht ungefähr wie folgt aus:

ID,message,feature_1,feature_2 
1,'This is the text',4,7 
2,'This is more text',3,2 
... 
+0

Können Sie ein Beispiel Ihres csv zeigen? – elyase

+0

@elyase, ich habe gerade eine Spielzeugversion hinzugefügt. – Jeremy

Antwort

14

Sie alles tun können mit Ihrer Karte und Lambda:

tokenized=map(lambda msg, ft1, ft2: features([msg,ft1,ft2]), posts.message,posts.feature_1, posts.feature_2) 

Das spart Ihre Zwischentemperatur Schritt und iteriert durch die 3 Säulen zu tun. Eine andere Lösung wäre, die Nachrichten in ihre CountVectorizer Sparse-Matrix zu konvertieren und diese Matrix mit den Feature-Werten aus dem Posts-Datenrahmen zu verbinden (dies überspringt das Erstellen eines Diktats und erzeugt eine dünn besetzte Matrix, ähnlich wie bei DictVectorizer). :

import scipy as sp 
posts = pd.read_csv('post.csv') 

# Create vectorizer for function to use 
vectorizer = CountVectorizer(binary=True, ngram_range=(1, 2)) 
y = posts["score"].values.astype(np.float32) 

X = sp.sparse.hstack((vectorizer.fit_transform(posts.message),posts[['feature_1','feature_2']].values),format='csr') 
X_columns=vectorizer.get_feature_names()+posts[['feature_1','feature_2']].columns.tolist() 


posts 
Out[38]: 
    ID    message feature_1 feature_2 score 
0 1 'This is the text'   4   7  10 
1 2 'This is more text'   3   2  9 
2 3 'More random text'   3   2  9 

X_columns 
Out[39]: 
[u'is', 
u'is more', 
u'is the', 
u'more', 
u'more random', 
u'more text', 
u'random', 
u'random text', 
u'text', 
u'the', 
u'the text', 
u'this', 
u'this is', 
'feature_1', 
'feature_2'] 

X.toarray() 
Out[40]: 
array([[1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 4, 7], 
     [1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 3, 2], 
     [0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 3, 2]]) 

Zusätzlich sklearn-Pandas hat DataFrameMapper was tut, was für auch Sie suchen:

from sklearn_pandas import DataFrameMapper 
mapper = DataFrameMapper([ 
    (['feature_1', 'feature_2'], None), 
    ('message',CountVectorizer(binary=True, ngram_range=(1, 2))) 
]) 
X=mapper.fit_transform(posts) 

X 
Out[71]: 
array([[4, 7, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], 
     [3, 2, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1], 
     [3, 2, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0]]) 

Hinweis: X nicht spärlich ist, wenn diese letzte Methode.

X_columns=mapper.features[0][0]+mapper.features[1][1].get_feature_names() 

X_columns 
Out[76]: 
['feature_1', 
'feature_2', 
u'is', 
u'is more', 
u'is the', 
u'more', 
u'more random', 
u'more text', 
u'random', 
u'random text', 
u'text', 
u'the', 
u'the text', 
u'this', 
u'this is'] 
+0

danke @khammel Ich habe dies in einen Kern gesetzt https://gist.github.com/danemacaulay/c8e3194b63570de1cf88f431ade32107 –

Verwandte Themen