エンジニア データサイエンティスト

Python機械学習「ホームラン数予測⑤」予測編!

2020年12月27日

Python機械学習

 

機械学習をさせて作ったモデルはどれくらい正確に予測してくれるんだろう?
モデル評価のスコアは結構良い感じだったけど、実際はどうだろ?

 

こんにちは、古賀です!

 

本記事は、

はてな

「Python機械学習でホームラン数を予測する」の予測編

です!

 

今回で、この「ホームラン数予測」は最終回です!

 

機械学習をさせてモデルを作成した後は、

実際にそのモデルを使って、予測させてみましょう!

良いモデルが作成できていれば、良い予測結果が出るはずです!

 

今回が最後なので、機械学習の一通りの流れは終わりです!

Pythonの機械学習の基本を学んで、次の勉強に活かしましょう!

 

前回の続きになりますので、

前回の記事を読まれていない方はこちらをご覧ください!

Python機械学習
Python機械学習「ホームラン数予測④」モデル作成・モデル評価編!

  「機械学習させてAIを作る!」ってなんだか難しそう。。 自分のレベルでもできるのかな。。   こんにちは、古賀です!   本記事は、 はてな 「Python機械学習で ...

続きを見る

 

自己紹介が遅れましたが、

わたしは大学卒業後、上場IT企業に就職し、プログラマー、システムエンジニアとして

約10年間働いておりまして、その後は様々な活動をしております。

プロフィールの詳細はこちらです。

野球
プロフィール

こんにちは、古賀正雄です。現在36歳です。 簡単ではありますが、こちらのページで自己紹介とこのブログについてお話します。 高校時代 学生時代は主に野球をしていました。 進学先の高校も野球で選びました。 ...

続きを見る

 

※YouTubeに同内容を公開しております。

Python機械学習「予測」の概要

分析

前回までの動画で、

  1. WEBスクレイピングでデータを収集
  2. データ分析をして「説明変数」と「目的変数」を作成
  3. 11球団のデータを使用して「モデル作成&モデル評価」

をしてきました。

 

今回は、今回の目的のゴールである

「作成したモデルを使って、巨人の選手のホームラン数を予測」

します!

 

前回、評価用データのホームラン数を予測したように、

巨人の選手のデータを渡して、ホームラン数を予測させます。

ですので、コードの内容も前回書いた内容と同じです。

 

具体的な手順は、

  1. 巨人のデータの「説明変数」を作成する
  2. 作成したモデルを使用して、巨人のホームラン数を予測させる
  3. 予測したホームラン数と実際のホームラン数を比較してみる

です!

Python機械学習「予測」をしてみる!

野球場

前回までのコードも含まれていますが、今回のコードは最後の4行分です。

今からこのコードを説明していきます!

# 表形式データを扱うライブラリ
import pandas as pd
# データ分割
from sklearn.model_selection import train_test_split
# モデル作成
from sklearn.linear_model import LinearRegression as LR
# 評価関数
from sklearn.metrics import mean_squared_error as MSE
# 行列計算ライブラリ(機械学習の結果がnumpyで返却される)
import numpy as np

# CSVデータ読み込み
df = pd.read_csv('playerData.csv', sep = ',')

# 巨人以外の11球団データを抽出
df11 = df[df['チーム'] != '巨人']
# 巨人のデータ
df_g = df[df['チーム'] == '巨人']

# 本塁打との相関係数をDataFrameとして変数に保存
df_homerun = pd.DataFrame(df11.corr()['本塁打'])

# 相関係数「0.7」以上の項目名を抽出
X_columns = df_homerun[df_homerun['本塁打'] >= 0.7].index.tolist()
# 本塁打は目的変数のため除外
X_columns.remove('本塁打')

# 説明変数と目的変数をセット
X = df11[X_columns]
y = df11['本塁打']

# データの分割
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 1)

# モデルの箱の準備および学習
lr = LR()
lr.fit(X_train, y_train)

