分類器トレーニング
記号を特定したので、テキストのカテゴリを予測するために分類器をトレーニングできます。 Naive Bayes Classifierから始めましょう。これは、タスクの出発点として最適です。 scikit-learnには、この分類子のバリアントがいくつか含まれています。 単語カウントに最も適しているのは、多項式バージョンです。
>>> from sklearn.naive_bayes import MultinomialNB >>> clf = MultinomialNB().fit(X_train_tfidf, twenty_train.target)
新しいドキュメントで結果を予測できるように、以前とほぼ同じシーケンスを使用して特徴(特徴)を抽出する必要があります。 違いは、トランスフォーマーのfit_transformの代わりに変換メソッドが使用されることです。これらは既にトレーニングセットに適用されているためです。
>>> docs_new = ['God is love', 'OpenGL on the GPU is fast'] >>> X_new_counts = count_vect.transform(docs_new) >>> X_new_tfidf = tfidf_transformer.transform(X_new_counts) >>> predicted = clf.predict(X_new_tfidf) >>> for doc, category in zip(docs_new, predicted): ... print('%r => %s' % (doc, twenty_train.target_names[category])) ... 'God is love' => soc.religion.christian 'OpenGL on the GPU is fast' => comp.graphics
パイプラインを作成する
チェインベクトライザー=>トランスフォーマー=>分類器での作業を容易にするために、scikit-learnには、複合(パイプライン化)分類器として機能するPipelineクラスがあります。
>>> from sklearn.pipeline import Pipeline >>> text_clf = Pipeline([('vect', CountVectorizer()), ... ('tfidf', TfidfTransformer()), ... ('clf', MultinomialNB()), ... ])
名前vect、tfidf、およびclf(分類子)は、私たちが任意に選択しました。 グリッド検索の章の後半でそれらの使用について説明します。 ここで、たった1つのコマンドでモデルをトレーニングします。
>>> text_clf = text_clf.fit(twenty_train.data, twenty_train.target)
テストサンプルで作業するときのパフォーマンス評価
予測モデルの精度の評価は非常に簡単です。
>>> import numpy as np >>> twenty_test = fetch_20newsgroups(subset='test', ... categories=categories, shuffle=True, random_state=42) >>> docs_test = twenty_test.data >>> predicted = text_clf.predict(docs_test) >>> np.mean(predicted == twenty_test.target) 0.834...
たとえば、83%の精度が得られました。 線形サポートベクターマシン(SVM)メソッドを使用してこの結果を改善できるかどうかを見てみましょう。 この方法は、一般的にテキスト分類アルゴリズムのベストと考えられています(ただし、単純なベイズよりも少し遅いです)。 別の分類オブジェクトをパイプラインに接続するだけで、学習モデルを変更できます。
>>> from sklearn.linear_model import SGDClassifier >>> text_clf = Pipeline([('vect', CountVectorizer()), ... ('tfidf', TfidfTransformer()), ... ('clf', SGDClassifier(loss='hinge', penalty='l2', ... alpha=1e-3, n_iter=5, random_state=42)), ... ]) >>> _ = text_clf.fit(twenty_train.data, twenty_train.target) >>> predicted = text_clf.predict(docs_test) >>> np.mean(predicted == twenty_test.target) 0.912...
scikit-learnは、結果のより詳細な分析のためのユーティリティも提供します。
>>> from sklearn import metrics >>> print(metrics.classification_report(twenty_test.target, predicted, ... target_names=twenty_test.target_names)) ... precision recall f1-score support alt.atheism 0.95 0.81 0.87 319 comp.graphics 0.88 0.97 0.92 389 sci.med 0.94 0.90 0.92 396 soc.religion.christian 0.90 0.95 0.93 398 avg / total 0.92 0.91 0.91 1502 >>> metrics.confusion_matrix(twenty_test.target, predicted) array([[258, 11, 15, 35], [ 4, 379, 3, 3], [ 5, 33, 355, 3], [ 5, 10, 4, 379]])
予想どおり、不正確さのマトリックスは、モデルがコンピューターグラフィックスに関するテキストよりも、無神論とキリスト教に関するニュースグループのテキストを混同することが多いことを示しています。
グリッド検索を使用するためのオプションの設定
TfidfTransformer関数のuse_idfなど、いくつかのパラメーターは既に計算されています。 分類子には原則として多くのパラメーターもあります。たとえば、MultinomialNBには平滑化係数アルファが含まれ、SGDClassifierには目的関数にペナルティーパラメーターアルファ(ペナルティ関数メソッド)、カスタム損失およびペナルティ項があります(ドキュメントセクションを参照するか、Pythonヒント関数を使用します)詳細情報を取得します)。
回路内のさまざまなコンポーネントのパラメーターを検索する代わりに、可能な値のグリッドで最適なパラメーターの検索を(徹底的な検索によって)開始できます。 SVM(サポートベクターメソッド)の0.01および0.001のペナルティパラメーターを使用して、idfを使用して、または使用せずに、単語またはバイグラムですべての分類器を試しました。
>>> from sklearn.grid_search import GridSearchCV >>> parameters = {'vect__ngram_range': [(1, 1), (1, 2)], ... 'tfidf__use_idf': (True, False), ... 'clf__alpha': (1e-2, 1e-3), ... }
明らかに、徹底的な検索を使用したこのような検索は、リソースを大量に消費する可能性があります。 多くのプロセッサコアを自由に使用できる場合は、グリッド検索を実行して、n_jobsパラメーターと並行してパラメーターのすべての組み合わせを試すことができます。 このパラメーターを-1に設定すると、グリッド検索により、インストールされているコアの数が決定され、すべてのコアが使用されます。
>>> gs_clf = GridSearchCV(text_clf, parameters, n_jobs=-1)
グリッド検索インスタンスは、通常のscikit-learnモデルのように動作します。 トレーニングセットの小さな部分で検索を実行して、処理速度を上げましょう。
>>> gs_clf = gs_clf.fit(twenty_train.data[:400], twenty_train.target[:400])
GridSearchCVオブジェクトにfitメソッドを適用した結果、予測関数の実行に使用できる分類子を取得します。
>>> twenty_train.target_names[gs_clf.predict(['God is love'])] 'soc.religion.christian'
しかし、一方で、それは非常に大きくてかさばるオブジェクトです。 パラメータとメジャーのペアのリストであるgrid_scores_オブジェクトの属性を調べることで、最適なパラメータを取得できます。 メジャーの属性を取得するには、次のことができます。
>>> best_parameters, score, _ = max(gs_clf.grid_scores_, key=lambda x: x[1]) >>> for param_name in sorted(parameters.keys()): ... print("%s: %r" % (param_name, best_parameters[param_name])) ... clf__alpha: 0.001 tfidf__use_idf: True vect__ngram_range: (1, 1) >>> score 0.900...
演習
演習を完了するには、「skeletons」フォルダーの内容を「workspace」という新しいフォルダーにコピーします。
% cp -r skeletons workspace
演習の元の指示を失うことを恐れずに、ワークスペースフォルダーの内容を編集できます。
次に、ipythonシェルを開き、演習用の未完成のスクリプトを実行します。
[1] %run workspace/exercise_XX_script.py arg1 arg2 arg3
例外がスローされた場合、%debugを使用して緊急ipdbセッションを開始します。
実装をクリーンアップし、問題が解決するまで繰り返します。
各演習で、スケルトンファイルには、必要なすべてのインポート命令、データを読み込むためのコードテンプレート、およびモデル予測の精度を評価するためのコード例が含まれています。
演習1:言語の定義
- パイプラインを書く-特別な前処理とCharNGramAnalyzerを使用したテキスト分類子。 ウィキペディアの記事をトレーニングサンプルとして使用します。
- トレーニングサンプルと一致しないテストサンプルのパフォーマンスを評価します。
ipythonコマンドライン:
%run workspace/exercise_01_language_train_model.py data/languages/paragraphs/
演習2:映画レビューに基づく好みの分析
- パイプラインを書く-映画レビューをポジティブとネガティブに分類するテキスト分類子。
- グリッド検索を使用して、適切なパラメーターセットを選択します。
- テストサンプルのパフォーマンスを評価します。
ipythonコマンドライン:
%run workspace/exercise_02_sentiment.py data/movie_reviews/txt_sentoken/
演習3:ユーティリティ-コマンドラインでのテキスト分類子(コンソールアプリケーション)
前の演習の結果と標準ライブラリのcPickleモジュールを使用して、標準入力(キーボード入力)のテキストの言語を決定し、テキストが英語で記述されている場合は極性(正または負)を決定するコマンドラインユーティリティを記述します。
次は?
このセクションでは、演習を完了した後にscikit-learnに慣れるのに役立ついくつかのヒントを提供します。
- アナライザーとトークンの正規化をCountVectorizerに適用してみてください
- マークアップがない場合は、 クラスタリングを使用して問題を解決してください。
- ドキュメントに多くのタグが付けられている場合、つまり カテゴリー、 マルチクラスとマルチラベルのセクションを見てください
- 潜在セマンティック分析に Truncated SVDを使用してみてください。
- RAMに収まらないデータから学習するために、 Out-of-Core Classificationの使用を発見してください。
- CountVectorizerと比較して必要な空きメモリが少ないHashing Vectorizerを確認してください 。