テキスト分類プログラムの構築:NLPチュートリアル
公開: 2022-03-11ディープラーニングは、機械学習ワークフローの不可欠な部分となったテクノロジーです。 並列計算能力とサポートツールの改善を利用して、かつては実用的ではなかった複雑で深いニューラルネットワークが現在実行可能になっています。
Tensorflow、Torch、Deeplearning4jなどの強力でアクセス可能なライブラリの出現により、大規模なテクノロジー企業の学界や研究部門を超えたユーザーにも開発が開かれました。 ファーウェイやアップルなどの企業は、その普及の証として、ディープラーニングアプリケーションを強化するために、最新のデバイスに専用のディープラーニングに最適化されたプロセッサを搭載しています。
ディープラーニングは、多くのドメインでその力を証明しています。 最も注目すべきは、GoogleのAlphaGoが囲碁のゲームで人間のプレイヤーを打ち負かすことができたということです。囲碁のゲームは、かつて人間のプレイヤーとの競争において、コンピューターに対する克服できないほどの複雑さの障壁と見なされていました。 ソニーのFlowMachinesプロジェクトは、過去の有名なミュージシャンのスタイルで音楽を作曲できるニューラルネットワークを開発しました。 Appleが開発したセキュリティ機能であるFaceIDは、ディープラーニングを使用してユーザーの顔を認識し、ユーザーの顔の変化を経時的に追跡します。
この記事では、自然言語処理とワインという2つのお気に入りのトピックにディープラーニングを適用します。 専門家による自然言語のワインレビューを理解し、彼らがレビューしているワインの多様性を推測するためのモデルを構築します。
NLPのディープラーニング
ディープラーニングは、文の複雑な基礎構造やさまざまな単語の意味的近接性を学習するのに適しているため、自然言語処理(NLP)で広く使用されています。 たとえば、感情分析の現在の最先端技術では、否定や混合感情などのモデル化が難しい言語概念をキャプチャするためにディープラーニングを使用しています。
ディープラーニングには、NLPの他のアルゴリズムに比べていくつかの利点があります。
- 柔軟なモデル:深層学習モデルは、他のMLモデルよりもはるかに柔軟です。 必要に応じてレイヤーを追加および削除して、さまざまな構造を簡単に試すことができます。 深層学習モデルでは、柔軟な出力を備えたモデルを構築することもできます。 柔軟性は、複雑な言語構造を理解するのに適したモデルを開発するための鍵です。 また、翻訳、チャットボット、テキスト読み上げアプリケーションなどのNLPアプリケーションの開発にも不可欠です。
- 必要なドメイン知識が少ない:優れたディープラーニングモデルを開発するには、確かにある程度のドメイン知識と直感が必要ですが、ディープラーニングアルゴリズムが独自に機能階層を学習できるということは、開発者が深層学習NLPアルゴリズムを開発するための問題空間。 自然言語のように複雑な問題空間の場合、これは非常に歓迎すべき利点です。
- 継続的な学習の容易化:ディープラーニングアルゴリズムは、新しいデータが入ってくると簡単にトレーニングできます。一部の機械学習アルゴリズムでは、データセット全体をモデルに送信して更新する必要があります。これは、ライブの大規模なデータセットでは問題が発生します。
今日の問題
本日は、レビューテキストに基づいてレビュー対象のワインの種類を決定するためのディープラーニングアルゴリズムを構築します。 Kaggleユーザーzackthouttが提供するhttps://www.kaggle.com/zynicide/wine-reviewsのワインマガジンデータセットを使用します。
概念的には、問題は、次のようなワインのレビューを受けることができるかということです…
アロマにはトロピカルフルーツ、ほうき、ブリムストーン、ドライハーブが含まれます。 味わいは過度に表現力がなく、熟していないリンゴ、柑橘類、乾燥したセージを、活発な酸味とともに提供します。
…そしてそれが白いブレンドについてであることを認識しますか? ワイン愛好家の中には、リンゴ、柑橘類、はっきりとした酸味などの白ワインの明らかな兆候を認識する人もいるかもしれませんが、これらの信号を認識するようにニューラルネットワークをトレーニングできますか? さらに、ホワイトブレンドレビューとピノグリジオレビューの微妙な違いを認識するようにニューラルネットワークをトレーニングできますか?
同様のアルゴリズム
私たちが今日取り組んでいる問題は、本質的にNLP分類の問題です。 NLPのさまざまな問題に適用されているNLP分類アルゴリズムがいくつかあります。 たとえば、ナイーブベイズはさまざまなスパム検出アルゴリズムで使用されており、サポートベクターマシン(SVM)は、医療機関で進捗メモなどのテキストを分類するために使用されています。 これらのアルゴリズムの単純なバージョンを実装して、深層学習モデルのベースラインとして機能させることは興味深いことです。
ナイーブベイズ
NLPのナイーブベイズの一般的な実装には、TF-IDFを使用してテキストを前処理し、前処理された出力で多項ナイーブベイズを実行することが含まれます。 これにより、ドキュメント内の最も目立つ単語に対してアルゴリズムを実行できます。 単純ベイズは次のように実装できます。
import numpy as np from sklearn.naive_bayes import MultinomialNB from sklearn.feature_extraction.text import CountVectorizer import pandas as pd from collections import Counter from sklearn.model_selection import train_test_split from sklearn.feature_extraction.text import TfidfTransformer df = pd.read_csv('data/wine_data.csv') counter = Counter(df['variety'].tolist()) top_10_varieties = {i[0]: idx for idx, i in enumerate(counter.most_common(10))} df = df[df['variety'].map(lambda x: x in top_10_varieties)] description_list = df['description'].tolist() varietal_list = [top_10_varieties[i] for i in df['variety'].tolist()] varietal_list = np.array(varietal_list) count_vect = CountVectorizer() x_train_counts = count_vect.fit_transform(description_list) tfidf_transformer = TfidfTransformer() x_train_tfidf = tfidf_transformer.fit_transform(x_train_counts) train_x, test_x, train_y, test_y = train_test_split(x_train_tfidf, varietal_list, test_size=0.3) clf = MultinomialNB().fit(train_x, train_y) y_score = clf.predict(test_x) n_right = 0 for i in range(len(y_score)): if y_score[i] == test_y[i]: n_right += 1 print("Accuracy: %.2f%%" % ((n_right/float(len(test_y)) * 100)))
上記のコードを実行すると、次のようなものが表示されます: 73.56%
10のクラスを見ていることを考えると、これはかなり良い結果です。
サポートベクターマシンを使用して、それがどのようになるかを確認することもできます。 パフォーマンスを確認するには、分類子の定義を次のように置き換えるだけです。
clf = SVC(kernel='linear').fit(train_x, train_y)
これを実行すると、次の出力が表示されます。

