スッキリわかるPython入門

国本・中山の性格を分析する(その3)

国本・中山の性格を分析する(その3)

こんにちは、スッキリJava&サーブレット&Python著者の国本です(カレー好き)。

前回は、PythonからIBM Cloudが提供する「Watson Personality Insights」を利用する方法を紹介しました。数分でアカウント登録ができて、さらに無料でやれちゃうんなんて、IBM Cloud 恐るべしでしたね。

今回はで私と中山氏の性格診断の結果を比べて、類似度をで出すのをPythonでやってみたいと思います。
開発環境はPython3系でAnacondaでインストールされたJupyterLabを使用します。

Pythonで類似度を出す方法は、とても沢山あります。

・ユークリッド距離
・Jaccard係数
・Dice係数
・コサイン類似度
・などなど

今回は、この中でも有名なコサイン類似度を用いてみます。

「コサイン類似度とは」という詳細な説明はおいておきます。その辺は文系の私の説明よりも、正しくきっちり説明してくれているサイトを参照してください(そのうち、数学大好き須藤氏が、解説の記事を書いてくれると思います)。

とりあえず、コサイン類似度 とは 「 1 - コサイン距離」で求める事ができる0から1の値で、1に近い方が類似度が高くなります。

コサイン距離は、計算式を自分で書いて求めることができますが、Scipyライブラリを使用して簡単に出すことができます。

簡単な例を見てみましょう。論よりソースです。次の例は、リストaとbのコサイン距離を求めています。(Anacondaをインストールしている場合、Scipyライブラリはインストール済みなので追加は必要はありません)

import scipy.spatial.distance as dis
a = [10, 20, 30];
b = [30, 20, 10];
cos_dis = dis.cosine(a, b)

コサイン類似度は「1からコサイン距離」を引いた値なので、下記のようにすれば求める事ができます。

cos_sim = 1 - cos_dis
print('類似度は{}'.format(cos_sim));

実行結果

類似度は0.7142857142857142

では、ここからが本題です。「中山氏=真面目」「国本=かぶきもの」といわれ続けてきた汚名を晴らすため、中山氏と私の性格が似ているかどうか、類似度を出して検証してみましょう。

まず、前回の記事を参考に性格診断を行う関数を作成しましょう。例では、関数の名前はget_profileにしています。

from ibm_watson import PersonalityInsightsV3
def get_profile(filename):
   # PersonalityInsigthsV3オブジェクトの作成 
   personality_insights = PersonalityInsightsV3(
        version='2017-10-13',
        iam_apikey='xxxxxxx', # Personality InsightsのAPI-Key
        url='xxxxxxx' # Personality InsightsのURL
    )
    # 分析データをファイルから読み込み
    with open(filename) as file:
        text =file.read()
    # 分析
    profile = personality_insights.profile(
        content=text,  # 入力データ(分析データ)
        accept='application/json',  #出力(結果)データの形式
        content_type='text/plain',  #入力データの形式
        content_language='ja'  #入力データの言語
    ).get_result()
    return profile

次に、性格診断の結果から各特性スコアを抽出してリストにセットする関数を作成します。例では関数名をget_scoreにしています。

def get_score(profile):
    score = [] # 各特性のスコアを格納するリスト
    # ビッグ・ファイブ特性を順に取得
    for factor in profile['personality']:
        percentile = factor['percentile'] # # 取得したビッグファイブ特性のスコア
        score.append(percentile)
        # 下位特性を順に取得
        for child in factor['children']:
            percentile = child['percentile'] # 取得した下位特性のスコア
            score.append(percentile)
    return score

これらの関数をつかって、中山氏と私の性格分析を行い、そのスコアをリストに格納します。

# 性格分析を実行
nakayama_profile = get_profile('nakayama.txt');
kunimoto_profile = get_profile('kunimoto.txt');

# 分析結果からスコアを抽出
nakayama_score = get_score(nakayama_profile)
kunimoto_score = get_score(kunimoto_profile)

最後に、コサイン類似度を算出して出力してみましょう。

import scipy.spatial.distance as dis
cos_sim =  1 - dis.cosine(nakayama_score, kunimoto_score)
print('類似度は{}'.format(cos_sim))

実行結果

類似度は0.9719659531879526

おおっ、結構高い!!  のかな? 試しに、Watson Personalit Insightsのデモサイトに用意されている夏目漱石とガンジーのデータを使って、私との類似度を出してみたところ、夏目漱石と国本の類似度は「0.8088908405554577」、ガンジーと国本の類似度は「0.7872312302481758」でした。

ということは、国本と中山氏は性格が激似と言っていいと思います(ほんまか?)

これで「スッキリわかるJava入門の菅原さんのモデルって中山さんですよね。まさか国本さんじゃないですよね。ははん(冷笑)」という問いにも自信をもって対応していけます。やったぜ、かあちゃん!

(ちなみに、菅原のモデルは中山・国本でもなく別人です)

-スッキリわかるPython入門
-