《Rick.C & Peter.R 共同創作》
在上一篇【Python學習筆記_賽事預測-MLB全壘打與勝負的相關?】中,我們研究了全壘打與勝負間的關聯性,部分實證的確符合我們的預期,但也找出了一些與我們猜想不同的結果。
而今日我們變換一個特徵值,我們就來拿與全壘打相似,卻考慮更多打者數據的「打擊率」作為我們本日的研究特徵,我們將探討以下幾點:
球來就打我們都知道,但要先了解計分板上的背後邏輯。規則上的打擊率是衡量打者成績的一個重要指標,與上壘率、長打率合稱「打擊三圍」,計算方式為安打(H)除以打數(AB),而安打包含了一壘安打、二壘安打、三壘安打,以及全壘打,因此涵蓋打者打擊能力的數值又比全壘打更為周全。
我們的資料來源一樣為FANGRAPHS,數據期間我們也一樣抓取2015賽季至2021賽季,共7年的期間作為我們研究的賽期。
在上一篇章中,我們總會認為主隊擁有主場優勢,直覺認為在成績上大多數據應該要比客隊來的優異,這一刻讓我們就先來看看主隊的打擊率是否存在著主場BUFF
首先,我們一樣導入套件
# 數據整理
import numpy as np
import pandas as pd
# 可視化
import matplotlib.pyplot as plt
import seaborn as sns
import plotly as py
import plotly.graph_objs as go
接著讀取資料
df = pd.read_excel(r"C:\Users\Guess365User\Desktop\MLB\fangraphs紀錄\fan_all.xlsx",index_col='date')
df.head()
我們所爬取的資料中,只有主隊以及客隊的打擊率(AVG),再假設之上還尚缺一點點精準度!在此我們要自行製作欄位「more_Batting_AVG」,為判斷主客隊誰的打擊率較高;「W/L」為判斷主客隊誰獲勝;「more_AVG_win」為判斷打擊率高者是否獲勝
df['more_Batting_AVG'] = (df['Home_Batting_AVG'] > df['Away_Batting_AVG'])*1
df['W/L'] = (df['主隊得分'] > df['客隊得分']) *1
df["more_AVG_win"] = (df['more_Batting_AVG'] == df['W/L'])*1
df.head(5)
這裡我們用到剛剛創建的欄位「more_Batting_AVG」來視覺化看看
trace0 = go.Pie(labels=df["more_Batting_AVG "].value_counts().index,
values=df["more_Batting_AVG "].value_counts().values,
hole=0.5,
opacity=0.9,
marker=dict(line=dict(color='white', width=1.3))
)
layout = go.Layout(title='主客打擊率')
data = [trace0]
fig = go.Figure(data, layout)
py.offline.plot(fig, filename=r'C:\Users\Guess365User\Desktop\IT邦寫文\圖表區\主客打擊率.xlsx')
藍色(1)表示主隊打擊率較高,橘色(0)表示客隊打擊率較高。我們可以發現,主隊打擊率的確有較高的機率勝過客隊打擊率,不過以統計的角度來看,52.5%的機率其實就跟各半是差不多的,所以說,打擊率並無特別受到主場優勢的加持
依照大眾的直覺感官,打擊率高的隊伍應該要有較高的機率獲勝,因為只有將球擊出去,這樣才有可能得分,但真實情況會是如此嗎?
這裡我們用到剛剛創建的欄位「more_AVG_win」來視覺化看看
trace0 = go.Pie(labels=df["more_AVG_win"].value_counts().index,
values=df["more_AVG_win"].value_counts().values,
hole=0.5,
opacity=0.9,
marker=dict(line=dict(color='white', width=1.3))
)
layout = go.Layout(title='打擊率與勝負關係')
data = [trace0]
fig = go.Figure(data, layout)
py.offline.plot(fig, filename=r'C:\Users\Guess365User\Desktop\IT邦寫文\圖表區\打擊率與勝負關係圖.xlsx')
此處藍色(1)為打擊率高且獲勝者,佔比高達81.1%,而橘色(0)為打擊率高但卻輸者,佔比18.9%,由此可知,打擊率較高的隊伍,獲得勝利的機率也相對較高
接著我們先分別看看主客隊打擊率的分布。可以看到不論是主隊(綠色)或是客隊(紅色),大多比賽的打擊率都落在2~3成左右,但很明顯可以看到,主隊(綠色)的右半部較多一些,而客隊(紅色)的則是左半部較多,由此可知,主隊仍可能因為較熟悉主場地勢等原因,打擊略高於客隊一些
sns.set(style = "whitegrid") # 白色網格背景
plt.grid(linestyle='-.')
plt.hist(df['Home_Batting_AVG'],bins=30,color='#C1F320',alpha=.9)
plt.hist(df['Away_Batting_AVG'],bins=30,color='#FF0000',alpha=.4)
plt.show()
從平均值來看,主隊的確也是略高於客隊0.01%,但這一點點真的是有跟沒有一樣……
先從主隊來看,我們將主隊打擊率高於0.25的比賽取出,並存放其勝負的結果
home_win = df[df['Home_Batting_AVG'] > 0.25]['W/L']
home_win
接著將其畫成圓餅圖,藍色(1)為主隊打擊率過平均且獲勝的機率,為75.2%,而橘色(0)則為主隊打擊率過平均卻輸掉比賽的機率,為24.8%,由此可知,主隊的打擊率如果有過平均0.25,那獲勝的機率可高達7成5
trace0 = go.Pie(labels= home_win.value_counts().index,
values= home_win.value_counts().values,
hole=0.5,
opacity=0.9,
marker=dict(line=dict(color='white', width=1.3))
)
layout = go.Layout(title='主隊過平均打擊率與勝負關係')
data = [trace0]
fig = go.Figure(data, layout)
py.offline.plot(fig, filename=r'C:\Users\Guess365User\Desktop\IT邦寫文\圖表區\主隊過平均打擊率與勝負關係圖.xlsx')
那麼客隊的狀況又會是如何呢?
我們如法炮製的將客隊圖畫出,但客隊的平均打擊率為0.24,因此我們將剛剛主隊0.25的部分更改為0.24,並將其勝負放入away_win中
away_win = df[df['Away_Batting_AVG'] > 0.24]['W/L']
away_win
trace0 = go.Pie(labels= away_win.value_counts().index,
values= away_win.value_counts().values,
hole=0.5,
opacity=0.9,
marker=dict(line=dict(color='white', width=1.3))
)
layout = go.Layout(title='客隊過平均打擊率與勝負關係')
data = [trace0]
fig = go.Figure(data, layout)
py.offline.plot(fig, filename=r'C:\Users\Guess365User\Desktop\IT邦寫文\圖表區\客隊過平均打擊率與勝負關係圖.xlsx')
可以看到下方圓餅圖,藍色(0)為客隊打擊率過平均且獲勝的機率,為65.4%,而橘色(1)為客隊打擊率過平均卻輸掉比賽的機率,為34.6%,由此可知,客隊的打擊率高於平均0.24時,要獲勝的機率雖然輸給主隊,但也高達6成5
最後,我們來看看剛剛統計出打擊率較高,且獲勝的隊伍究竟是主隊多還是客隊多呢?
我們將df中全壘打數多且獲勝的隊伍取出,並存放到「df_avg_win」中
df_avg_win = df_avg_win["W/L"] == df['W/L']]
df_avg_win.head()
接著將「W/L」這欄位的數值視覺化看看
trace0 = go.Pie(labels= df_avg_win["W/L"].value_counts().index,
values= df_avg_win["W/L"].value_counts().values,
hole=0.5,
opacity=0.9,
marker=dict(line=dict(color='white', width=1.3))
)
layout = go.Layout(title='打擊率勝負與主客關係')
data = [trace0]
fig = go.Figure(data, layout)
py.offline.plot(fig, filename=r'C:\Users\Guess365User\Desktop\IT邦寫文\圖表區\打擊率勝負與主客關係圖.xlsx')
橘色(0)表示打擊率高且獲勝的隊伍為客隊,其佔比達46.2%,而藍色(1)表示打率高且獲勝的隊伍為主隊,佔比為53.8%,由此可知,主隊打擊率高且獲勝的機率較高出一些,但整體來說仍然處於一半一半的狀態
根據今天的研究,打擊率高的隊伍的確有較高的機率可以獲得勝利,因此打擊率將做為我們預測勝負的一個重要指標之一,同時從其他角度的統計看出,主場仍然不存在明顯的主場優勢加持,因此有時候我們未經過統計的驗證,真的很容易被其他的聲音所影響而渾然不覺。
相信直覺的同時、也不忘拿數據當作背書。歷史在那邊躺著、用數據科學將其重整、下一次要練習哪一個指標~就讓我們繼續看下去… …To Be continued
[Guess官網平台-分析專欄] https://reurl.cc/yMOVE6
[資料視覺化 | 製作充滿說服力的資訊圖表]
[Python 資料科學實戰教本:爬蟲、清理、資料庫、視覺化、探索式分析、機器學習建模,數據工程一次搞定!]