# 予測値の算出
y_pred_test = lr.predict(X_test)

# MSEの算出
mse_test = MSE(y_test, y_pred_test)

# RMSEの算出
rmse_test = np.sqrt(mse_test)

# RMSEの表示
print(rmse_test)

# 巨人データ(説明変数)
X_g = df_g[X_columns]

# 予測ホームラン数の算出
y_pred_g = lr.predict(X_g)

# 予測本塁打列の追加
df_g['予測本塁打'] = np.round(y_pred_g).astype(np.int32)

# 予測値と実際の値との比較結果
print(df_g[['選手名','本塁打','予測本塁打']])

巨人の説明変数を作成する

まずは、ホームラン数を予測するための材料「説明変数」を巨人のデータで作成します。

学習用データの「説明変数」の項目と一致していないと、

予測処理を実行させた時にエラーが発生してしまうので、

学習用データの「説明変数」を作った時と同じように、巨人のデータの「説明変数」も作成します。

# 巨人データ(説明変数)
X_g = df_g[X_columns]

「df_g」の変数には、巨人の選手データが格納されています。

※その過程はこちら記事で解説しています。

Python機械学習
Python機械学習「ホームラン数予測③」データ分析編!

  ホームラン数を予測できるように機械学習させたいけど、 どんな情報を渡せば良いんだろう。。 片っ端から渡して色々と試せばいいんだろうか。。   こんにちは、古賀です! &nbsp ...

続きを見る

 

その巨人のデータから「説明変数」の項目名が配列型で格納されている「X_columns」を指定して、

「説明変数」の項目のみ取り出して、「X_g」にセットしています。

これで巨人の選手の「説明変数」の作成が完了です!

 

中身を確認してみると、

# 巨人の説明変数
print(X_g)

# 結果
 打席数   打数  得点   安打  二塁打   塁打  打点  四球   三振  併殺打
11   500  440  79  121   26  240  97  55   85   10
16   491  423  63  120   31  234  77  63  101    3
20   479  412  64  119   28  206  65  62   85    9
49   389  354  47   97   16  141  32  30   60    6
64   313  278  42   73   11  103  19  29   71    4
65   312  279  19   83   13  117  29  31   59   11
70   308  274  30   74   10  113  41  30   82    1
75   288  263  26   65    9  110  36  22   47    6
126  159  146  22   36    6   50  14   8   32    6
129  156  141  21   36    7   49  17  11   21    3
132  154  146  14   39    3   56  13   8   35    6
145  114  100   4   18    2   23   7   8   23    3
158   96   90  17   23    5   33   6   6   33    1
167   88   75   9   17    2   25  10  10   24    2
176   78   68   7   18    2   25   6   8   15    0
178   77   63  12   15    1   19   6   9   21    1
210   48   37  30   11    2   13   2  11   12    1
211   48   43   2   13    3   19   5   3   16    4
212   47   45   2   11    1   18   7   2   12    1
238   27   23   5    6    0   11   4   4    6    1
248   21   18   1    1    0    1   0   0    4    0
250   20   18   0    3    0    3   0   2    8    0
274   12   10   1    1    0    1   0   1    2    0
280   11    9   3    2    0    5   4   2    3    0
285    9    7   3    0    0    0   0   1    3    0
286    9    9   0    0    0    0   0   0    2    1
326    1    1   0    0    0    0   0   0    1    0

説明変数の項目だけ取り出せていることが確認できます。

 

おさらいですが、この項目は「ホームラン数との相関係数が0.7以上」の項目です。

この項目から「ホームラン数」を予測できるように、モデルを作成してきました。

「チーム名」や「選手名」が項目にないので、

巨人のデータかどうか判断が付かないかもしれませんが、

「チーム名」や「選手名」はホームラン数を予測するための材料ではないので、

除外されているのが正解です!

モデルに巨人のホームラン数を予測させる

「説明変数」を作成したら、機械学習モデルに渡して「ホームラン数」を予測してもらいます。

