web-dev-qa-db-ja.com

Scikit-LearnのPandasデータフレームのベクトル化

次のようにPandasにデータフレームがあるとします。

> my_dataframe

col1   col2
A      foo
B      bar
C      something
A      foo
A      bar
B      foo

ここで、行はインスタンスを表し、列の入力フィーチャ(ターゲットラベルは表示されませんが、これは分類タスク用です)、つまり、構築しようとしています[〜#〜] x [〜#〜 ]のうちmy_dataframe

これを効率的にベクトル化するにはどうすればよいですか。 DictVectorizer

最初にDataFrameのすべてのエントリを辞書に変換する必要がありますか? (それは上記のリンクの例で行われている方法です)。これを行うためのより効率的な方法はありますか?

17

まず、サンプル配列のどこに特徴があり、どこに観測があるかはわかりません。

第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'}]
_
21
alko

を見てみましょう sklearn-pandasこれは、まさにあなたが探しているものを提供します。対応するGithubリポジトリは here です。

11
Matt

間違いなくDictVectorizerを使用できます。 DictVectorizerdictに似たオブジェクトの反復可能オブジェクトを想定しているため、次のことを実行できます。

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)
6
Kris

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がAbarの影響を切片に組み込むことで多重共線性を回避しようとしたことに注意してください。そうすれば、たとえば、col1[T.B]予測子は、Bとして分類される観測に関連するAの追加効果として解釈されるべきです。

3
foglerit