
ゆうき( @BASEBALLY15 )です^^
プロ野球選手って,お金持ちのイメージがあるけれど,全員,そうなの・・・?
どうなんでしょうか?
実際に,検証してみましょう^^
今回は,プロ野球選手の中で,年俸が1億円を超えている人と,そうでない人にはどのような関係があるのかを
『ロジスティック回帰』検証してみます.
検証してみると,年功序列なのか?と一瞬疑ってしまいました.

目次
プロ野球選手って,みんな稼いでるんじゃないの?
プロ野球選手と聞くと,有名でお給料も高いのでは?と感じるのではないでしょうか.
子どもからも人気があり,なりたい職業ランキングでもに上位にくるほどです!
さらに,選手名鑑やサイトを見てみると,1億円プレイヤーどころか,2億,3億円プレイヤーまで存在します.
そこで,今回は,ロジスティック回帰を使って,年俸が高い選手には,どのような関係があるのかを分析してみました.
ロジスティック回帰とは?
ロジスティック回帰とは,簡単に言うと,ある事柄に対して『はい』か『いいえ』の2択で答えることを言います.
例えば,「私はプロ野球選手になれますか?」という質問に対して,その人の身長・体重・能力などから判断し,
「はい.あなたはプロ野球選手になれます.」と答えることです.
以下の動画がロジスティック回帰について分かりやすく説明されているので,視聴してみてください^^
それでは,Pythonを使って検証してみましょう^^
ロジスティック回帰を使ったデータ分析
使ったデータ
今回のロジスティック回帰で使ったデータは,以下のサイトを参考にしました.
このデータを扱いやすいようにまとめたのが,以下のcsvファイルです.
ダウンロードして使ってみてください.
今回は,年俸上位100人と下位100人のデータを使いました.
それでは,ロジスティック回帰でデータ分析を行っていきましょう^^
まずは,データ分析を行うためのライブラリを用意します.
ライブラリ
import numpy as np
import pandas as pd
from pandas import Series, DataFrame
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style("whitegrid")
%matplotlib inline
そして,ロジスティック回帰を行うためのライブラリと,検証を行うためのライブラリを用意します.
#ロジスティック回帰を行うためのライブラリ
from sklearn.linear_model import LogisticRegression
#学習用とテスト用に分けるためのライブラリ
from sklearn.model_selection import train_test_split
#精度を求めるためのライブラリ
from sklearn.metrics import accuracy_score
コード
ライブラリを用意した後は,csvファイルを読み込みます.
#csvファイルを読み込み
baseball_df = pd.read_csv("a professional baseball player_data.csv")
#実行
baseball_df
すると,このように表示されます.
player’s name | annual salary(yen) | Years (years) | Age (Year) | Height (cm) | Weight (kg) | |
---|---|---|---|---|---|---|
0 | 菅野 智之 | 650000000 | 7 | 30 | 186 | 95 |
1 | 柳田 悠岐 | 570000000 | 9 | 31 | 187 | 91 |
2 | 浅村 栄斗 | 500000000 | 11 | 29 | 182 | 90 |
3 | サファテ | 500000000 | 9 | 38 | 193 | 102 |
4 | 坂本 勇人 | 500000000 | 13 | 31 | 186 | 83 |
… | … | … | … | … | … | … |
195 | 益子 京右 | 4700000 | 1 | 19 | 176 | 87 |
196 | 遠藤 淳志 | 4800000 | 2 | 20 | 184 | 78 |
197 | 卓丸 | 4800000 | 5 | 23 | 180 | 76 |
198 | 鈴木 裕太 | 4800000 | 1 | 19 | 182 | 93 |
199 | 牧 丈一郎 | 4800000 | 2 | 20 | 181 | 87 |
今回は,年俸が1億円を超えているか,そうでないかに分けたいので,
1億円を超えている場合を1,超えていない場合を0としたいと思います.
#1億円以上の時1,それ以外を0とする
def over_1oku(x):
if x>=100000000:
return 1
else:
return 0
#"1億円以上"という項目を追加
baseball_df["over_1oku"] = baseball_df["annual salary(yen)"].apply(over_1oku)
#実行
baseball_df
すると,このように『over_1oku』という項目が追加されています.
player’s name | annual salary(yen) | Years (years) | Age (Year) | Height (cm) | Weight (kg) | over_1oku | |
---|---|---|---|---|---|---|---|
0 | 菅野 智之 | 650000000 | 7 | 30 | 186 | 95 | 1 |
1 | 柳田 悠岐 | 570000000 | 9 | 31 | 187 | 91 | 1 |
2 | 浅村 栄斗 | 500000000 | 11 | 29 | 182 | 90 | 1 |
3 | サファテ | 500000000 | 9 | 38 | 193 | 102 | 1 |
4 | 坂本 勇人 | 500000000 | 13 | 31 | 186 | 83 | 1 |
… | … | … | … | … | … | … | … |
195 | 益子 京右 | 4700000 | 1 | 19 | 176 | 87 | 0 |
196 | 遠藤 淳志 | 4800000 | 2 | 20 | 184 | 78 | 0 |
197 | 卓丸 | 4800000 | 5 | 23 | 180 | 76 | 0 |
198 | 鈴木 裕太 | 4800000 | 1 | 19 | 182 | 93 | 0 |
199 | 牧 丈一郎 | 4800000 | 2 | 20 | 181 | 87 | 0 |
『 over_1oku 』がどんなデータなのか,見てみましょう.
#データを可視化
baseball_df.groupby("over_1oku").mean()
annual salary(yen) | Years (years) | Age (Year) | Height (cm) | Weight (kg) | |
---|---|---|---|---|---|
over_1oku | |||||
0 | 3140600.0 | 2.38 | 22.25 | 181.08 | 82.65 |
1 | 226421000.0 | 8.63 | 31.98 | 183.48 | 91.00 |
これを見ると,1億円を超えているかどうかは,年齢と年数が影響するのではないか,
ということが推測できますね^^
追記ココから(2020/4/20現在)
このデータをseabornを使って可視化してみます.
#ヒストグラムを描く(年数)
sns.countplot("Years (years)", data=baseball_df.sort_values("Years (years)"), hue="over_1oku")

