ナード戦隊データマン

データサイエンスを用いて悪と戦うぞ

ツイートとMBTIを用いて論理的な人かどうか予測する

前回、「ツイートからMBTIの性格タイプ「分析家」かどうかを予測する」という記事の中で、分析家かどうかを予測しました。しかし、分析家は全体の20%しかいないため、モデルのaccuracy 80%という数字は無意味だったことになります。そこで、より広い範囲で「論理的」なタイプの人(全体の50%)に対して予測を立て、ちゃんとROCを用います。

使用するデータ

py_ml_tutorial/tweet_personalities.csv at master · sugiyamath/py_ml_tutorial · GitHub

Jupyter notebookのコード

In[1]:

import pandas as pd
import numpy as np
data = pd.read_csv("tweet_personalities.csv")
data["logical"] = data["label"].isin(["論理学者", "建築家", "指揮官", "討論者", "幹部", "管理者", "巨匠", "起業家"])
labels = np.unique(data["label"])

fixed_tweets = []

for val in data["tweet"].tolist():
    fixed_tweet = val
    regex = u'[ぁ-んァ-ンa-zA-Z]'

    for label in labels:
        fixed_tweet = fixed_tweet.replace(label, "")
        fixed_tweet = re.sub(regex, "", fixed_tweet)

    fixed_tweets.append(fixed_tweet)
        
data["tweet"] = fixed_tweets

In[2]:

from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np

pipe = Pipeline([('tfidf',TfidfVectorizer(min_df=3, max_df=10)), ("clf",LogisticRegression())])
grid = GridSearchCV(pipe, {}, cv=5, scoring="roc_auc")
np.mean(cross_val_score(grid, data["tweet"], data["logical"], cv=10))

Out[2]:

0.5563909774436091

In[3]:

%matplotlib inline
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve, auc
import matplotlib.pyplot as plt

X_train, X_test, y_train, y_test = train_test_split(data["tweet"], data["logical"])

grid.fit(X_train, y_train)
vectorizer = grid.best_estimator_.named_steps["tfidf"]
feature_names = np.array(vectorizer.get_feature_names())
fpr, tpr, _ = roc_curve(y_test.ravel(), grid.decision_function(X_test).ravel())

plt.figure()
lw = 2
plt.plot(fpr, tpr, color='darkorange', lw=lw)
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.show()

Out[3]: download (1).png

In[4]:

import mglearn

mglearn.tools.visualize_coefficients(
    grid.best_estimator_.named_steps["clf"].coef_,
    feature_names, n_top_features=10
)

Out[5]: download (3).png

考察

ROC曲線やAUCスコアを見る限り、微量な汎化能力があるように見えます。 (AUC>0.5なので)

ただ、それほど高い性能ではないことがわかります。前回と同様、サンプル数は限られており、自己顕示バイアスの影響があります。

「状況」「報酬」「対象」という言葉を使う人は、論理的だと判断される可能性が高まります。一方で、「学校」「質問」という言葉を使う人は、論理的ではないと判断される可能性が高まります。