次のようにPandasにデータフレームがあるとします。
> my_dataframe
col1 col2
A foo
B bar
C something
A foo
A bar
B foo
ここで、行はインスタンスを表し、列の入力フィーチャ(ターゲットラベルは表示されませんが、これは分類タスク用です)、つまり、構築しようとしています[〜#〜] x [〜#〜 ]のうちmy_dataframe
。
これを効率的にベクトル化するにはどうすればよいですか。 DictVectorizer
?
最初にDataFrameのすべてのエントリを辞書に変換する必要がありますか? (それは上記のリンクの例で行われている方法です)。これを行うためのより効率的な方法はありますか?
まず、サンプル配列のどこに特徴があり、どこに観測があるかはわかりません。
第2に、DictVectorizer
はデータを保持せず、変換ユーティリティとメタデータストレージのみに関するものです。変換後、機能名とマッピングが保存されます。これは、さらなる計算に使用されるnumpy配列を返します。 Numpy配列(特徴行列)のサイズは_features count
_ x _number of observations
_に等しく、値は観測値の特徴値に等しい。したがって、観察と特徴がわかっている場合は、この配列を他の方法で作成できます。
Sklearnがそれを実行することを期待する場合は、転置されたデータフレームに_to_dict
_を適用して行うことができるため、dictを手動で再構築する必要はありません。
_>>> df
col1 col2
0 A foo
1 B bar
2 C foo
3 A bar
4 A foo
5 B bar
>>> df.T.to_dict().values()
[{'col2': 'foo', 'col1': 'A'}, {'col2': 'bar', 'col1': 'B'}, {'col2': 'foo', 'col1': 'C'}, {'col2': 'bar', 'col1': 'A'}, {'col2': 'foo', 'col1': 'A'}, {'col2': 'bar', 'col1': 'B'}]
_
Scikit-learn 0.13.0(2014年1月3日)以降、使用可能な to_dict()
メソッドの新しいパラメーター_'records'
_があるため、このメソッドを簡単に使用できます追加の操作なし:
_>>> df = pandas.DataFrame({'col1': ['A', 'B', 'C', 'A', 'A', 'B'], 'col2': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar']})
>>> df
col1 col2
0 A foo
1 B bar
2 C foo
3 A bar
4 A foo
5 B bar
>>> df.to_dict('records')
[{'col2': 'foo', 'col1': 'A'}, {'col2': 'bar', 'col1': 'B'}, {'col2': 'foo', 'col1': 'C'}, {'col2': 'bar', 'col1': 'A'}, {'col2': 'foo', 'col1': 'A'}, {'col2': 'bar', 'col1': 'B'}]
_
を見てみましょう sklearn-pandas
これは、まさにあなたが探しているものを提供します。対応するGithubリポジトリは here です。
間違いなくDictVectorizer
を使用できます。 DictVectorizer
はdict
に似たオブジェクトの反復可能オブジェクトを想定しているため、次のことを実行できます。
from sklearn.base import TransformerMixin
from sklearn.pipeline import make_pipeline
from sklearn.feature_extraction import DictVectorizer
class RowIterator(TransformerMixin):
""" Prepare dataframe for DictVectorizer """
def fit(self, X, y=None):
return self
def transform(self, X):
return (row for _, row in X.iterrows())
vectorizer = make_pipeline(RowIterator(), DictVectorizer())
# now you can use vectorizer as you might expect, e.g.
vectorizer.fit_transform(df)
pandasカテゴリ(または単に文字列)を含むDataFrameから設計行列を作成し、それを行う最も簡単な方法は、複製するライブラリ patsy を使用することです。 R式の機能を拡張します。
あなたの例を使用すると、変換は次のようになります。
import pandas as pd
import patsy
my_df = pd.DataFrame({'col1':['A', 'B', 'C', 'A', 'A', 'B'],
'col2':['foo', 'bar', 'something', 'foo', 'bar', 'foo']})
patsy.dmatrix('col1 + col2', data=my_df) # With added intercept
patsy.dmatrix('0 + col1 + col2', data=my_df) # Without added intercept
結果の設計行列は、いくつかの追加情報を含むNumPy配列であり、scikit-learnで直接使用できます。
インターセプトを追加した結果の例:
DesignMatrix with shape (6, 5)
Intercept col1[T.B] col1[T.C] col2[T.foo] col2[T.something]
1 0 0 1 0
1 1 0 0 0
1 0 1 0 1
1 0 0 1 0
1 0 0 0 0
1 1 0 1 0
Terms:
'Intercept' (column 0)
'col1' (columns 1:3)
'col2' (columns 3:5)
PatsyがA
とbar
の影響を切片に組み込むことで多重共線性を回避しようとしたことに注意してください。そうすれば、たとえば、col1[T.B]
予測子は、B
として分類される観測に関連するA
の追加効果として解釈されるべきです。