文章から抽出して判定する

以下のようにして、DataFrame dfの文章の列textを特徴行列に変換できます。

from sklearn.feature_extraction.text import CountVectorizer

cv = CountVectorizer()
X = cv.fit_transform(df['text'])

CountVectorizerは文章のリストを特徴行列に変換します。

  • 各文章(以下のN個)の文字列をスペースで区切って単語とする
  • 入力データ全体で出現する単語の種類を数える(以下のD個)
  • 各文ごとに、単語の出現回数を数えたN × D次元の特徴行列を作る
import pandas as pd
df = pd.read_csv('./input/reviews.csv')
df.head()
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer()
X = cv.fit_transform(df['text'])
y = df.iloc[:, 1]
import numpy as np
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression

# C=0.01, 0.1, 1, 10, 100で試した
lr = LogisticRegression(C=1, random_state=0, solver='liblinear')
scores = cross_val_score(lr, X, y, cv=10)
print("正答率", np.mean(scores), "標準偏差 +/-", np.std(scores))
正答率 0.8150000000000001 標準偏差 +/- 0.03905124837953326
from sklearn.tree import DecisionTreeClassifier

tree = DecisionTreeClassifier(random_state=0)
scores = cross_val_score(tree, X, y, cv=10)

print("正答率", np.mean(scores), "標準偏差 +/-", np.std(scores))
正答率 0.6599999999999999 標準偏差 +/- 0.0916515138991168
from sklearn.svm import SVC

# C=0.1, 1, 10 gamma=0.1, 1, 10で試した
svm = SVC(C=10, gamma=0.1, random_state=0)
scores = cross_val_score(svm, X, y, cv=10)

print("正答率", np.mean(scores), "標準偏差 +/-", np.std(scores))
正答率 0.7849999999999999 標準偏差 +/- 0.045000000000000005
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.3,
    random_state=0,
)

# 判定用に変数に保存
clf = lr
clf.fit(X_train, y_train)
clf.score(X_test, y_test)
0.8

新しい文章に対してのポジティブ/ネガティブ判定は、cv.transformで特徴量に変換してから、clf.predictをよぶことでできます。
例えば、clf.predict(cv.transform([‘Good points.’, ‘No answer.’]))を実行すると、array([1, 0])になります。最初の文がポジティブで、2つ目の文がネガティブということがわかります。

学習したモデルを使って、評価のないコメントから肯定かどうかを判定したり、SNSなどのコメントから商品が良い商品かどうかを判定したりできると思います。

また、テキストからの分類方法を知っていれば他にも以下の用途で活かせます。

  • スパムフィルター(スパムメールかどうかの判定)
  • ある人が好む・興味のある文章かどうかの判定

今回は英語の文章でしたので簡単にテキストから特徴抽出(ベクトル化)ができました。
英文はスペースで区切るだけでも単語に分割できるので解析は比較的簡単です。

しかし日本語の場合は 形態素解析 して文を単語に分割する必要があります。
日本語の文章から特徴抽出する場合は MeCabなどの形態素解析エンジンを使う必要があります。

CountVectorizerのtokenizer=引数に関数を渡すことで、文章を単語(トークン)にする処理を変更できます。

一般に文章に出てくる単語の種類は膨大で、データは多次元になります。多次元のデータの次元数を減らすことを次元の削減といいます。
詳細は、Python機械学習中級の「次元削減」で扱います。

次元削減についての参考

NLTKというライブラリーに含まれるストップワード一覧を使って単語数自体を減らしたり、単語の品詞を解析して特定の品詞のみ使ったりして次元を削減できます。
入門自然言語処理(次元の削減方法、精度の向上方法など)

コメント

タイトルとURLをコピーしました