ある日、私はイギリスとアメリカの文学が単語の選択の点で異なっているのか疑問に思いました。もしそれらが異なっていれば、使用される単語の頻度の点で文学テキストを区別する分類器を訓練することができますか? 異なる言語で書かれたテキストを区別するのは非常に簡単です。多くの単語の交差の力は、サンプル内の多くの単語に比べて小さいです。 テキストを「科学」、「キリスト教」、「コンピューターグラフィックス」、「無神論」のカテゴリに分類することは、テキストの頻度で作業するタスクの中でよく知られているこんにちは世界です。 同じ言語の2つの方言を比較し、テキストには一般的なセマンティック指向がなかったため、私はより困難な作業に直面しました。
機械学習の最も長い段階はデータマイニングです。 トレーニングサンプルでは、 Project Gutenbergのテキストを使用しました。これらは自由にダウンロードできます。 ウィキペディアからデフレートしたアメリカとイギリスの著者のリスト。 困難は、著者の名前で一致を見つけることでした。 プロジェクトのサイトは名前で検索できますが、サイトの解析は禁止されており、代わりにメタデータを含むアーカイブを使用することが提案されています。 これは、名前の一致(アーサー・イグナティウス・コナン・ドイルとドイル、C。は同じ人であり、メイン州のドイルはもはやない)の一致する名前の非自明な問題を解決し、非常に高い精度でそれを行う必要があることを意味しました。 代わりに、正確さを優先してサンプルサイズを犠牲にして時間を節約したため、一部のメタデータファイルに含まれている著者のWikipediaリンクを一意の識別子として選択しました。 だから私は約1,600の英国のテキストと2,500のアメリカのテキストを受け取り、分類器を訓練し始めました。
すべての操作で、sklearnパッケージを使用しました。 データを収集して分析した後の最初のステップは、CountVectorizerを使用した前処理です。 テキストデータの入力配列を受け取り、特徴ベクトルを返します。 次に、分類器は数値データを処理するため、特性を数値形式で提示する必要があります。 これを行うには、tf-idf、 ターム頻度 -TfidfTransformerを使用して逆ドキュメント頻度を計算します。
これが行われる方法と理由の簡単な例:
「the」という単語を取り、テキストAでこの単語の出現回数をカウントします。出現回数を100とし、ドキュメント内の単語の合計数を1000とします。
tf(“the”) = 100/1000 = 0.1
次に、50回発生した「sepal」(sepal)という単語を取り上げます。
tf(“sepal”) = 50/1000 = 0.05
これらの単語の逆ドキュメント頻度を計算するには、テキストの総数に対するこの単語の出現が少なくとも1つあるテキストの数の比率の対数を取る必要があります。 合計10,000件のテキストがあり、それぞれに「the」という単語がある場合、
idf(“the”) = log(10000/10000) = 0
tf-idf(“the”) = idf(“the”) * tf(“the”) = 0 * 0.1 = 0
「sepal」という言葉ははるかにまれであり、5つのテキストでのみ見つかったため、
idf(“sepal”) = log(10000/5) = 7.6
tf-idf(“sepal”) = 7.6 * 0.05 = 0.38
したがって、頻出する単語には最小の重みがあり、特定のまれな単語には大きな重みがあり、テキストに「sepal」という単語が大量に出現することにより、植物学と何らかの関係があると推測できます。
データが一連の機能として表示されるようになったので、分類器をトレーニングする必要があります。 スパースデータとして表示されるテキストを使用するため、多くの機能を備えた分類タスクにうまく対応する線形分類器が最適なオプションでした。 そして、CountVectorizer、TF-IDFTransformer、およびSGDをデフォルトのパラメーターでトレーニングしました。 各ステージで個別に作業できますが、パイプラインを使用する方が便利です。
pipeline = Pipeline([ ('vect', CountVectorizer()), ('tfidf', TfidfTransformer()), ('clf', SGDClassifier()), ])
精度とサンプルサイズのグラフを分析したところ、サンプルサイズが大きい場合でも精度に大きな変動があることがわかりました。これは、分類器が特定のサンプルに大きく依存していることを示しています。つまり、あまり効果的ではなく、大幅な改善が必要です。 分類器の重みのリストを受け取った後、問題の一部に気付きました。アルゴリズムは、「of」や「he」などの基本的にノイズである頻出語で再訓練されました。 この問題は、そのような単語を記号から削除することで簡単に解決でき、パラメータCountVectorizer stop_words = 'english'または独自の単語リストによって設定されます。 いくつかの一般的な一般的な単語を削除して、精度をもう少し改善しました。 ストップワードを削除すると、精度が0.85向上しました。
次に、GridSearchCVを使用してパラメーターの設定を開始しました。 このメソッドは、CountVectorizer、TfidfTransformer、およびSGDClassifierのパラメーターの最適な組み合わせを明らかにするため、これは非常に長いプロセスであり、約1日かかりました。 その結果、私はそのようなパイプラインを得ました:
pipeline = Pipeline([ ('vect', CountVectorizer(stop_words = modifyStopWords(), ngram_range = (1, 1))), ('tfidf', TfidfTransformer(use_idf = True, norm = 'l2', smooth_idf = True)), ('clf', SGDClassifier(alpha=0.001, fit_intercept = True, n_iter = 10, penalty = 'l2', loss = 'epsilon_insensitive')), ])
最終的な精度は0.89です。
私にとって最も興味深いのは、どの単語がテキストの起源を示しているかということです。 以下は、分類子の重み修飾子によって降順でソートされた単語のリストです。
アメリカのテキスト :ドル、新しい、ニューヨーク、女の子、グレー、アメリカ、カーベル、色、都市、アイン、長い、ちょうど、パーラー、ボストン、名誉、ワシントン、家、労働、得た、最終的に、多分、ホダー、永遠に、ドロシー博士
イギリスのテキスト :ラウンド、サー、レディ、ロンドン、かなり、ミスター、しなければならない、ロード、グレー、親愛なる、名誉、持つ、フィリップ、貧しい、ポンド、スクルージ、ソームズ、物、海、男、終わり、来る、色、イラスト、英語、学んだ
分類子を楽しんで、アメリカ人と最も「アメリカ人」の英国人から最も「イギリス人」の著者を得ました(私の分類子がどれだけ間違っている可能性があるかについて話すエレガントな方法です):
最も「イギリス人」のアメリカ人:
- バーネット、フランシス・エリザ(イギリス生まれ、17歳でアメリカに引っ越したので、彼女をアメリカ人と結びつけます)
- ヘンリー・ジェームズ(米国生まれ、33歳で英国に移住)
- ウィスター、オーウェン
- メアリー・ロバーツ・ラインハート(私たちが見るように、アメリカのアガサ・クリスティーと呼ばれる理由があります)
- ウィリアム・マクフィー(バーネットのように、幼い頃にアメリカに引っ越した)
最も「アメリカ人」英国人:
- リディアード・キプリング(アメリカに数年間住んでいたが、「アメリカン・ノート」のおかげでリストに載った)
- アンソニー・トロロップ(再び、アメリカの地名は彼の「北米」のせいだ)
- フレデリック・マリエット(おそらく、「カリフォルニア、ソナラ、テキサス西部のムッシューヴァイオレットの旅と冒険の物語」という名前は、分類器を混乱させるのに十分でしょう)
- アーノルドベネット(「米国:最初の訪問の印象」に感謝)
- フィリップスオッペンハイム
また、最も「イギリス人」のイギリス人と「アメリカ人」のアメリカ人(分類器はまだ良いため)。
アメリカ人:
- フランシス・ホプキンソン・スミス
- ガムリンガーランド
- ジョージ・エイド
- チャールズ・ダドリー・ワーナー
- マーク・トウェイン
イギリス人:
- ジョージ・メレディス
- サミュエル・リチャードソン
- ジョン・ガルズワージー
- ギルバートキースチェスタトン
- アンソニー・トロロープ
@TragicAllyHereのツイートは、そのような分類子を作成するように私をプッシュしました:
私はイギリス人になりたいです。 葉の水を飲んで、赤い電話ボックスから巨大な時計を見つめ、さらに文字を追加します。
コードはここで取得できます。すでにトレーニングされた分類子も利用できます。