M-1グランプリ2023の決勝戦をデータ分析で予想！part2

[前回](https://qiita.com/paonwaon/items/d0c3d80726433d54b483)作成したモデルでは、
・さや香
・カベポスター
・真空ジェシカ
この3組が決勝ラウンド進出予想されました。
ただ情報が少なったため、もう少しデータを足し、モデルを改良して再度予想してみましょう。

現在、競馬予想モデルで予想ブログ運営しております。最新の予想は[こちら](https://sciencekeiba.com)から。

# ABCお笑いグランプリの結果と関西弁を足してみる
現状、 __所属事務所__ , __結成年__ ,  __決勝出場経験__ の3つからモデルが作成されています。
他にどのような情報がM1と関係しそうですかね。
いろいろ候補を考えました。

・ABCお笑いグランプリの結果
・上方漫才大賞の結果
・キングオブコントの結果
・方言（関西弁）
・M1準決勝進出の回数

ぱっと思いつくのはやはり他の賞レースでの結果ですね。結果的には __ABCお笑いグランプリの結果__ を採用しました。
理由としては、関東関西問わず参加しており、M1決勝進出者にABCお笑いグランプリで好成績を残しているコンビが多かったからです。
今回決勝に進出した9組の中でも令和ロマンやカベポスターが準優勝、優勝と活躍していますね。

賞レース以外では今回 __関西弁__ に着目しました。お笑いというとやはり関西が強いイメージがありますよね。実際のところ違いはあるのでしょうか。

ということで以上の2つ、__ABCお笑いグランプリの結果__ と __関西弁__ をデータに追加します。

・ABCお笑いグランプリの結果→3位以内に入った経験の有無
・関西弁→少し主観入りますが、関西弁かどうか（わからない場合は出身やNSCの情報活用）

ABCお笑いグランプリについては決勝出場経験だとM1の決勝に出れるコンビはそれぐらいの実力が他のコンビニもあると思ったので、3位以内の成績を残したかどうかでわけました。

ということで使用データを確認します。
##### 今回使用するデータ
・所属事務所→吉本か否かで分類（吉本:0 非吉本:1）
・コンビ歴→(開催年ー結成年の値）
・決勝出場回数→初出場か連続出場か〇年ぶりかで分類（初:0 連続:1 ぶり:2）
・ABCお笑いグランプリの結果→3位以内に入った経験の有無（なし:0 あり:1）
・関西弁→（違う:0 そう:1）
・出番順を文字列→数値データに変更（おまけ）

出番順は笑みくじでまだわからないため、予想モデルに使えないのでおまけです。

5つの特徴量を用いていざ予想モデル作成です。

# 新要素と合計点の関係を確認
と、その前に今回追加した要素について、データの可視化を行い、データを分析していきましょう。

##### ABCお笑いグランプリの結果と合計点の関係
```
print("ABC1～3位経験なし: %.2f"%(konbi3[konbi3.ABC == 0].合計点.mean()))
print("ABC1～3位経験あり: %.2f"%(konbi3[konbi3.ABC == 1].合計点.mean()))
```
ABC1～3位経験なし: 636.90
ABC1～3位経験あり: 644.89

8点の差が出ましたね。有用なデータが用意できました。

##### 関西弁と合計点の関係
```
print("not関西弁: %.2f"%(konbi3[konbi3.関西弁 == 0].合計点.mean()))
print("関西弁: %.2f"%(konbi3[konbi3.関西弁 == 1].合計点.mean()))
```
not関西弁: 635.33
関西弁: 641.94

こちらも6点ほど差がみられました。関西勢の方がやや有利なようです。

ということで使えそうなデータが用意できてよかったです。モデルを作成しましょう。

# 予測モデル(決定木)
今回も決定木を用いてモデルを作成します。

```
# 目的変数と説明変数の値を取得
target = konbi3["合計点"].values
features_one = konbi3[["コンビ名 所属事務所", "決勝出場回数", "結成年","ABC","関西弁"]].values
# 決定木の作成
my_tree_one = tree.DecisionTreeClassifier()
my_tree_one = my_tree_one.fit(features_one, target)
```
```
#  説明変数の値を取得
test_features = m2023[["コンビ名 所属事務所", "決勝出場回数", "結成年","ABC","関西弁"]].values
#  予測
my_prediction = my_tree_one.predict(test_features)
my_prediction
```
結果がこちらです。
1位：681点：ダンビラムーチョ
1位：681点：マユリカ
3位：659点：モグライダー
4位：653点：カベポスター
5位：647点：真空ジェシカ
6位：625点：さや香
7位：622点：ヤーレンズ
8位：617点：令和ロマン
8位：616点：くらげ

ずいぶんと変わりました。ダンビラとマユリカがめっちゃ高い、、、
勘のいい方はこの点数を見てピンときたかもしれません。
そうです。ミルクボーイの点数と一緒です。
実はダンビラとマユリカは吉本所属、初出場、結成12年、ABC好成績なし、関西弁と2019年のミルクボーイと全く条件が同じです。
今回決定木で回帰モデルを作成していて、学習の深さの上限を設けなかったため、これらの特徴が同じデータが学習データにあればそれに分類されます。データ数が少ないため仕方ないですね、、、

### 決定木モデルの評価
今回作成した決定木と同様のモデルを、今度は学習データを訓練データとテストデータに分けてモデルを作成し、精度の評価を行ってみます。

```
data_x = konbi3[["コンビ名 所属事務所",'結成年', "決勝出場回数","ABC","関西弁"]].values
data_y = konbi3["合計点"].values

# データをトレーニング用と検証用に分割
train_x, test_x, train_y, test_y = train_test_split(data_x, data_y, test_size=0.3)

my_tree_one = tree.DecisionTreeClassifier()
my_tree_one = my_tree_one.fit(train_x, train_y)
print("学習用データの精度：{:.3f}".format(my_tree_one.score(train_x, train_y)))
print("テスト用データの精度：{:.3f}".format(my_tree_one.score(test_x, test_y)))
```
学習用データの精度：0.905
テスト用データの精度：0.056

いや全然あかんやん笑
一応決定係数R2を用いた性能評価を行ってみます。
```
from sklearn.metrics import r2_score            # 決定係数
from sklearn.metrics import mean_squared_error  # RMSE

# 予測値(Train）
y_train_pred = my_tree_one.predict(train_x)

# 予測値（Test)
y_test_pred = my_tree_one.predict(test_x)

# 決定係数(R^2)
print('R^2 学習: %.2f, テスト: %.2f' % (
        r2_score(train_y, y_train_pred), # 学習
        r2_score(test_y, y_test_pred)    # テスト
      ))
```


$R^2 学習: 0.85, テスト: -0.64$

この決定係数の値について、理想は0.8~0.9程度と言われています。
1に近すぎても過学習を起こしている可能性があるためですね。
それが今回マイナスです。そんなことあるのかと思い調べてみると、0以下はターゲット変数の平均値を予測するより悪いようです。
ゼンゼンダメジャン！
データ数が少ないことが原因なんですかね、、、
木の深さに制限をかけてみてもあまり改善は見込めませんでした。

このまま終わってももったいないので重回帰分析というアプローチで予測モデル作成しましょう。

# 予測モデル(重回帰分析)
重回帰分析を行うにあたり
・決勝出場回数→初出場か否かで分類（初:0 経験あり:1 ）
に変更しました。そもそも本来ダミー変数って0or1の2進数で管理すべきなんですかね。要勉強です。

てことでちゃちゃっとモデル作成しちゃいましょう。
```
from sklearn.linear_model import LinearRegression
X=konbi3[['コンビ名 所属事務所','結成年',"決勝出場回数","ABC","関西弁"]]
y=konbi3["合計点"]
reg=LinearRegression()
reg.fit(X,y)
reg.predict(m2023)
```
結果がこちらです。

1位：651点：カベポスター
1位：646点：さや香
3位：644点：令和ロマン
4位：643点：マユリカ
5位：641点：ダンビラムーチョ
6位：638点：くらげ
7位：635点：モグライダー
8位：634点：真空ジェシカ
8位：633点：ヤーレンズ

点数の式は以下になります。
$合計点 = -10.25(吉本:0)+0.39(コンビ歴)+3.8(初出場:0)+5.86(ABC成果あり:1)+2.23(関西弁:1)+636.08$

吉本かどうかが重要なようですね。

ちなみにこちらでも決定係数を算出してみました。
$R^2:-0.0377848498967468$

あかんやないかーーーい

# まとめ
あと100年分ぐらいのM1決勝データが欲しいですね。
決勝だと10人しかいませんが、準決勝進出できるか判定や、準々決勝進出できるか判定のモデルであればもっとサンプル数も増えるため、いいモデルが作れるかもなと思いました。また来年にでも挑戦してみたいですね、、もっと知識量増やしてリベンジします。

現在、競馬予想モデルで予想ブログ運営しております。最新の予想は[こちら](https://sciencekeiba.com)から。