この処理は前回「評価用」データを使って「ホームラン数」を予測した時の処理と同じです。

「predict」関数に「説明変数」を渡すだけです。

# 予測ホームラン数の算出
y_pred_g = lr.predict(X_g)

予測した結果を「y_pred_g」に格納しています。

 

この「y_pred_g」の中身を確認してみると、

# 巨人の選手の予測ホームラン数
print(y_pred_g)

# 結果
[ 3.03649782e+01  2.58365917e+01  1.86877379e+01  7.81516555e+00
  4.85751026e+00  6.25010037e+00  8.18228025e+00  1.12004516e+01
  2.49942288e+00  1.84167971e+00  4.16257778e+00  8.26275391e-01
  1.19097672e+00  1.87673228e+00  1.25447360e+00  7.48982976e-01
  1.60781695e-01  1.06783859e+00  1.85258636e+00  1.67598326e+00
 -5.88513415e-02 -9.46117004e-02  1.25350398e-03  1.06725505e+00
  3.90698297e-02  1.34692065e-01  3.55937892e-02]

こんな感じになっています。

各選手の予測ホームラン数が一覧で表示されています。

「e+01」や「e-01」という表示がありますが、これは「10の何乗」であるかを表しています。

「3.03649782e+01」であれば、「30.36」本ということになります。

 

ただこれだと、かなり見づらいですね。。

ちょっと見やすくなるように改善してみましょう!

小数点以下を四捨五入してみます。

「Numpyのndarray型」の各要素を四捨五入したい場合は、「np.round」関数を使います。

# 予測ホームラン数を四捨五入
print(np.round(y_pred_g))

# 結果
[30. 26. 19.  8.  5.  6.  8. 11.  2.  2.  4.  1.  1.  2.  1.  1.  0.  1.
  2.  2. -0. -0.  0.  1.  0.  0.  0.]

これで大分見やすくなりましたが、「小数点」と「-」が気になるので、

これも消していきましょう。

 

1つ1つの要素を整数型である「int型」に変換します。

要素に対して変換をする場合は、「astype(変換したいデータ型)」関数を使います。

「int(変数)」では要素に対して変換が行われないので注意が必要です!

「int(変数)」では、ndarrayをintに変換しようとして、エラーが発生してしまいます。

# 予測ホームラン数を四捨五入してintに変換
print(np.round(y_pred_g).astype(np.int32))

# 結果
[30 26 19  8  5  6  8 11  2  2  4  1  1  2  1  1  0  1  2  2  0  0  0  1
  0  0  0]

これでホームラン数が綺麗に確認できるようになりました!

予測したホームラン数と実際のホームラン数を比較

最後に「予測したホームラン数」と「実際のホームラン数」を比較してみましょう。

前回と同じように、評価関数を使って比較しても良いのですが、

評価関数の値を確認してもいまいちピンとこないと思うので、

今回は直接「予測したホームラン数」と「実際のホームラン数」を、

横並びで確認してみたいと思います!

 

やることは簡単です。

まずは、巨人のデータが格納されている「df_g」に「予測したホームラン数」を追加します。

「Dataframe」の変数「df_g」に列追加したい場合は、

「Dataframe[追加したい項目名]=セットしたい値」

とすれば、新しい列が追加できます。

# 予測本塁打列の追加
df_g['予測本塁打'] = np.round(y_pred_g).astype(np.int32)

セットしたい値は、先程「予測したホームラン数」を綺麗にした値です。

これで巨人の選手データに「予測本塁打」の列が追加されています。

 

最後に「選手名」、「本塁打」、「予測本塁打」を指定して、データを確認してみましょう!

# 予測値と実際の値との比較結果
print(df_g[['選手名','本塁打','予測本塁打']])

# 結果
 選手名  本塁打  予測本塁打
