大辞林より
従来,機械(コンピュータ)に仕事をさせるには,人間が情報処理の手順や法則をプログラムとして記述し,機械に与えて実行していた
一方,機械学習による情報処理では,機械(コンピュータ)がデータから法則を自動的・統計的に学習する
データにおける入力X(特徴量)と出力y(正解データ)の関係f (y = f(X))を学習する. 機械学習の最も代表的なアプローチ.回帰と分類の2タイプに大別される.
正解データを指定せず,データそのものがどのような性質を持っているかを学習する. 代表的な方法に次元削減,クラスタリングがある.
ヒオウギ・アヤメ(Iris-Setosa) | ブルーフラッグ (Iris-Versicolour) | バージニカ (Iris-Virginica) |
![]() | ![]() | ![]() |
(C) Malcolm Manners - CC BY 2.0 | (C) Maja Dumat - CC BY 2.0 | (C) Frank Mayfield - CC BY-SA 2.0 |
#準備(すべてに共通) # PandasとNumpyをインポート import pandas as pd import numpy as np # 日本語化Matplotlibもインポート import matplotlib.pyplot as plt !pip install japanize-matplotlib import japanize_matplotlib # Seabornもインポート import seaborn as sns # pickleをインポート(モデルの保存用) import pickle
#アヤメデータの取得 iris_data = pd.read_csv("https://www2.cmds.kobe-u.ac.jp/~masa-n/dshandson/iris-sample.csv") #確認 iris_data
iris_data.shape
iris_data.describe()
iris_data["品種"].value_counts()
#Seabornのペアプロットを使う sns.pairplot(data=iris_data, hue="品種")
#Pandasにも機能がある.ただし,色分けするのに手間なので,Seabornを使おう pd.plotting.scatter_matrix(iris_data)
#特徴に使う列名リスト features = ["がくの長さ", "がくの幅", "花びらの長さ", "花びらの幅"] #正解データに使う列名 target = ["品種"] X = data[features] y = data[target] from sklearn import tree #決定木による分類モデルの構築 model = tree.DecisionTreeClassifier(random_state = 0, max_depth=3) model.fit(X,y)
#未知のデータで予測してみる new_data = pd.DataFrame([[4.8, 3.3, 1.4, 0.2],[7.3, 3.2, 4.4, 1.3],[5.5, 2.6, 5.5, 2.7] ], columns=features) new_data
#予測してみる model.predict(new_data)
#ユーザから入力を受け付けて,答えを出すプログラム print("■アヤメの品種予測アプリ") while True: input_str = input("がくの長さ・幅,花びらの長さ・幅を入力(0で終了):") if (len(input_str) == "0"): break vals = np.array(input_str.split()).astype(float) if (len(vals) != 4): print(" ×エラー:4つの数値が必要です.やり直し") continue df_params = pd.DataFrame([vals], columns=features) print(f" ○AI:品種は{model.predict(df_params)[0]}と思われます") print("終了します")
tree.plot_tree(model, feature_names=X.columns)
→ モデルの評価 が必要
#X, yのそれぞれを訓練データとテストデータに分ける (訓練:テスト=2:1) from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) #それぞれ確認してみる print(X_train, X_test, y_train, y_test)
model.fit(X_train, y_train)
acc = model.score(X_test, y_test) print(f"分類精度: {acc}")
#実際にあっているかどうかを評価 y_eval = pd.DataFrame() #空のデータフレームを作成 y_eval["正解"] = y_test["品種"] #正解はテストデータにある品種 y_eval["予測"] = model.predict(X_test) #予測はモデルが予測した品種 y_eval["結果"] = y_eval["正解"] == y_eval["予測"] #予測と正解が合致したかどうか
#混同行列を表示する from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay cm = confusion_matrix(y_test, model.predict(X_test)) disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=model.classes_) disp.plot()
import pickle with open("フォルダのパス名/保存ファイル名", "wb") as f pickle.dump(model, f)
import pickle with open("フォルダのパス名/保存ファイル名", "rb") as f model = pickle.load(f) #以降,アプリでmodelを利用する
################### ライブラリのインポート ######################### #いつものPandasとNumPyをインポート import pandas as pd import numpy as np #日本語化MatplotLib import matplotlib.pyplot as plt !pip install japanize-matplotlib import japanize_matplotlib # Seabornをインポート import seaborn as sns # Pickleをインポート import pickle
########################### データの取得 ############################ #アヤメデータの取得 iris_data = pd.read_csv("https://www2.cmds.kobe-u.ac.jp/~masa-n/dshandson/iris-sample.csv")
ここでは省略.様々な角度から,データを眺めてみる(探索的データ分析:次回)
############################## 前処理 ################################ #特徴量に指定する列名リスト features = ["がくの長さ", "がくの幅", "花びらの長さ", "花びらの幅"] # 正解データに指定する列名 target = ["品種"] #特徴量 X = iris_data[features] #正解データ y = iris_data[target] #X, yのそれぞれを訓練データとテストデータに分ける (訓練:テスト=2:1) from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0)
###################### モデルの選択と学習 ############################# #モデルの選択 from sklearn import tree model = tree.DecisionTreeClassifier(max_depth=3, random_state=0) #モデルの学習(訓練データを使う) model.fit(X_train, y_train) #モデルの表示(オプショナル) tree.plot_tree(model, feature_names=X.columns) plt.show()
########################### モデルの評価 ############################### #分類精度 acc = model.score(X_test, y_test) print(f"分類精度: {acc}") #実際にあっているかどうかを確認してみる (オプショナル) y_eval = pd.DataFrame() y_eval["正解"] = y_test["品種"] y_eval["予測"] = model.predict(X_test) y_eval["結果"] = (y_eval["正解"] == y_eval["予測"]) print(y_eval) #混同行列を表示する (オプショナル) from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay cm = confusion_matrix(y_test, model.predict(X_test)) disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=model.classes_) disp.plot()
with open("/content/drive/MyDrive/フォルダ名/ファイル名.pkl", "wb") as f: pickle.dump(model, f)
################### ライブラリのインポート ######################### #いつものPandasとNumPyをインポート import pandas as pd import numpy as np #日本語化MatplotLib import matplotlib.pyplot as plt !pip install japanize-matplotlib import japanize_matplotlib # Seabornをインポート import seaborn as sns # Pickleをインポート import pickle ########################### データの取得 ############################ #アヤメデータの取得.個体番号をあらかじめインデクスにセット iris_data = pd.read_csv("https://www2.cmds.kobe-u.ac.jp/~masa-n/dshandson/iris-sample.csv", index_col="個体番号") #確認 iris_data
############################## 前処理 ################################ #特徴量に指定する列名リスト features = ["品種", "がくの長さ", "がくの幅"] # 正解データに指定する列名 target = ["花びらの長さ"] #特徴量 X = iris_data[features] #正解データ y = iris_data[target] #X, yのそれぞれを訓練データとテストデータに分ける (訓練:テスト=2:1) from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) ###################### モデルの選択と学習 ############################# #モデルの選択(今回は線形回帰モデルを使用する) from sklearn import linear_model model = linear_model.LinearRegression() #モデルの学習(訓練データを使う) model.fit(X_train, y_train)
ValueError: could not convert string to float: 'Iris-versicolor'
pd.get_dummies(data=iris_data, columns=["品種"], drop_first=True )
############################## 前処理 ################################ #ダミー変数化 iris_dummy = pd.get_dummies(data=iris_data, columns=["品種"], drop_first=True) #特徴量に指定する列名リスト(ダミー変数化した後のデータから列名を選ぶ) features = ["品種_Iris-versicolor", "品種_Iris-virginica", "がくの長さ", "がくの幅"] # 正解データに指定する列名 target = ["花びらの長さ"] #特徴量 X = iris_dummy[features] #正解データ y = iris_dummy[target] #X, yのそれぞれを訓練データとテストデータに分ける (訓練:テスト=2:1) from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) ###################### モデルの選択と学習 ############################# #モデルの選択(今回は線形回帰モデルを使用する) from sklearn import linear_model model = linear_model.LinearRegression() #モデルの学習(訓練データを使う) model.fit(X_train, y_train)
########################### モデルの評価 ############################### #回帰の決定係数 r2 = model.score(X_test, y_test) print(f"【決定係数】 {r2}") #実際にあっているかどうかを確認してみる (オプショナル) y_eval = pd.DataFrame() y_eval["正解"] = y_test[target] y_eval["予測"] = model.predict(X_test)
#数値の予測なので,正解と予測値の差(誤差)でモデルの良しあしを評価する #引き算した結果1つ1つに絶対値absを適用している y_eval["誤差"] = (y_eval["正解"] - y_eval["予測"]).apply(abs) print(y_eval)
print(f"【平均絶対誤差(MAE)】{y_eval['誤差'].mean()}") #予測値と正解値を散布図にプロットしてみる y_eval.plot.scatter(x="予測", y="正解") #plt.show() #同じことを行うライブラリがある from sklearn.metrics import PredictionErrorDisplay, mean_absolute_error disp = PredictionErrorDisplay(y_true = y_eval["正解"], y_pred= y_eval["予測"]) #実際値 vs 予測値 散布図 disp.plot(kind="actual_vs_predicted") #残差 vs 予測 散布図 disp.plot() #MAEを求める mae = mean_absolute_error(y_true = y_eval['正解'], y_pred= y_eval['予測']) print(f"【平均絶対誤差(MAE)】{mae}")
線形回帰モデルは,与えられた X=(x1,x2,...,xn) と y から,
y^ = w0 + w1 * x1 + w2 * x2 + ... + wn * xn
かつ,y^とyがなるべく近くなるような,w0,w1,...,wnを見つける.ここで wiは,
と呼ばれる.今回のモデルのそれぞれの値を求めると,
print(f"【切片】{model.intercept_}") print(f"【偏回帰係数】{model.coef_}") print(f"【特徴量名】{model.feature_names_in_}")
データフレームに入れて見やすくする
m_exp = pd.DataFrame() m_exp.index = ["切片"] + model.feature_names_in_.tolist() m_exp["重み"] = [model.intercept_[0]] + model.coef_[0].tolist() m_exp
すなわち,花びらの長さを以下の式で説明しようとしている
花びらの長さ (cm) = -1.531962 + 2.018762 * 品種_Iris_versicolor + 2.916333 * 品種_Iris-virginica + 0.699632 * がくの長さ - 0.140591 * がくの幅
wiの求め方には最小二乗法が良く知られている.
ユーザから品種とがくの長さ,幅を受け取って,花びらの長さを推定するアプリケーションを作ってみよう.
# アヤメの花びらの長さを推定する単純なアプリケーション print("■アヤメの花びらの長さ推定アプリ Ver0.1") while True: #品種の入力 input_str = input("○品種を入力(0:ヒオウギ, 1:ブルーフラッグ, 2:バージニカ, 9:終了 )") #ダミー変数への割り当て if (input_str=="0"): (versicolor, virginica) = (0,0) elif (input_str=="1"): (versicolor, virginica) = (1,0) elif (input_str=="2"): (versicolor, virginica) = (0,1) elif (input_str=="9"): break else: print("番号が不正です.やり直し") continue input_str2 = input("○がくの長さと幅を入力:") #データを取得し,小数型へ params = np.array(input_str2.split()).astype(float) #個数が足りない場合はやり直し if len(params) != 2 : print("2つのデータがありません.やり直し") continue #データをデータフレームに入れて,予測する df_tmp = pd.DataFrame([[versicolor, virginica, params[0], params[1]]], columns=X.columns) pred = model.predict(df_tmp) #結果を表示 print(f"このアヤメの花びらの長さは,推定{pred[0]}cm です.") print("終了しました")
[添付]
図12: 教師あり機械学習モデルの開発プロセス