RのWeb制作

Webサービス制作のための技術情報を。データ分析(Python、機械学習コンペ他)や自作野球ゲームMeisyoのこと中心。

Web制作 Meisyo

[Meisyo]ビッグデータから学ぶ試合の基礎設計2

投稿日:2018年10月16日 更新日:

名将と呼ばれた者達、めちゃくちゃソースコードが長い(この記事

ここでは、「どのパラメータが打率等にどれくらい関係するのか」を理解することで強いチームを作る指針を記載しておきます。

というわけで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なんだけど。
みたいなことをしていました。

それに比べたらだいぶ進歩したなあと思ってます。

-Web制作, Meisyo

執筆者:


  1. […] これは[Meisyo]ビッグデータから学ぶ試合の基礎設計2の投手編です! […]

comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

[Meisyo] ゲーム内容刷新予定について

Work It!がある程度形ができてきたので、 Meisyoで今考えているゲーム内容の刷新を公開しておきます。 刷新内容 プログラム再構築  UI改修、高速化とセキュリティ向上のため、プログラムを再構 …

[Meisyo]スタミナ減少による球速低下が酷過ぎる件について

最近SQLばっかり書いているRです。早く適正なSQLを書きたいものです…。 とはいえ、ネットで書かれているようなことは一通り理解してできるようになりました。やったぜ。 今回は、タイトルの通り・・・ ス …

(VPSでつくる) Socket通信を使ったモダンなチャットアプリをFlaskで作ろう

連載第十三回目です。 今回は、チャットアプリを作っていきたいと思います。 チャットの想定としては、会員制、socket通信で滑らかにチャットできる、データベースにログを残すにしましょう。 ただのチャッ …

no image

PHP5.5から使える暗号化「password_hash」を「password_compact」を使って以前のバージョンで利用する

PHP最高の暗号化法としてPHP5.5から使える「password_hash」があります。 でもそれを、5.5未満のバージョンで使いたい! 特に私が使っている、さくらインターネットのサーバーはPHP …

見よう見まねでGitHubでmatomeyomiを公開する

「GitHub」をエンジニア用のSNSと聞いたのではじめてみました。 理由は「他人のコードが見たい!」と、ただそれだけでした。 全て英語ですね。 ↓使い方がわからない方はこちら 黒い画面とかよくわから …