ここでは、「どのパラメータが打率等にどれくらい関係するのか」を理解することで強いチームを作る指針を記載しておきます。
機械学習(重回帰分析)を使って本気で遊んでます。
実際のデータセットはこちら
野手データ 2018.12.17.csv
投手データ 2018.12.17.csv
*公平を期すために使用したデータセットを公開しています
計:146141打席
多くなりましたね。
結果
野手編
打率(AVE)、出塁率(OBP)、長打率(SLG)、OPS(OPS)
に対し・・・ミート(MT)、パワー(PW)、走力(SP)、肩力(SF)、守備力(DF)、反応速度(SS)が相関しています。

とはいえ、速球投手が全然居ないのでミート王者は変わりそうにありませんが。
昔は速球投手が猛威を奮っており、反応高くないと死ぬゲームでした。
投手編
防御率(ERA)、WHIP
に対し・・・コントロールが高ければ高いほど、ERAとWHIPは落ちる傾向。
速球とスタミナがあるとERAとWHIPが上がる・・・だと?

相手投手との相関性を全く考えていないデータなので、水物ではあります。日々変化しそう。
守備もデータ取ってないから説明できないのが悲しいところですね。
詳細分析
AVE

平均: 0.22
中央値: 0.22
分散: 0.01
標準偏差: 0.12
OPS

平均: 0.63
中央値: 0.64
分散: 0.08
標準偏差: 0.29
ERA(防御率)

平均: 4.20
中央値: 3.91
分散: 18.28
標準偏差: 4.28
・・・こいつだけエラいばらばらやな?
WHIP

