2021年10月秋研修


2021年秋研修

・今回はコサイン類似度を学習します。コサイン類似度は文章の類似度を検索する場合に使われるものですが、 今回は人の成績等を入力として類似した人を検索する処理を行ってみます

・使用するライブラリは機械学習でおなじみのscikit-learnです。

※実習1、2のデータはここからダウンロード
※実習3クライアントはここからダウンロード

実習1:コサイン類似度の例1

・プロ野球のデータで試してみます。成績を元に、一人のバッターのと似たバッターを検索します

#コサイン類似度による比較 鈴木誠也と似た選手を探す
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity

df1 = pd.read_csv("hitter_2020_C.csv", encoding="cp932")
df2 = pd.read_csv("hitter_2020_D.csv", encoding="cp932")
df3 = pd.read_csv("hitter_2020_G.csv", encoding="cp932")
df4 = pd.read_csv("hitter_2020_S.csv", encoding="cp932")
df5 = pd.read_csv("hitter_2020_T.csv", encoding="cp932")
df6 = pd.read_csv("hitter_2020_YB.csv", encoding="cp932")
df = pd.concat([df1,df2,df3,df4,df5,df6])

data = df[["打率","出塁率","長打率","OPS","RC27","XR27"]]
data = data.replace('-','0')

#鈴木誠也
new_data = [["0.3","0.409","0.544","0.953","7.67","7.46"]]

cos_sim = cosine_similarity(data, new_data)

data["類似度"] = cos_sim
data["選手名"] = df["選手名"]
data = data.sort_values("類似度", ascending=False) 

print(data["選手名"] + ":" + data["類似度"].astype(str))

data.to_csv("test.csv", encoding="cp932")

他の人と似た人を探したいとき

hitter_2020_T.csv等のファイルをEXCELで開き、その中から"打率","出塁率","長打率","OPS","RC27","XR27" を調べて、以下のコードの部分を書き換えます

new_data = [["0.3","0.409","0.544","0.953","7.67","7.46"]]

例)阪神の近本選手と比べたいとき、以下の様に書き換えます

new_data = [["0.293","0.344","0.416","0.759","5.46","5.27"]]

実習2:コサイン類似度の例2

性格分析の例 就活生の性格が自分の会社の社員の誰に性格が似ているかを探します

①比較される対象のデータ(企業の社員データ)data.csv



②比較する対象のデータ(就活生データ)good.csv



#コサイン類似度による比較(全項目分析)
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity

df1 = pd.read_csv("data.csv", encoding="cp932")
df2 = pd.read_csv("good.csv", encoding="cp932")

data = df1.drop(["個人ID","漢字姓","漢字名","カナ姓","カナ名","メールアドレス","生年月日","受検言語","CAB1受検日","CAB2受検日","CAB3受検日","CAB4受検日","OPQ受検日","一貫性"], axis=1)
new_data = df2.drop(["個人ID","漢字姓","漢字名","カナ姓","カナ名","メールアドレス","生年月日","受検言語","CAB1受検日","CAB2受検日","CAB3受検日","CAB4受検日","OPQ受検日","一貫性"], axis=1)

cos_sim = cosine_similarity(data, new_data)

data["類似度"] = cos_sim
data["名前"] = df1["漢字姓"]+df1["漢字名"]
data = data.sort_values("類似度", ascending=False) 

print(data["名前"] + ":" +  data["ヴァイタリティ"].astype(str) + ":" + data["オーガナイズ能力"].astype(str)+ ":" + data["類似度"].astype(str))

実習3:性格類似者検索システム

今回研修で作成するシステム(性格類似者検索システム)

①PythonAPIに処理を追加する

②RailsのサンプルクライアントをHerokuに配備する


提供するクライアントのサンプルの表示

①受検者一覧

②受検者一覧の詳細ボタンをクリックすると詳細画面が表示され、一番下にPythonAPIで取得した類似者が表示される


今回は前回構築してherokuに配備したモデルに性格検索処理を追加します。クライアントはサンプルを用意しますので、herokuに配備してください