11    岡本 和真   31     30
16    丸 佳浩     27     26
20    坂本 勇人   19     19
49    吉川 尚輝    8      8
64    松原 聖弥    3      5
65    中島 宏之    7      6
70    大城 卓三    9      8
75    ウィーラー   12     11
126   若林 晃弘    2      2
129   亀井 善行    2      2
132   パーラ        4      4
145   炭谷 銀仁朗  1      1
158   重信 慎之介  1      1
167   北村 拓己    2      2
176   田中 俊太    1      1
178   陽 岱鋼      1      1
210   増田 大輝    0      0
211   岸田 行倫    1      1
212   石川 慎吾    2      2
238   立岡 宗一郎  1      2
248   小林 誠司    0      0
250   ウレーニャ    0      0
274   吉川 大幾    0      0
280   モタ          1      1
285   湯浅 大      0      0
286   香月 一也    0      0
326   加藤 脩平    0      0

各選手のホームラン数を見てみると、1、2本の誤差がある選手もいますが、

大体正確に予測ができていると思います!

 

5回に分けて説明してきましたが、

このようにデータを機械に読み込ませて、機械学習モデルを作成することで、

「説明変数」を渡すだけで、「目的変数」を求めることができるようになります!

 

最後に今回のコード全体をもう一度見てみましょう!

# 表形式データを扱うライブラリ
import pandas as pd
# データ分割
from sklearn.model_selection import train_test_split
# モデル作成
from sklearn.linear_model import LinearRegression as LR
# 評価関数
from sklearn.metrics import mean_squared_error as MSE
# 行列計算ライブラリ(機械学習の結果がnumpyで返却される)
import numpy as np

# CSVデータ読み込み
df = pd.read_csv('playerData.csv', sep = ',')

# 巨人以外の11球団データを抽出
df11 = df[df['チーム'] != '巨人']
# 巨人のデータ
df_g = df[df['チーム'] == '巨人']

# 本塁打との相関係数をDataFrameとして変数に保存
df_homerun = pd.DataFrame(df11.corr()['本塁打'])

# 相関係数「0.7」以上の項目名を抽出
X_columns = df_homerun[df_homerun['本塁打'] >= 0.7].index.tolist()
# 本塁打は目的変数のため除外
X_columns.remove('本塁打')

# 説明変数と目的変数をセット
X = df11[X_columns]
y = df11['本塁打']

# データの分割
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 1)

# モデルの箱の準備および学習
lr = LR()
lr.fit(X_train, y_train)

# 予測値の算出
y_pred_test = lr.predict(X_test)

# MSEの算出
mse_test = MSE(y_test, y_pred_test)

# RMSEの算出
rmse_test = np.sqrt(mse_test)

# RMSEの表示
print(rmse_test)

# 巨人データ(説明変数)
X_g = df_g[X_columns]

# 予測ホームラン数の算出
y_pred_g = lr.predict(X_g)

# 予測本塁打列の追加
df_g['予測本塁打'] = np.round(y_pred_g).astype(np.int32)

# 予測値と実際の値との比較結果
print(df_g[['選手名','本塁打','予測本塁打']])

おまけ

少しだけおまけです。

今回はホームラン数を相関が強い項目を説明変数として、モデルを作成しました。

野球に詳しい方であれば、お気づきでしょうが、

野球の「塁打」という項目は、

「塁打」=4×「本塁打」+3×「三塁打」+2×「二塁打」+「単打」

という式で求めることができます。

なので、「本塁打」を求めたければ、

相関の強さに関係なく、「塁打」、「三塁打」、「二塁打」、「単打」を渡せば、

正確に「ホームラン数」を求めることができるはずです。

ただ今回データの中に「単打」の項目がないので、代わりに「安打」を渡してみます。

※「単打」はシングルヒット数、「安打」はホームランを含んだ全ヒット数です。

# 「安打、二塁打、三塁打、塁打」を説明変数にする
X_columns = ['安打','二塁打','三塁打','塁打']

 

これで再度機械学習をさせて「ホームラン数」を予測してみると、

# RMSEの表示
print(rmse_test)

# 予測値と実際の値との比較結果
print(df_g[['選手名','本塁打','予測本塁打']])