平均: 0.46
中央値: 0.50
分散: 0.09
標準偏差: 0.30
※注意:各選手の結果をリスト化して、単純に平均、中央値等を出しているだけなので、投球回数等は反映されていないデータです。ご注意ください。
分析スクリプト
コマンドプロンプトでpython他をインストールしてみてください。
グラフの出力は100行目くらいにある
sys.exit()
をコメントアウトしてくださいませ。
投手用
# -*- coding: utf-8 -*-
import os, sys, csv
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 基礎設定
file_name = 'meisyo_p 20181217.csv'
# CSV読み込み
df = pd.read_csv(file_name, encoding='utf-8')
# Null値を把握
# print(df.isnull().sum())
# 基礎設定
team = pd.DataFrame(index=[], columns=[])
# 投手能力結合・削除
for i in ['sp', 'co', 'st', 'bb1n', 'bb2n', 'bb3n']:
df['p_'+i] = df['p_'+i] + df['pt_p_'+i] + df['pw_p_'+i]
df = df.drop(['pt_p_'+i, 'pw_p_'+i], axis=1)
#for i in ['bb1', 'bb2', 'bb3', 'bb0k', 'bb1k', 'bb2k', 'bb3k']:
# df = df.drop(['p_'+i], axis=1)
# 野手能力結合・削除
for i in ['mt', 'pw', 'sp', 'sf', 'df', 'er', 'ss']:
df['b_'+i] = df['b_'+i] + df['pt_b_'+i] + df['pw_b_'+i]
df = df.drop(['b_'+i, 'pt_b_'+i, 'pw_b_'+i], axis=1)
team = df
# 不必要品削除
df = df.drop(['mn_id', 'name', 'side_p', 'type', 'type_p', 'hp', 'cond', 'cond_b', 'img', 'exp', 'time', 'skill', 'game.1', 'id.1', 'g_bench', 'g_pos', 'g_sb', 'game', 'pc_type', 'bt_type', 'grow_type'], axis=1)
# 欠損値のある行を削除
df = df.dropna()
# 変化球(チェンジアップ=0)ありか
df['p_bb'] = 0
if df['p_bb1'].empty or df['p_bb2'].empty or df['p_bb3'].empty:
df['p_bb'] = 1
# データセット
df = df.drop(['type_b', 'side_b', 'lv'], axis=1)
df = df.drop(['p_bb1', 'p_bb2', 'p_bb3'], axis=1)
# データ確認
#print(df.isnull().sum())
# 結果データ作成
rs = pd.DataFrame(index=[], columns=[])
rs['id'] = df['id']
rs['era'] = (df['er'] * 9) / (df['ip'] / 3)
rs['whip'] = (df['h'] + df['bb']) / (df['ip'])
# 結果削除(結果に直接相関する)
df = df.drop(['pa', 'ab', 'h', 'risp_b', 'risp_h', '1b', '2b', '3b', 'hr', 'tb', 'sh', 'sf', 'bb', 'hbp', 'so', 'e_er'], axis=1)
df = df.drop(['er', 'r', 'ip', 'wp', 'win', 'lose', 'save', 'cg', 'sho', 'gs'], axis=1)
# データ欠損値の埋め合わせ
rs = rs.fillna(0)
# データ設定
x_col = df.drop('id', axis=1)
x = x_col.values
y_era = rs.values[:, 1]
y_whip = rs.values[:, 2]
#必要なパッケージのインポート
from sklearn import linear_model
model_era = linear_model.LinearRegression()
model_whip = linear_model.LinearRegression()
# 学習する
model_era.fit(x, y_era)
model_whip.fit(x, y_whip)
# 偏回帰係数
print("era")
print(pd.DataFrame({"Name":x_col.columns, "Coefficients":model_era.coef_}).sort_values(by='Coefficients') )
print(model_era.intercept_)
print("whip")
print(pd.DataFrame({"Name":x_col.columns, "Coefficients":model_whip.coef_}).sort_values(by='Coefficients') )
print(model_whip.intercept_)
# 相関
myteam = {}
for key, row in team.iterrows():
if row['mn_id'] == 'れい' and row['type'] == 'P':
sum = 0
for i in x_col.columns:
if i is not 'p_bb':
sum += row[i]
myteam[row['name']] = '{:.0f}'.format(sum);
for k, v in sorted(myteam.items(), key=lambda x: x[1]):
print(str(k) + ": " + str(v))
# stop
sys.exit()
# グラフ用
y_eraV = ['{:.2f}'.format(n) for n in y_era]
y_whipV = ['{:.2f}'.format(n) for n in y_whip]
# plot
data = y_whipV
import collections
list = collections.Counter(data)
x = np.arange(200) / 100
values = []
for i in x:
i = '{:.2f}'.format(i)
print(str(i) + ":" + str(list[i]))
if list[i]:
values.append(list[i])
else:
values.append(0)
values[0]=0 # 0を無視
# 計算
from statistics import mean, median,variance,stdev
print(data)
data = [float(s) for s in data]
m = mean(data)
median = median(data)
variance = variance(data)
stdev = stdev(data)
print('平均: {0:.2f}'.format(m))
print('中央値: {0:.2f}'.format(median))
print('分散: {0:.2f}'.format(variance))
print('標準偏差: {0:.2f}'.format(stdev))
plt.bar(x, values, width=0.1)
plt.xlabel("result")
plt.ylabel("num")
plt.show()
野手用
# -*- coding: utf-8 -*-
import os, sys, csv
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 基礎設定
file_name = 'meisyo_b 20181217.csv'
# CSV読み込み
df = pd.read_csv(file_name, encoding='utf-8')
# Null値を把握
# print(df.isnull().sum())
# 基礎設定
team = pd.DataFrame(index=[], columns=[])
# 投手能力結合・削除
for i in ['sp', 'co', 'st', 'bb1n', 'bb2n', 'bb3n']:
# df['p_'+i] = df['p_'+i] + df['pt_p_'+i] + df['pw_p_'+i]
df = df.drop(['pt_p_'+i, 'pw_p_'+i], axis=1)
for i in ['bb1', 'bb2', 'bb3', 'bb0k', 'bb1k', 'bb2k', 'bb3k']:
df = df.drop(['p_'+i], axis=1)
# 野手能力結合・削除
for i in ['mt', 'pw', 'sp', 'sf', 'df', 'er', 'ss']:
df['b_'+i] = df['b_'+i] + df['pt_b_'+i] + df['pw_b_'+i]
# df = df.drop(['b_'+i, 'pt_b_'+i, 'pw_b_'+i], axis=1)
team = df
# 不必要品削除
df = df.drop(['mn_id', 'name', 'side_p', 'type', 'type_p', 'hp', 'cond', 'cond_b', 'img', 'exp', 'time', 'skill', 'game.1', 'id.1', 'g_bench', 'g_pos', 'g_sb', 'game', 'pc_type', 'bt_type', 'grow_type'], axis=1)
# 欠損値のある行を削除
df = df.dropna()
# 不必要分削除
df = df.drop(['type_b', 'side_b', 'lv'], axis=1)
df = df.drop(['b_er'], axis=1)
# データ確認
#print(df.isnull().sum())
# 結果データ作成
rs = pd.DataFrame(index=[], columns=[])
rs['id'] = df['id']
rs['ave'] = df['h'] / df['ab']
rs['obp'] = (df['h'] + df['bb'] + df['hbp']) / (df['ab'] + df['bb'] + df['hbp'] + df['sf'])
rs['slg'] = df['tb'] / df['ab']
rs['ops'] = rs['obp'] + rs['slg']
# 野手結果削除(結果に直接相関する)
df = df.drop(['pa', 'ab', 'h', 'risp_b', 'risp_h', '1b', '2b', '3b', 'hr', 'tb', 'rbi', 'rs', 'sh', 'sf', 'bb', 'hbp', 'so', 'dp', 'e_er', 'tc', 'm_er', 'sb', 'cb', 'c_sb', 'c_cs'], axis=1)
# データ欠損値の埋め合わせ
rs = rs.fillna(0)
# データ設定
x_col = df.drop('id', axis=1)
x = x_col.values
y_ave = rs.values[:, 1]
y_obp = rs.values[:, 2]
y_slg = rs.values[:, 3]
y_ops = rs.values[:, 4]
print(df.isnull().any())
print(rs.isnull().any())
#必要なパッケージのインポート
from sklearn import linear_model
model_ave = linear_model.LinearRegression()
model_obp = linear_model.LinearRegression()
model_slg = linear_model.LinearRegression()
model_ops = linear_model.LinearRegression()
# 学習する
model_ave.fit(x, y_ave)
model_obp.fit(x, y_obp)
model_slg.fit(x, y_slg)
model_ops.fit(x, y_ops)
# 偏回帰係数
print("ave")
print(pd.DataFrame({"Name":x_col.columns, "Coefficients":model_ave.coef_}).sort_values(by='Coefficients') )
print(model_ave.intercept_)
print("obp")
print(pd.DataFrame({"Name":x_col.columns, "Coefficients":model_obp.coef_}).sort_values(by='Coefficients') )
print(model_obp.intercept_)
print("slg")
print(pd.DataFrame({"Name":x_col.columns, "Coefficients":model_slg.coef_}).sort_values(by='Coefficients') )
print(model_slg.intercept_)
print("ops")
print(pd.DataFrame({"Name":x_col.columns, "Coefficients":model_ops.coef_}).sort_values(by='Coefficients') )
print(model_ops.intercept_)
# 結果表示
print(x_col.columns)
print(model_ops.coef_)
# 相関図
myteam = {}
for key, row in team.iterrows():
if row['mn_id'] == 'れい' and row['type'] == 'B':
sum = 0
for i in x_col.columns:
sum += row[i]
myteam[row['name']] = '{:.0f}'.format(sum);
for k, v in sorted(myteam.items(), key=lambda x: x[1]):
print(str(k) + ": " + str(v))
# stop
sys.exit()
# グラフ用
y_aveV = ['{:.2f}'.format(n) for n in y_ave]
y_obpV = ['{:.2f}'.format(n) for n in y_obp]
y_slgV = ['{:.2f}'.format(n) for n in y_slg]
y_opsV = ['{:.2f}'.format(n) for n in y_ops]
# plot
data = y_aveV
import collections
list = collections.Counter(data)
x = np.arange(100) / 100
values = []
for i in x:
i = '{:.2f}'.format(i)
print(str(i) + ":" + str(list[i]))
if list[i]:
values.append(list[i])
else:
values.append(0)
values[0]=0 # 0を無視
# 計算
from statistics import mean, median,variance,stdev
print(data)
data = [float(s) for s in data]
m = mean(data)
median = median(data)
variance = variance(data)
stdev = stdev(data)
print('平均: {0:.2f}'.format(m))
print('中央値: {0:.2f}'.format(median))
print('分散: {0:.2f}'.format(variance))
print('標準偏差: {0:.2f}'.format(stdev))
plt.bar(x, values, width=0.1)
plt.xlabel("result")
plt.ylabel("num")
plt.show()

[…] [Meisyo]ビッグデータから学ぶ試合の基礎設計4から早4か月。 「球速の上方修正してほしいな」というコメントが届きました。 […]