今回の作業内容

①前回構築したPythonAPIに検索処理を追加します。

app.py

from joblib import dump, load
import flask
import numpy as np
from flask_cors import CORS 

# initialize our Flask application and pre-trained model
app = flask.Flask(__name__)
CORS(app)
model = None

# 学習済モデルの読み込み
def load_model():
    global model
    print(" * Loading pre-trained model ...")
    model = load("sample-model.pkl")
    print(' * Loading end')

# 接続確認テスト用 getでrootにアクセスしたときに、Hello Worldを表示させる
@app.route('/')
def index():
    return 'Hello World!'

# 機械学習結果返却処理
@app.route("/predict", methods=["POST"])
def predict():
    model = load("sample-model.pkl")
    response = {
        "success": False,
        "Content-Type": "application/json"
    }
    # ensure an feature was properly uploaded to our endpoint
    if flask.request.method == "POST":
        if flask.request.get_json().get("feature"):
            # read feature from json
            feature = flask.request.get_json().get("feature")

            # preprocess for classification
            # list  -> np.ndarray
            feature = np.array(feature).reshape((1, -1))

            # classify the input feature
            response["prediction"] = model.predict(feature).tolist()

            # indicate that the request was a success
            response["success"] = True
    # return the data dictionary as a JSON response
    return flask.jsonify(response)

#--- 追加START ---
@app.route("/classify", methods=["POST"])
def classify():
    df1 = pd.read_csv("data.csv", encoding="cp932")
    
    data = df1[["説得力","指導力","独自性","外向性","友好性","社会性","謙虚さ","協議性","面倒み","具体的事物","データ","美的価値","人間","オーソドックス","変化志向","概念性","創造的","計画性","緻密","几帳面","余裕","心配性","タフ","抑制","楽観的","批判的","行動力","競争性","上昇志向","決断力"]]

    response = {
        "success": False,
        "Content-Type": "application/json"
    }
    if flask.request.method == "POST":
        if flask.request.get_json().get("feature"):
            # read feature from json
            feature = flask.request.get_json().get("feature")

            # preprocess for classification
            # list  -> np.ndarray
            feature = np.array(feature).reshape((1, -1))

            cos_sim = cosine_similarity(data, feature)
            
            data["類似度"] = cos_sim
            data["名前"]   = df1["漢字姓"] + " "+ df1["漢字名"]
            data["個人ID"]   = df1["個人ID"]
            data = data.sort_values("類似度", ascending=False) 
            
            print(data["名前"] + ":" + data["類似度"].astype(str))

            # 類似度の高い5件を返す
            sdata = data.head(5)

            print(sdata["名前"] + ":" + sdata["類似度"].astype(str))

            classify = []
            for index, row in sdata.iterrows():
                classify.append([row["名前"], row["類似度"], row["個人ID"]])

            response["classify"] = classify

            # indicate that the request was a success
            response["success"] = True

    return flask.jsonify(response)

#--- 追加END ---

if __name__ == "__main__":
    load_model()
    print(" * Flask starting server...")
    app.run(host='0.0.0.0', port='8000')

②クライアントの配備

・syslink-recuruit.zipを解凍し以下の修正後、自分のherokuに配備してください

◆サンプルの修正点 APIのURLを自分のHerokuのURLに変更してください。

examinees_controller showメソッド

  def show
    logger.info "-----------------------Examinees show start-----------------------------"
    @examinee = Examinee.find(params[:id])

    # API情報設定
    uri = URI.parse("http://syslink-recuruit-api.herokuapp.com/classify") #ここを直してください
    http = Net::HTTP.new(uri.host, uri.port)
    req = Net::HTTP::Post.new(uri.path)
    req.set_content_type("application/json")

・配備後、以下のコマンドでデータを付け込んでください

heroku run rails db:migrate
heroku run rails db:fixtures:load
heroku run import:spi
heroku run import:examinee
heroku run update:examinee
heroku run add:spi
heroku run update:spi
heroku run update:acceptance