精度: 80.66%
ぼろぼろでもありません。
これらの結果を上回るか、少なくとも一致させることができる深層学習モデルを構築できるかどうかを見てみましょう。 それを管理すれば、私たちの深層学習モデルが、ドメインの専門知識によって知らされた人気のある機械学習モデルの結果を少なくとも複製するのに効果的であることを示す大きな兆候となるでしょう。
モデルの構築
今日は、KerasとTensorflowを使用してモデルを構築します。 Kerasは、Tensorflow APIの比較的低レベルのインターフェースと比較して、ディープラーニングモデルの構築を非常に簡単にするPythonライブラリです。 密なレイヤーに加えて、埋め込みレイヤーと畳み込みレイヤーを使用して、単語の基礎となる意味情報とデータ内の潜在的な構造パターンを学習します。
データクリーニング
まず、ニューラルネットワークで簡単に処理して理解できるようにデータを再構築する必要があります。 これを行うには、単語を一意の識別番号に置き換えます。 埋め込みベクトルと組み合わせると、柔軟で意味的に敏感な方法で単語を表すことができます。
実際には、この前処理についてもう少し賢くしたいと思うでしょう。 一般的に使用される単語に焦点を合わせ、最も一般的に使用される単語(たとえば、the、this、a)を除外することも理にかなっています。
DefaultdictとNLTKを使用してこの機能を実装できます。 次のコードを別のPythonモジュールに記述します。 lib/get_top_x_words.py
に配置しました。
from nltk import word_tokenize from collections import defaultdict def count_top_x_words(corpus, top_x, skip_top_n): count = defaultdict(lambda: 0) for c in corpus: for w in word_tokenize(c): count[w] += 1 count_tuples = sorted([(w, c) for w, c in count.items()], key=lambda x: x[1], reverse=True) return [i[0] for i in count_tuples[skip_top_n: skip_top_n + top_x]] def replace_top_x_words_with_vectors(corpus, top_x): topx_dict = {top_x[i]: i for i in range(len(top_x))} return [ [topx_dict[w] for w in word_tokenize(s) if w in topx_dict] for s in corpus ], topx_dict def filter_to_top_x(corpus, n_top, skip_n_top=0): top_x = count_top_x_words(corpus, n_top, skip_n_top) return replace_top_x_words_with_vectors(corpus, top_x)
これで、モデルを作成する準備が整いました。 アプリケーションに役立つ可能性のあるすべての深層学習機能を利用するために、埋め込み層、畳み込み層、および高密度層が必要です。 Kerasを使用すると、モデルを非常に簡単に構築できます。
from keras.models import Sequential from keras.layers import Dense, Conv1D, Flatten from keras.layers.embeddings import Embedding from keras.preprocessing import sequence from keras.utils import to_categorical import pandas as pd from collections import Counter from sklearn.model_selection import train_test_split from lib.get_top_xwords import filter_to_top_x df = pd.read_csv('data/wine_data.csv') counter = Counter(df['variety'].tolist()) top_10_varieties = {i[0]: idx for idx, i in enumerate(counter.most_common(10))} df = df[df['variety'].map(lambda x: x in top_10_varieties)] description_list = df['description'].tolist() mapped_list, word_list = filter_to_top_x(description_list, 2500, 10) varietal_list_o = [top_10_varieties[i] for i in df['variety'].tolist()] varietal_list = to_categorical(varietal_list_o) max_review_length = 150 mapped_list = sequence.pad_sequences(mapped_list, maxlen=max_review_length) train_x, test_x, train_y, test_y = train_test_split(mapped_list, varietal_list, test_size=0.3) max_review_length = 150 embedding_vector_length = 64 model = Sequential() model.add(Embedding(2500, embedding_vector_length, input_length=max_review_length)) model.add(Conv1D(50, 5)) model.add(Flatten()) model.add(Dense(100, activation='relu')) model.add(Dense(max(varietal_list_o) + 1, activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) model.fit(train_x, train_y, epochs=3, batch_size=64) y_score = model.predict(test_x) y_score = [[1 if i == max(sc) else 0 for i in sc] for sc in y_score] n_right = 0 for i in range(len(y_score)): if all(y_score[i][j] == test_y[i][j] for j in range(len(y_score[i]))): n_right += 1 print("Accuracy: %.2f%%" % ((n_right/float(len(test_y)) * 100)))
コードを実行すると、次の出力が表示されます。
精度: 77.20%
ナイーブベイズとSVCの精度はそれぞれ73.56%と80.66%だったことを思い出してください。 したがって、私たちのニューラルネットワークは、そこにあるより一般的なテキスト分類方法のいくつかに対して非常に独自のものを保持しています。
結論
今日は、ワインのレビューを分析するための分類ディープラーニングモデルの構築について説明しました。
他の機械学習アルゴリズムのいくつかと競合し、それを上回ることができるモデルを構築できることがわかりました。 この情報を使用して、より複雑なデータセットを分析し、より複雑な出力を生成するアプリケーションを構築するように促されることを願っています。
注:この記事で使用したコードはGitHubにあります。
Toptal Engineeringブログでさらに読む:
- より深い意味:Pythonでのトピックモデリング
- 電子メール感情分析ボットを構築する方法:NLPチュートリアル