この章の目標は、scikit-learnで最も重要なツールの1つを特定のタスクで調査することです。20の異なるトピックに関するテキストドキュメント(ニュース記事)のコレクションを分析します。
この章では、次の方法について説明します。
- ファイルのコンテンツとカテゴリをアップロードする
- 機械学習に適した特徴ベクトルを強調表示する
- 分類を実行するために1次元モデルを訓練する
- グリッド検索戦略を使用して、特徴抽出および分類子に最適な構成を見つけます
インストール手順
この章で説明する実用的なレッスンを開始するには、scikit-learnをインストールし、それに依存するすべてのコンポーネント(numpy、Scipy)をインストールする必要があります。
さまざまなオペレーティングシステムのインストール手順と推奨事項については、 このページにアクセスしてください 。
このレッスンのローカルコピーはフォルダーにあります。
scikit-learn / doc /チュートリアル/ text_analytics /
現在、scikit-learnはdoc /フォルダーおよびその他のコンテンツと共にインストールされません。 githubからダウンロードできます。
チュートリアルフォルダーには、次のファイルとフォルダーが含まれている必要があります。
- * .rstファイル-sphinxを使用して処理されたトレーニングドキュメントのソース
- data-トレーニング中にデータセットを保存するためのフォルダー
- スケルトン-不完全な運動スクリプトのサンプル
- ソリューション-運動ソリューション
sklearn_tut_workspaceと呼ばれるハードドライブ上の任意の場所にスケルトンをコピーすることもできます。ここで、独自の運動ファイルを編集します。 したがって、元のスケルトンは変更されません。
% cp -r skeletons work_directory/sklearn_tut_workspace
機械学習アルゴリズムにはデータが必要です。 $ TUTORIAL_HOME / dataの各サブフォルダーに移動し、そこからfetch_data.pyスクリプトを実行します(最初に読み取ります)。
例:
% cd $TUTORIAL_HOME/data/languages % less fetch_data.py % python fetch_data.py
20のニュースデータセットをダウンロードする
データセットは「Twenty Newsgroups」と呼ばれます。 以下は、 サイトから取られた彼の公式の説明です 。
「The 20 Newsgroups」データは、約20,000のニュースドキュメントのコレクションであり、20の異なるカテゴリに(ほぼ)均等に分割されています。 私たちが知る限り、それは元々Ken Langによって収集されたもので、おそらく彼の作品、Newsweeder:netnewsのフィルター処理について学習しましたが、明示的には述べていません。 20のニュースグループコレクションは、テキスト分類やクラスタリングなどのテキストアプリケーション用の機械学習手法を実験するための一般的なデータセットになりました。
次に、組み込みのデータセットローダーを使用して、scikit-learnから "The 20 newsgroups"を取得します。 それ以外の場合は、Webサイトから選択を手動でダウンロードし、 sklearn.datasets.load_files関数を使用して、「20news-bydate-train」フォルダーを指定して、解凍したアーカイブを保存できます。
最初の例をより速く実行するために、可能な20の内の4つのカテゴリに分割されたデータセットの一部のみを使用します。
>>> categories = ['alt.atheism', 'soc.religion.christian', ... 'comp.graphics', 'sci.med']
以下に示すように、必要なカテゴリに一致するファイルのリストをアップロードできます。
>>> from sklearn.datasets import fetch_20newsgroups >>> twenty_train = fetch_20newsgroups(subset='train', ... categories=categories, shuffle=True, random_state=42)
返されるデータセットはscikit-learnコレクションです。Pythonディクショナリのキー(dictキー)、つまりオブジェクトの属性(オブジェクト属性)として解釈できるフィールドを持つ1次元のコンテナです。 たとえば、target_namesには、要求されたカテゴリの名前のリストが含まれます。
>>> twenty_train.target_names ['alt.atheism', 'comp.graphics', 'sci.med', 'soc.religion.christian']
ファイル自体は、データ属性としてメモリにロードされます。 ファイル名も参照できます。
>>> len(twenty_train.data) 2257 >>> len(twenty_train.filenames) 2257
ロードされた最初のファイルの最初の行を印刷しましょう:
>>> print("\n".join(twenty_train.data[0].split("\n")[:3])) From: sd345@city.ac.uk (Michael Collier) Subject: Converting images to HP LaserJet III? Nntp-Posting-Host: hampton >>> print(twenty_train.target_names[twenty_train.target[0]]) comp.graphics
教師による指導(教師あり学習)のアルゴリズムでは、トレーニングサンプルの各ドキュメントに特定のカテゴリのゴミが含まれている必要があります。 この例では、カテゴリはニュースサンプルの名前であり、「偶然」は特定のドキュメントを含むフォルダーの名前です。
メモリの速度と効率的な使用を高めるために、scikit-learnはtarget_namesリストのカテゴリ名のインデックスに対応する整数の配列としてターゲット属性をロードします。 各サンプルのカテゴリインデックスは、ターゲット属性に保存されます。
>>> twenty_train.target[:10] array([1, 1, 3, 3, 3, 3, 3, 2, 2, 2])
カテゴリの名前を取得できます:
>>> for t in twenty_train.target[:10]: ... print(twenty_train.target_names[t]) ... comp.graphics comp.graphics soc.religion.christian soc.religion.christian soc.religion.christian soc.religion.christian soc.religion.christian sci.med sci.med sci.med
サンプルがランダムにシャッフルされたことに気付くかもしれません(ランダムに生成された数値を使用して-固定RNGシード)。 この方法は、モデルの迅速なトレーニングに最初のサンプルのみを使用する場合、および完全なデータセットでさらに再トレーニングする前に結果の一般的なアイデアを取得する場合に適しています。
テキストファイルから機能を抽出する
テキストドキュメントで機械学習を使用するには、最初にテキストコンテンツを数値特徴ベクトルに変換する必要があります。
「単語の袋」(単語のセット)
上記の変換を行う最も直感的な方法は、テキストを単語のセットとして表示することです。
- トレーニングセットのドキュメントに表示される各単語に一意の整数インデックスを割り当てます(たとえば、整数インデックスを持つ単語から辞書を作成する)。
- 各ドキュメント#iについて、各単語wの使用回数を計算し、X [i、j]に保存(数値)します。 これは属性#jの値になります。jは辞書内の単語wのインデックスです。
「単語の袋」の表現は、n_featuresがコーパス内の一意の単語の数であることを意味します。 通常、この量は100,000を超えます。
n_samples == 10000の場合、float32型のnumpy配列として保存されたXは、 10,000 x 100,000 x 4バイト= 4GBのRAM(RAM)を必要としますが 、これは現代のコンピューターではほとんど実現できません。
幸いなことに、 Xの値のほとんどはゼロです。これは、1つのドキュメントで使用される一意の単語が数百個未満であるためです。 したがって、「単語の袋」は、ほとんどの場合、 高次元のスパースデータセットです。 特徴ベクトルのゼロ以外の部分のみをメモリに保存することで、多くの空きRAMを節約できます。
scipy.sparseマトリックスは、まさにそれを行うデータ構造です—データを構造化します。 Scikit-learnには、これらの構造のサポートが組み込まれています。
scikit-learnを使用したテキストトークン化
テキストの前処理、トークン化、ストップワードのフィルタリングが高レベルコンポーネントに含まれているため、特徴的な機能の辞書を作成し、ドキュメントを機能ベクトルに変換できます。
>>> from sklearn.feature_extraction.text import CountVectorizer >>> count_vect = CountVectorizer() >>> X_train_counts = count_vect.fit_transform(twenty_train.data) >>> X_train_counts.shape (2257, 35788)
CountVectorizerは、Nグラムの単語または文字シーケンスのカウントをサポートしています。 ベクトル化機能は、機能インデックスの辞書を作成します。
>>> count_vect.vocabulary_.get(u'algorithm') 4690
辞書内の単語のインデックスの値は、教育施設全体での使用頻度に関連しています。
使用から頻度まで
単語の使用を数えることは良い出発点ですが、問題があります。長いドキュメントでは、1つのトピックに焦点を当てていても、単語の使用の平均数は短いドキュメントよりも多くなります。
これらの潜在的な不整合を回避するには、文書内の各単語の使用回数を文書内の単語の総数で割れば十分です。 この新しい機能はtf-用語の頻度と呼ばれます。
tfメジャーの次の改良点は、コーパス内の多くの文書に現れる単語の重みの削減であり、ここからはコーパスのごく一部でのみ使用される文書よりも情報量が少なくなります。 低い規範的な単語の例は、サービス単語、記事、前置詞、接続詞などです。
この減少はtf – idfと呼ばれ、「用語頻度と逆文書頻度」を意味します。
メジャーtfとtf – idfは、次のように計算できます。
>>> from sklearn.feature_extraction.text import TfidfTransformer >>> tf_transformer = TfidfTransformer(use_idf=False).fit(X_train_counts) >>> X_train_tf = tf_transformer.transform(X_train_counts) >>> X_train_tf.shape (2257, 35788)
上記のコード例では、最初にfit(..)メソッドを使用してデータ推定アルゴリズムを実行し、次にtransform(..)メソッドを使用して数値行列をtf-idf表現に変換します。 これらの2つのステップを組み合わせて同じ出力を得ることができますが、不要な処理をスキップすることで高速化できます。 これを行うには、以下に示すようにfit_transform(..)メソッドを使用します。
>>> tfidf_transformer = TfidfTransformer() >>> X_train_tfidf = tfidf_transformer.fit_transform(X_train_counts) >>> X_train_tfidf.shape (2257, 35788)
...
パート2に続きます。