#ヒストグラムを描く(年齢)
sns.countplot("Age (Year)", data=baseball_df.sort_values("Age (Year)"), hue="over_1oku")

追記ココまで
では,実際にロジスティック回帰を使って,検証してみたいと思います.
ロジスティック回帰で検証してみよう!
まずは,予測に使うデータX(説明変数)と予測したいデータY(目的変数)に分けます.
今回は,1億円を超えているかそうでないかを検証したいので,以下のコードを記述します.
#"player's name"と"annual salary(yen)"と"over_1oku"を取り除いたデータをX(説明変数)
X = baseball_df.drop([ "player's name", "annual salary(yen)", "over_1oku"], axis=1)
#"over_1oku"をY(目的変数)
Y = baseball_df["over_1oku"]
次に,ロジスティック回帰のモデルを用意し,モデルを作成します.
#ロジスティックモデルを準備
baseball_log = LogisticRegression()
#XとYのロジスティックモデルを作成
baseball_log.fit(X, Y)
そして,1億円プレイヤーにはどのような関係があるのかをデータフレームで示したいと思います.
#関係性をデータフレームにする
baseball_coeff_df = DataFrame([X.columns, baseball_log.coef_[0]]).T
#実行
baseball_coeff_df
すると,このように表示されます.
0 | 1 | |
---|---|---|
0 | Years (years) | 0.332022 |
1 | Age (Year) | 0.639506 |
2 | Height (cm) | 0.052844 |
3 | Weight (kg) | 0.0640881 |
この表は,プラスの場合は年俸1億円との関係性が高く,
マイナスの場合は関係性が低いことを示しています.
これを見ると,やはり,『年数』と『年齢』が年俸1億に深く関係していることが分かります.
そして,『身長』と『体重』はあまり年俸と関係がないことが分かります.
プロ野球は,経験がものを言う世界なのでしょうか^^
今回の検証の精度は?
最後に,今回のロジスティック回帰の精度を求めたいと思います.
#学習用とテスト用に分ける
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, shuffle=True)
#ロジスティックモデルを準備
money_log = LogisticRegression()
#XとYのロジスティックモデルを作成
money_log.fit(X_train, Y_train)
#予測する
Y_pred = money_log.predict(X_test)
#精度を表示する
print("精度=", accuracy_score(Y_pred, Y_test))
実行すると,
精度= 0.925
高精度な結果となりました^^
追記(2020/4/20現在)
『標準化』して精度を求めてみよう!(読者からのご提案)
読者の方から,データを『標準化』するとどのような精度になるのか,
というご質問を頂いたので,追記させて頂きました^^
標準化とは?
平均を0,分散を1に変換すること.
引用元:具体例で学ぶ数学
それでは,コードを見ていきましょう⤵
『SciPy』をインポートしよう!
上で紹介したライブラリに加えて,
標準化を行うことが出来る『SciPy』というライブラリをインポートします.
#標準化するためのライブラリを用意
import scipy.stats
『scipy.stats.zscore』で標準化しよう!
まず,全体のデータフレームを表示させておきます.
#データフレームを表示
baseball_df
player’s name | annual salary(yen) | Years (years) | Age (Year) | Height (cm) | Weight (kg) | over_1oku | |
---|---|---|---|---|---|---|---|
0 | 菅野 智之 | 650000000 | 7 | 30 | 186 | 95 | 1 |
1 | 柳田 悠岐 | 570000000 | 9 | 31 | 187 | 91 | 1 |
2 | 浅村 栄斗 | 500000000 | 11 | 29 | 182 | 90 | 1 |
3 | サファテ | 500000000 | 9 | 38 | 193 | 102 | 1 |
4 | 坂本 勇人 | 500000000 | 13 | 31 | 186 | 83 | 1 |
… | … | … | … | … | … | … | … |
195 | 益子 京右 | 4700000 | 1 | 19 | 176 | 87 | 0 |
196 | 遠藤 淳志 | 4800000 | 2 | 20 | 184 | 78 | 0 |
197 | 卓丸 | 4800000 | 5 | 23 | 180 | 76 | 0 |
198 | 鈴木 裕太 | 4800000 | 1 | 19 | 182 | 93 | 0 |
199 | 牧 丈一郎 | 4800000 | 2 | 20 | 181 | 87 | 0 |
それでは,以下のコードを記述し,年数・年齢・身長・体重の値を標準化します.
#標準化
#年数
sta_years = scipy.stats.zscore(baseball_df["Years (years)"], ddof=1)
#年齢
sta_age = scipy.stats.zscore(baseball_df["Age (Year)"], ddof=1)
#身長
sta_height = scipy.stats.zscore(baseball_df["Height (cm)"], ddof=1)
#体重
sta_weight = scipy.stats.zscore(baseball_df["Weight (kg)"], ddof=1)
scipy.stats.zscore関数を使うと,値を標準化することが出来ます.
また,今回使うデータはあくまでも標本集団なので,
『ddof=1』と書くことで,『n-1で割る』標準偏差を使います.
(※母集団の場合は,nで割るが,標本集団の場合は,n-1で割る.)
標準化した値を入れ替えよう!
次に,データフレーム内に,標準化した値を代入します.
#データフレームの値を入れ替える
baseball_df.iloc[:,2] = sta_years
baseball_df.iloc[:,3] = sta_age
baseball_df.iloc[:,4] = sta_height
baseball_df.iloc[:,5] = sta_weight
実行してみましょう^^
#表示
baseball_df
player’s name | annual salary(yen) | Years (years) | Age (Year) | Height (cm) | Weight (kg) | over_1oku | |
---|---|---|---|---|---|---|---|
0 | 菅野 智之 | 650000000 | 0.306322 | 0.491789 | 0.587655 | 0.752107 | 1 |
1 | 柳田 悠岐 | 570000000 | 0.716118 | 0.662254 | 0.745627 | 0.384104 | 1 |
2 | 浅村 栄斗 | 500000000 | 1.125914 | 0.321325 | -0.044232 | 0.292103 | 1 |
3 | サファテ | 500000000 | 0.716118 | 1.855504 | 1.693458 | 1.396114 | 1 |
4 | 坂本 勇人 | 500000000 | 1.535710 | 0.662254 | 0.587655 | -0.351903 | 1 |
… | … | … | … | … | … | … | … |
195 | 益子 京右 | 4700000 | -0.923065 | -1.383318 | -0.992063 | 0.016100 | 0 |
196 | 遠藤 淳志 | 4800000 | -0.718167 | -1.212853 | 0.271712 | -0.811908 | 0 |
197 | 卓丸 | 4800000 | -0.103473 | -0.701461 | -0.360176 | -0.995910 | 0 |
198 | 鈴木 裕太 | 4800000 | -0.923065 | -1.383318 | -0.044232 | 0.568106 | 0 |
199 | 牧 丈一郎 | 4800000 | -0.718167 | -1.212853 | -0.202204 | 0.016100 | 0 |
予測に使うデータ(説明変数)と予測するデータ(目的変数)に分けよう!
次に,説明変数と目的変数に分けて,データフレームで表示します.
#予測に使うデータ(説明変数)と予測するデータ(目的変数)に分ける
X2 = baseball_df.drop([ "player's name", "annual salary(yen)", "over_1oku"], axis=1)
Y2 = baseball_df["over_1oku"]
ロジスティック回帰で精度を求めてみよう!(標準化編)
説明変数と目的変数に分けたデータを,さらに学習用とテスト用に分けます.
#学習用とテスト用に分ける
X2_train, X2_test, Y2_train, Y2_test = train_test_split(X2, Y2, test_size=0.2, shuffle=True)
そして,ロジスティックモデルを使い学習させます.
#ロジスティックモデルを準備する
money_log2 = LogisticRegression()
#学習する
money_log2.fit(X2_train, Y2_train)
それでは,『標準化』することで精度がどのようになるのか見てみましょう⤵
#精度を求める
pre = money_log2.predict(X2_test)
print("精度=", accuracy_score(pre, Y2_test))
精度= 0.975

このように,『標準化』することで,精度が向上しました^^
最後に
今回は,プロ野球選手のデータを使って,ロジスティック回帰分析を行いました.
今後は,他の分野のデータや分析方法を使っていきたいと思います^^
それでは・・・
Q &A
参考資料
https://note.nkmk.me/python-list-ndarray-dataframe-normalize-standardize/