名将と呼ばれた者達、めちゃくちゃソースコードが長い(この記事)
ここでは、「どのパラメータが打率等にどれくらい関係するのか」を理解することで強いチームを作る指針を記載しておきます。
というわけで27-2. 重回帰分析を使っていきます。
この結果(打率)はどの要素(ミート、パワー、走力…etc)が関係してるの?を答える統計解析です。
調べてみたらPHPで重回帰分析があったので使いました。(多分python使ったほうが良さそう。とても重かった・・・。)これをcakePHPに入れて計算してみます。
・・・ただし、これはコピペで動かないので注意。最初は動かなかったので、最終的にソースを整形する作業が必要でした。orz
調査内容
・計算する結果
打率、出塁率、長打率、OPS、各塁打率(各塁打/打数)、HR率(HR/打数)
・要素
定数項(1)、ミート、パワー、走力、肩力、守備力、エラー回避、反応、コントロール(投手)=PC
※定数項あり。コントロール(投手)は陰性対照・・・だよな?
調査方法
View/calc.ctp
<?php
App::uses('MeisyoController', 'Controller');
$ct = new MeisyoController();
$cf = Configure::read("cf");
// Test
App::import('Vendor','Regression');
$mag = 10000;
$total = 0;
// Data
$Y = $X = [];
//$CP_R = $ct->_set_array($ct->Dpp->find('all'), 'Dpp', 'id');
$CB_R = $ct->_set_array($ct->Dpb->find('all'), 'Dpb', 'id');
$i = 0;
foreach($CB_R as $d)
{
// if($i > 1000) break;
if($d['ab'] != 0)
{
// bt
$num0 = $d['h']/$d['ab']; // 打率
$num1 = ($d['h'] + $d['bb'] + $d['hbp']) / ($d['ab'] + $d['bb'] + $d['hbp'] + $d['sf']); // 出塁率
$num2 = $d['tb'] / $d['ab']; // 長打率
$num3 = $num1 + $num2; // OPS
$num4 = $d['1b'] / $d['ab']; // 1b率
$num5 = $d['2b'] / $d['ab']; // 2b率
$num6 = $d['3b'] / $d['ab']; // 3b率
$num7 = $d['hr'] / $d['ab']; // HR率
// 出力
$num = $num7 * $mag;
$total += $d['ab'];
//
if($CD = $ct->_read_data('Card', $d['id']))
{
$Y[] = [$num];
$X[] = [1, $CD['b_mt'], $CD['b_pw'], $CD['b_sp'], $CD['b_sf'], $CD['b_df'], $CD['b_er'], $CD['b_ss'], $CD['p_co']];
$i++;
}
}
}
// 早い処理
// 5000件ずつデータを取得するようにする
//$limit = 5000;
//$params = array('limit' => $limit, 'offset' => 0);
//while ($data = $this->Model->find('all', $params)){
// 何らかの処理
//$params['offset']+= $limit;
//}
//$this->_read_data('Dpp', $CD['id']);
//$this->_read_data('Dpb', $CD['id']);
$reg = new Lib_Regression();
$reg->setX($X);
$reg->setY($Y);
$reg->Compute();
// 出力
echo "Num:" . count($Y) . "<br>";
echo "TotalAb:{$total}<br>";
echo "×:{$mag}<br>";
$Table = ['getCoefficients', 'getStandardError',];
echo "<table>";
foreach ($Table as $array)
{
echo "<tr>";
foreach($reg->$array() as $val)
{
echo "<td>". floor($val * 1000)/1000 ."</td>";
}
echo "</tr>\n";
}
echo "</table>";
// 表示
$List = ['getSSE', 'getSSR', 'getSSTO', 'getRSQUARE', 'getF', 'getRSQUAREPValue', 'getCoefficients', 'getStandardError', 'getTStats', 'getPValues'];
foreach($List as $array)
{
echo "{$array}<pre>";
var_dump($reg->$array());
echo "</pre>";
}
?>
Viewに入れるのは良くないが(‘A`)
調査結果
データ(選手)数:1561
トータル打数:39429
倍率:10000(結果を見えやすくするため)
*SE:標準誤差
関係すると考えられる能力は赤(太)、関係しそうなのは黒(太)、関係しないと考えられる能力は黒で表記します。
判定基準を詳しく言うと、統計学の平均±標準誤差を使用します。
関係すると考えられる能力は赤(太)
説明変数Xiが、Xi±2SEをしても0にならない値となった場合これと判定します。
Xi±2SEは母平均の95%が含まれている。=該当する数値は0にならない可能性が非常に高いと判断できるからです。
関係しそうなのは黒(太)
説明変数Xiが、Xi±SEをしても0にならない値となった場合これと判定します。
Xi±SEは母平均の68%が含まれている。=該当する数値は0にならない可能性が高いと判断できるからです。
関係しないと考えられる能力は黒
それ以外は黒で表示します。「んーこれはXi±SEが0になるから関係ないんじゃね」という感じです。
では結果をば。
| 結果名 |
各 |
ミート |
パワー |
走力 |
肩力 |
守備力 |
E避 |
反応 |
PC |
| 各SE |
SE |
SE |
SE |
SE |
SE |
SE |
SE |
SE |
| 打率 |
298.8 |
34.469 |
7.941 |
8.212 |
-0.302 |
-2.406 |
0.94 |
3.695 |
2.68 |
| 415 |
2.904 |
2.831 |
2.941 |
2.893 |
2.936 |
2.689 |
2.643 |
4.353 |
| 出塁率 |
2331 |
22.17 |
2.895 |
4.454 |
-2.755 |
-5.649 |
-1.016 |
7.432 |
3.729 |
| 447.0 |
3.129 |
3.050 |
3.169 |
3.117 |
3.163 |
2.897 |
2.848 |
4.690 |
| 長打率 |
-1121 |
52.50 |
23.21 |
22.19 |
2.927 |
-0.431 |
3.298 |
8.225 |
5.102 |
| 622.3 |
4.355 |
4.245 |
4.411 |
4.339 |
4.403 |
4.033 |
3.964 |
6.528 |
| OPS |
1209 |
74.68 |
26.11 |
26.65 |
0.172 |
-6.08 |
2.281 |
15.657 |
8.832 |
| 966.6 |
6.766 |
6.594 |
6.852 |
6.74 |
6.84 |
6.264 |
6.157 |
10.14 |
| 一塁打率 |
1008 |
25.346 |
2.506 |
-4.174 |
-1.674 |
-2.467 |
0.061 |
1.989 |
1.611 |
| 386.7 |
2.707 |
2.638 |
2.741 |
2.696 |
2.736 |
2.506 |
2.463 |
4.057 |
| 二塁打率 |
-333.2 |
3.773 |
0.342 |
11.62 |
0.008 |
-0.724 |
-0.126 |
0.423 |
0.518 |
| 124.7 |
0.873 |
0.851 |
0.844 |
0.870 |
0.883 |
0.808 |
0.794 |
1.309 |
| 三塁打率 |
-42.44 |
1.782 |
0.348 |
-0.086 |
0.872 |
-0.346 |
0.533 |
-0.259 |
-0.252 |
| 61.69 |
0.431 |
0.42 |
0.437 |
0.43 |
0.436 |
0.399 |
0.393 |
0.647 |
| HR率 |
-334.2 |
3.566 |
4.745 |
0.843 |
0.492 |
1.129 |
0.472 |
1.540 |
0.802 |
| 102.6 |
0.718 |
0.700 |
0.727 |
0.716 |
0.726 |
0.665 |
0.654 |
1.077 |
結論から言うと、「ミートが全能力の中で一番、打率等に強い相関関係がある。」と言えるでしょう。
加えて、「複雑なパラメータが絡み合って存在していることが予想される」ということでしょう。設計通りでよかったです。
面白いのは、
・出塁率には守備力がマイナスに相関関係してそう。
・一塁打率には走力がマイナスに相関関係している。(二塁打率が高くなっている理由に合致しそう)
興味深いのは、
・OPSはミート>パワー≒走力>反応に相関している。
・反応が(表記の割に)意外と重要そう
設計通り。(キリッ
反応は、速球投手の活躍のために生まれました。速球早い=反応早くないとブレるって感じですね。その他には守備にも走塁にもプラス要素として入っている素敵な能力です。
不思議なのは、
・三塁打率・・・何故お前は肩力が必要なんだ?
・HR率は・・・ん?走力必要か?守備力とは・・・何なのか。
なんだろうこれは、というものですね。
予想外だったのは、
・長打にそれほどパワーが関係してこないこと(HRには関係するよ!)
面白いですね。
選手たちは本当に生き物みたいです。
今後もデータ分析を通じて面白いゲームを作っていきたいと思います。よろしくお願いします!
こぼれ話
このゲームの歴史をちょっと紐解くと、このゲームは生まれて間もないですが、原型の物理プログラムコード自体は2011年頃には生まれていました。
「何人かと思いっきり試合しまくって微調整する」「打撃練習(実装予定なし)で打率を調整する」等々、合わせて3年近く調整にかかっています。
当初は「0.1秒ごとに球を動かして投球・打撃をする」でした。
当時のマシンパワーは今に比べてひどかったのと、比較的重いPerl(CGI)だったので動かすのに相当苦労した記憶があります。
動作確認は「表示で疑似3Dを作って動きを1球ずつ確認」してました。
・まともに球投げねえ(笑)
・まともに打撃しねえ(笑)(そりゃ0.1秒間隔じゃ球とバットが埋まるでしょ)
・まともに守備しねえ(笑)ってか守備陣どこ?打ったらHRなんだけど。
みたいなことをしていました。
それに比べたらだいぶ進歩したなあと思ってます。