合作机构:阿里云 / 腾讯云 / 亚马逊云 / DreamHost / NameSilo / INWX / GODADDY / 百度统计
译者 | 朱先忠
审校 | 重楼
异常值检测是一种无监督的机器学习任务,用于识别给定数据集中的异常(即“异常观测”)。在大量现实世界中,当我们的可用数据集已经被异常“污染”时,异常值检测任务对于整个机器学习环节来说是非常有帮助的。当前,开源框架Scikit learn已经实现了几种异常值检测算法,在我们持有未受污染的基准数据的情况下,我们也可以使用这些算法进行新颖检测。这是一项半监督任务,可以预测新的观测结果是否为异常值。
本文中,我们将比较的四种异常值检测算法如下:
由于我们的任务是无监督的;所以,我们没有基本事实来比较这些算法的准确性。相反,我们想看看他们的结果(尤其是球员排名方面)彼此之间的差异,并对他们的行为和局限性获得一些直觉,这样我们就可以知道什么时候更喜欢其中一名球员而不是另一名。
接下来,让我们使用2023年美国职业棒球大联盟(MLB)赛季击球手表现的两个指标来比较其中的一些技术吧:
击球手表现还有许多更复杂的指标,例如OBP加SLG(OPS)、基本平均加权(wOBA)和调整后的加权跑动(WRC+)。然而,我们将看到,除了常用和易于理解之外,OBP和SLG具有适度的相关性和近似正态分布,使它们非常适合这种比较。
我们使用pybalball包来获取击球数据。该Python包接受MIT许可,能够取得来自于Fangraphs.com、Baseball-Reference.com和其他来源的数据;当然,这些来源反过来又是从美国职业棒球大联盟获得的官方记录数据。
我们使用pybalball的2023年击球统计数据,可以通过batting_stats(FanGraphs网站)或batting_stasts_bref(权威网站Baseball Reference)获得。事实证明,FanGraphs中的球员名称格式更正确,但Baseball Reference中的球员团队和联盟在交易球员的情况下格式更好。为了获得一个具有更高可读性的数据集,我们实际上需要合并三个表:FanGraphs、Baseball Reference和键查询。
from pybaseball import (cache, batting_stats_bref, batting_stats,
playerid_reverse_lookup)
import pandas as pd
cache.enable() # 重新运行时避免不必要的请求
MIN_PLATE_APPEARANCES = 200
# 为了可读性和合理的默认排序顺序
df_bref = batting_stats_bref(2023).query(f"PA >= {MIN_PLATE_APPEARANCES}"
).rename(columns={"Lev":"League",
"Tm":"Team"}
)
df_bref["League"] = \
df_bref["League"].str.replace("Maj-","").replace("AL,NL","NL/AL"
).astype('category')
df_fg = batting_stats(2023, qual=MIN_PLATE_APPEARANCES)
key_mapping = \
playerid_reverse_lookup(df_bref["mlbID"].to_list(), key_type='mlbam'
)[["key_mlbam","key_fangraphs"]
].rename(columns={"key_mlbam":"mlbID",
"key_fangraphs":"IDfg"}
)
df = df_fg.drop(columns="Team"
).merge(key_mapping, how="inner", on="IDfg"
).merge(df_bref[["mlbID","League","Team"]],
how="inner", on="mlbID"
).sort_values(["League","Team","Name"])
TOP