7/13機械学習関連研修


7/13機械学習関連研修

今回はコサイン類似度・教師ありモデル(回帰)・教師ありモデル(分類)の研修をします(いずれもscikit-learnを使用しています) 教師ありモデル(回帰)・教師ありモデル(分類)については、おまけで時間が余ったらでOKです。それよりもコサイン類似度のロジックをじっくり 見てもらう方が良いです

コサイン類似度の例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

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

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



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



#コサイン類似度による比較(全項目分析)
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))

教師ありモデル(回帰)の例1

家賃を予測するモデル

#家賃を予測する
import numpy as np
from sklearn import linear_model
#1次元目は面積 2次元目は階
X = np.array([
    [7, 7.12, 7.2, 7.69, 7.79, 8, 8.28, 8.37, 8.7, 9.93, 10.5, 10.53, 11, 12.19, 12.4],
    [2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 3, 3, 1]
]).T
#家賃(千円単位)
Y = np.array([
    [45, 51, 52, 53, 52.6, 52, 54, 54.2, 56, 64, 65, 72, 75, 78.3, 80]
]).T

model = linear_model.LinearRegression(fit_intercept=False)
model.fit(X, Y)

#面積8m² で3階にある部屋の家賃は?=>[[51.32707814]]
print(model.predict([[8, 3]]))

教師ありモデル(回帰)の例2

上記の家賃を予測するシステムが作成したら、今度は松江家賃.csvを学習したモデルに書き換えて、松江の家賃を予測するシステムにしましょう 上記のモデルはプログラムの中に配列のデータを持っていますが、そこをpandasでcsvをデータフレームに読み込んで、学習させます

下記のサンプルは広さと何階かを入力としていますが、色々変えてみてください

#家賃を予測する
import pandas as pd
from sklearn import linear_model
df = pd.read_csv("松江家賃.csv", encoding="cp932")
X = df[["広さ", "階"]] 
Y = df["家賃"]

#2021/07/14 fit_intercept=Trueにすれば精度UP
#model = linear_model.LinearRegression(fit_intercept=False)
model = linear_model.LinearRegression(fit_intercept=True)
model.fit(X, Y)

#面積47.7m² で1階にある部屋の家賃は?=>[1.70486347]
print(model.predict([[47.7, 1]]))

教師ありモデル(分類)の例





(1)学習データとテストデータを前半と後半に単純に分ける(精度低)

・irisdataは品種別に並んでいます。なので、学習データをテストデータを前半と後半に分けると学習が偏って行われ、正しいモデルにはなりません

#アヤメの画像を分類する(NGパターン)
import numpy as np
from sklearn import linear_model
from sklearn.datasets import load_iris
#データの取り出し
data = load_iris()
X = data.data
#ターゲット
y = data.target

# 識別器を作成
clf = linear_model.LogisticRegression()
n_samples = X.shape[0]  # データの個数
n_train   = n_samples // 2
n_test    = n_samples - n_train
#最初の半分
train_index = range(0, n_train)
#残りの半分
test_index  = range(n_train, n_samples)

#学習データ, 学習データのラベル
X_train, y_train = X[train_index], y[train_index]
#テストデータ、テストデータのラベル
X_test, y_test = X[test_index], y[test_index]

#識別器の学習
clf.fit(X_train, y_train)

#学習データの精度
print(clf.score(X_train, y_train))

#テストデータの精度
print(clf.score(X_test, y_test))

#テストデータの識別
clf.predict(X_test)

実行結果 学習データの精度 100% テストデータの精度 33.3%



(2)学習データとテストデータを前半と後半に単純に分ける(精度高)

・学習データをテストデータをランダムに分けます

#アヤメの画像を分類する(OKパターン)
import numpy as np
from sklearn import linear_model
from sklearn.datasets import load_iris

#データの取り出し
data = load_iris()
X = data.data

#ターゲット(0:悪性 1:良性)
y = data.target

# 識別器を作成
clf = linear_model.LogisticRegression()

#ランダムに学習・テストに分割するモジュール
from sklearn.model_selection import ShuffleSplit
ss = ShuffleSplit(n_splits=1,           # 1個作成
                 train_size = 0.5,      # 学習は半分
                 test_size  = 0.5,      # テストの半分
                 random_state=0)        # 乱数種(再現用)

#学習データとテストデータのインデックス作成
train_index, test_index  = next(ss.split(X))

#学習データ, 学習データのラベル
X_train, y_train = X[train_index], y[train_index]

#テストデータ、テストデータのラベル
X_test, y_test = X[test_index], y[test_index]

#識別器の学習
clf.fit(X_train, y_train)

#学習データの精度
print(clf.score(X_train, y_train))

#テストデータの精度
print(clf.score(X_test, y_test))

#テストデータの識別
clf.predict(X_test)

実行結果 学習データの精度 92% テストデータの精度 84%