私が作成したパイプラインを修正する方法を理解するのは難しいと感じています(お読みください:チュートリアルから主に貼り付けられています)。 python 3.4.2:
_df = pd.DataFrame
df = DataFrame.from_records(train)
test = [blah1, blah2, blah3]
pipeline = Pipeline([('vectorizer', CountVectorizer()), ('classifier', RandomForestClassifier())])
pipeline.fit(numpy.asarray(df[0]), numpy.asarray(df[1]))
predicted = pipeline.predict(test)
_
実行すると、次の結果が得られます。
_TypeError: A sparse matrix was passed, but dense data is required. Use X.toarray() to convert to a dense numpy array.
_
これはpipeline.fit(numpy.asarray(df[0]), numpy.asarray(df[1]))
行用です。
私はnumpy、scipyなどを通じてソリューションをたくさん試しましたが、まだそれを修正する方法がわかりません。はい、以前にも同様の質問がありましたが、パイプラインの内部にはありません。 toarray
またはtodense
を適用する必要があるのはどこですか?
残念ながら、これら2つには互換性がありません。 CountVectorizer
は疎行列を生成し、RandomForestClassifierは密行列を必要とします。 X.todense()
を使用して変換することができます。これを行うと、メモリフットプリントが大幅に増加します。
http://zacstewart.com/2014/08/05/pipelines-of-featureunions-of-pipelines.html に基づいてこれを行うためのサンプルコードを以下に示します。これにより、.todense()
パイプラインステージ。
class DenseTransformer(TransformerMixin):
def fit(self, X, y=None, **fit_params):
return self
def transform(self, X, y=None, **fit_params):
return X.todense()
DenseTransformer
を取得したら、それをパイプラインステップとして追加できます。
pipeline = Pipeline([
('vectorizer', CountVectorizer()),
('to_dense', DenseTransformer()),
('classifier', RandomForestClassifier())
])
別のオプションは、LinearSVC
のようなスパースデータ用の分類子を使用することです。
from sklearn.svm import LinearSVC
pipeline = Pipeline([('vectorizer', CountVectorizer()), ('classifier', LinearSVC())])
0.16-devのランダムフォレストは、スパースデータを受け入れるようになりました。
最も簡潔な解決策は、FunctionTransformer
を使用してデンスに変換することです。これは、Davidの答えのように、fit
、transform
、およびfit_transform
メソッドを自動的に実装します。さらに、パイプラインステップに特別な名前が必要ない場合は、sklearn.pipeline.make_pipeline
便利な関数を使用して、モデルを記述するためのよりシンプルな言語を有効にします。
from sklearn.preprocessing import FunctionTransformer
pipeline = make_pipeline(
CountVectorizer(),
FunctionTransformer(lambda x: x.todense(), accept_sparse=True),
RandomForestClassifier()
)
_.values
_メソッドを使用して、pandas Series
を配列に変更できます。
_pipeline.fit(df[0].values, df[1].values)
_
ただし、CountVectorizer()
はデフォルトでスパース行列を返し、RF分類子にパイプすることはできません。CountVectorizer()
には返される配列のタイプを指定するdtype
パラメーター単語の特徴ベクトルは非常に長いため、通常、テキストの分類にランダムフォレストを使用するには、何らかの次元削減を行う必要があります