投稿のテキストとその他の機能(時刻、投稿の長さなど)の両方に基づいて、投稿が受け取るスコアをモデル化しようとしています。
これらのさまざまなタイプの機能を1つのモデルに最適に組み合わせる方法を考えています。今、私は次のようなものを持っています( ここ と ここ から盗まれました)。
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)
pandasデータフレームから必要なすべての機能を抽出して、それらをすべて一緒に圧縮するのは非常にばかげているようです。この手順を実行するためのより良い方法はありますか?
CSVは次のようになります。
ID,message,feature_1,feature_2
1,'This is the text',4,7
2,'This is more text',3,2
...
マップとラムダですべてを行うことができます:
tokenized=map(lambda msg, ft1, ft2: features([msg,ft1,ft2]), posts.message,posts.feature_1, posts.feature_2)
これにより、暫定的な一時ステップの実行が節約され、3つの列を反復処理します。
別の解決策は、メッセージをCountVectorizerスパース行列に変換し、この行列を投稿データフレームの特徴値と結合することです(これにより、dictを作成する必要がなくなり、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]])
さらに、sklearn-pandasにはDataFrameMapperがあり、これもあなたが探していることを実行します。
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]])
注:この最後の方法を使用する場合、Xはスパースではありません。
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']