# 結果
4.897912368638467e-15

        選手名  本塁打  予測本塁打
11    岡本 和真   31     31
16     丸 佳浩   27     27
20    坂本 勇人   19     19
49    吉川 尚輝    8      8
64    松原 聖弥    3      3
65    中島 宏之    7      7
70    大城 卓三    9      9
75    ウィーラー   12     12
126   若林 晃弘    2      2
129   亀井 善行    2      2
132     パーラ    4      4
145  炭谷 銀仁朗    1      1
158  重信 慎之介    1      1
167   北村 拓己    2      2
176   田中 俊太    1      1
178    陽 岱鋼    1      1
210   増田 大輝    0      0
211   岸田 行倫    1      1
212   石川 慎吾    2      2
238  立岡 宗一郎    1      1
248   小林 誠司    0      0
250   ウレーニャ    0      0
274   吉川 大幾    0      0
280      モタ    1      1
285    湯浅 大    0      0
286   香月 一也    0      0
326   加藤 脩平    0      0

評価関数「RMSE」の値は「4.897912368638467e-15」でほぼ「0」です。

「予測したホームラン数」と「実際のホームラン数」の値も完全一致しています。

 

このように「Pythonの知識」や「機械学習の知識」、「データ分析力」も必要ですが、

目的の値を正しく予測するためには、「取り組む課題自体の知識」も非常に重要になります!

まとめ:Python機械学習「予測」

ここまでの話をまとめます。

まとめ

今回は作成したモデルを使用して「予測したホームラン数」と「実際のホームラン数」を比較した!

今回やったことは、

  1. 巨人のデータの「説明変数」を作成した
  2. 作成したモデルを使用して、巨人のホームラン数を予測させた
  3. 予測したホームラン数と実際のホームラン数を比較した

1、2本の誤差はあったものの、ホームラン数を精度高く予測することができた!

 

全5回に分けて「Python機械学習」について、説明してきました。

今回の内容は機械学習の基本的な部分です。

 

ところどころ何やっているのか、わからなくなってしまった方は、

「概要編」を振り返ってみてください。

Python機械学習
Python機械学習「ホームラン数予測①」概要編!

  PythonってAIや機械学習ができるって言うけど、 誰にでもできるんだろうか。。 やっぱり難しいコードを書いたりするんだろうか。。 イメージを掴みたいな。。   こんにちは、 ...

続きを見る

 

全体の流れを再確認することで、機械学習の基本的な流れや、

コードの理解も進むと思います。

 

今回はホームランという「実数」を予測する「回帰問題」であり、

機械学習をさせるためのデータがある「教師あり学習」でした。

 

機械学習の分野には他にも、分類分けをする「分類問題」であったり、

「教師なし学習」ができる「ディープラーニング」の分野もあります。

 

まだまだ奥が深いので、

今回の内容を足掛かりにして、お互いに勉強を進めていきましょう!

おすすめ記事

eSportsプラットフォームSPFans 1

  こんにちは、古賀です!   本記事では、わたしが個人開発したWEBサービス はてな eSportsプラットフォーム「SPFans」 の紹介をします。   以前に紹介し ...

成長するエンジニア 2

  エンジニアになったけど、いまいち成長を感じられないなぁ。。 作業スピードも品質も平凡。 この先成長していけるんだろうか。。   こんにちは、古賀です!   エンジニア ...

道のり 3

※本記事は、各記事のまとめ記事です。   こんにちは、古賀です!   本記事では、 「プログラミング未経験者がエンジニアとして働き、 年収1000万に到達するまでの道のり」 をご説 ...

プログラミングスクール 4

  プログラミングを本格的に勉強して仕事に繋げていきたいけど、 プログラミングスクール多すぎる。。 どういう目線で選べばいいんだ。。   こんにちは、古賀です。   プロ ...

-エンジニア, データサイエンティスト
-, ,

Copyright© Koga Masao's LifeBlog , 2024 All Rights Reserved.