恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

LeaguePredictor:基于英雄阵容的机器学习胜率预测实战

  • 首页
  • 资讯中心
  • /
  • LeaguePredictor:基于英雄阵容的机器学习胜率预测实战

相关资讯

宏脉医美系统使用手册:从开单到回访的业务流全解析 2026/10/11 16:53:06
Intouch报警数据库配置实战:从报警组规划到历史入库 2026/10/11 16:53:06
学籍管理系统数据流图与数据字典:结构化需求分析实战 2026/10/11 16:48:05

最新资讯

Spring Boot+微信小程序:咖啡店点餐系统全栈实战解析
Reverse Engineer Anything:单日狂揽 1w+ Star 的开源逆向工程神器
SpringBoot+微信小程序点餐系统实战:从架构到支付回调避坑指南
单写者 Actor 与类型化脱敏:ai-memory 内部那些“看着多余却保命“的工程细节
Python+Django员工管理系统开发全流程:从数据库设计到部署实践
三维PDE有限差分数值解实战:Python+NumPy实现与CFL稳定性控制

今日推荐

UE动画修改实战:从资产编辑到重定向与蒙太奇驱动
统计随机数生成器攻击下的KLJN安全密钥交换协议Matlab仿真
政务API安全治理:资产测绘、低代码编排与行标对标实践

本周热门

UE动画修改实战:从资产编辑到重定向与蒙太奇驱动
统计随机数生成器攻击下的KLJN安全密钥交换协议Matlab仿真
政务API安全治理:资产测绘、低代码编排与行标对标实践

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

LeaguePredictor:基于英雄阵容的机器学习胜率预测实战

发布时间:2026/10/11 16:53:06
LeaguePredictor:基于英雄阵容的机器学习胜率预测实战 简介LeaguePredictor 是一套面向电子竞技数据分析初学者与机器学习实践者的 Python 项目源码聚焦英雄联盟比赛胜率预测这一具体场景帮助读者理解如何把分类模型落地到真实赛事数据上。资源包共 24 个文件以 22 个 py 脚本为主体覆盖数据生成、特征结构处理、分类器训练与测试等模块另附 gitignore 与 txt 说明文件压缩包约 31KB体量轻便、便于快速通读与二次修改。目前已有 235 人学习下载。项目完整呈现了从历史比赛数据清洗、特征工程到模型选择、训练评估与部署更新的全流程思路涉及 Pandas、Numpy、Scikit-learn 等常用库并包含逻辑回归、随机森林等分类模型的对比实践适合想系统了解监督学习项目结构、积累特征提取与调参经验的读者参考。1. 从 Ban/Pick 到水晶爆炸LeaguePredictor 到底在算什么排位赛加载界面一出来十个英雄头像亮起你心里其实已经在算一笔账对面三个突进我们辅助是软辅这把前中期大概率要炸。这种“看一眼阵容就知道几几开”的直觉正是 LeaguePredictor 想用数据复现的东西。它不预测你这一把会不会送也不看你上一局的 KDA它只吃两边各五个英雄的阵容信息输出一个 0 到 1 之间的胜率数字。听起来像玄学但背后是实打实的特征工程和分类模型。这件事的价值在于它把“阵容克制”这件靠老玩家经验判断的事变成了可量化、可复现的工程问题。适合谁做想入门机器学习但苦于找不到有意思数据集的开发者、想给自己战队做 BP 辅助工具的分析师、以及单纯想知道“我这套绝活阵容到底强不强”的硬核玩家。整条链路不复杂拿到对局数据、把英雄 ID 变成模型能吃的特征、训一个二分类器、再用校准后的概率输出胜率。下面按我实际落地的顺序拆开讲。2. 数据从哪来、特征怎么搭LeaguePredictor 的输入层设计2.1 对局数据的三个来源与取舍做胜率预测第一道坎不是模型是数据。常见做法有三条路官方对局 API 拉取、公开对局数据集、以及自己爬取的对局记录。官方 API 有速率限制适合小批量拉取高段位对局公开数据集胜在量大但版本混杂需要按 patch 过滤自爬数据灵活但清洗成本高。我一般会先用公开数据集跑通全流程确认特征有效后再用 API 补充特定版本的数据。关键字段其实就几个双方各五个英雄的 ID、对局结果1 或 0、对局版本号、以及可选的分段信息。英雄 ID 一定要用官方稳定的数字 ID不要用名字字符串否则版本改名或本地化会让你对不上号。版本号必须保留因为英雄强度随 patch 波动跨版本混训会让模型学到“版本噪声”而不是“阵容逻辑”。import pandas as pd # 假设原始数据每行是一局blue_1..blue_5 / red_1..red_5 是英雄ID df pd.read_csv(matches_raw.csv) # 只保留需要的列并按版本过滤掉过老的数据 df df[[blue_1,blue_2,blue_3,blue_4,blue_5, red_1,red_2,red_3,red_4,red_5, blue_win,patch]] # 只保留最近若干个大版本避免远古数据干扰 recent_patches [14.1,14.2,14.3,14.4] df df[df[patch].isin(recent_patches)].reset_index(dropTrue) print(df.shape) print(df[blue_win].mean()) # 检查标签是否接近 0.5严重偏斜要警惕这段代码做了三件事裁剪字段、按版本过滤、检查标签分布。标签均值如果离 0.5 太远说明数据采样有偏比如只爬了某一方视角的胜利局后续模型会学出虚假先验。参数上recent_patches建议覆盖 3 到 5 个 patch太少样本不足太多则版本差异被抹平。2.2 把十个英雄 ID 变成模型能吃的特征英雄 ID 是类别变量直接丢给模型会被当成有序数值这是新手最容易翻车的地方。正确做法是 one-hot 或多热编码。因为一局里同一方不会出现重复英雄所以每方可以用一个长度为“英雄总数”的 0/1 向量表示再把蓝红两方拼起来得到维度为 2×N 的输入。import numpy as np # 构建英雄ID到索引的映射假设英雄ID范围已知 all_heroes sorted(set(df[[blue_1,blue_2,blue_3,blue_4,blue_5, red_1,red_2,red_3,red_4,red_5]].values.ravel())) hero_to_idx {h: i for i, h in enumerate(all_heroes)} n_heroes len(all_heroes) def encode_row(row): vec np.zeros(2 * n_heroes, dtypenp.float32) for h in [row.blue_1,row.blue_2,row.blue_3,row.blue_4,row.blue_5]: vec[hero_to_idx[h]] 1.0 for h in [row.red_1,row.red_2,row.red_3,row.red_4,row.red_5]: vec[n_heroes hero_to_idx[h]] 1.0 return vec X np.stack(df.apply(encode_row, axis1).values) y df[blue_win].values.astype(np.float32) print(X.shape, y.shape)这里前 N 维代表蓝色方后 N 维代表红色方。用多热而不是 one-hot 是因为一局有五个英雄one-hot 会丢失“同时存在”的信息。参数上n_heroes取决于你数据覆盖的英雄数量通常在一百六十上下。注意编码映射必须固定下来存成文件推理时新对局要用同一套映射否则特征错位预测结果就是黑匣子里蹦出来的随机数。2.3 为什么先别急着加 KDA、经济这些特征很多人第一反应是加更多特征击杀、经济、视野分。但 LeaguePredictor 的定位是赛前预测这些赛后数据在 BP 阶段根本拿不到加了就是数据泄漏离线指标好看上线全废。我见过有人用赛后经济差训出 0.95 准确率结果一上线发现输入根本没有经济字段血泪经验。所以特征层要克制只保留 BP 阶段可获得的信息英雄、位置、版本最多加上分段和先后选顺序。3. 模型选型与训练从逻辑回归到梯度提升的取舍3.1 基线模型为什么先用逻辑回归面对 2×N 维的稀疏 0/1 特征逻辑回归是最诚实的基线。它训练快、可解释、不容易过拟合而且输出的就是概率天然适合胜率预测。先用它跑一个数出来你才知道后面的复杂模型到底有没有真本事。如果逻辑回归只能到 0.55而某个深度模型号称 0.75那多半是泄漏或过拟合不是模型强。from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.metrics import roc_auc_score, log_loss X_train, X_val, y_train, y_val train_test_split( X, y, test_size0.2, random_state42, stratifyy) clf LogisticRegression( C1.0, # 正则强度越小正则越强 max_iter1000, # 稀疏特征收敛慢给足迭代 solverliblinear # 小规模稀疏数据上稳定 ) clf.fit(X_train, y_train) prob clf.predict_proba(X_val)[:, 1] print(AUC:, roc_auc_score(y_val, prob)) print(LogLoss:, log_loss(y_val, prob))参数说明C控制正则稀疏高维特征下建议从 1.0 试起过拟合就调小solver选liblinear是因为特征维度高但样本相对不算海量它在稀疏场景下比默认的lbfgs更稳。评估别只看准确率胜率预测要看 AUC 和 LogLoss前者衡量排序能力后者衡量概率校准质量。一个只会输出 0.5 的模型准确率也有五成但 LogLoss 会暴露它毫无信息量。3.2 梯度提升树能不能带来实质提升逻辑回归假设特征线性可加但英雄之间有配合与克制存在交互效应。梯度提升树如 LightGBM能自动捕捉这类非线性交互通常在 AUC 上能比逻辑回归高两到四个百分点。代价是训练变慢、可解释性下降、更容易过拟合。我的做法是逻辑回归定基线LightGBM 冲上限两者都跑用验证集 AUC 决定上线哪个。import lightgbm as lgb dtrain lgb.Dataset(X_train, labely_train) dval lgb.Dataset(X_val, labely_val, referencedtrain) params { objective: binary, metric: auc, learning_rate: 0.05, # 学习率小一点更稳 num_leaves: 31, # 叶子数控制复杂度 min_data_in_leaf: 50, # 每叶最少样本防过拟合 feature_fraction: 0.8, # 特征采样 bagging_fraction: 0.8, bagging_freq: 1, verbose: -1 } model lgb.train( params, dtrain, num_boost_round500, valid_sets[dval], callbacks[lgb.early_stopping(50)] ) print(best iter:, model.best_iteration)参数上num_leaves和min_data_in_leaf是防过拟合的两个闸门稀疏 0/1 特征下叶子别开太大31 到 63 之间比较稳early_stopping(50)表示验证集 50 轮不提升就停避免无效训练。注意 LightGBM 对特征缩放不敏感所以不需要对 0/1 向量做标准化这点比逻辑回归省事。3.3 概率校准为什么你的 0.7 不是真的 70%树模型输出的概率往往偏极端预测 0.9 的局实际胜率可能只有 0.75。胜率预测如果要做成给人看的数字校准不能省。常用方法是 Platt 缩放或等渗回归在验证集上拟合一个映射把原始分数拉回真实概率。from sklearn.calibration import CalibratedClassifierCV calibrated CalibratedClassifierCV( model, methodisotonic, cvprefit ) calibrated.fit(X_val, y_val) cal_prob calibrated.predict_proba(X_val)[:, 1] print(校准后 LogLoss:, log_loss(y_val, cal_prob))methodisotonic适合样本量足够的情况样本少时改用sigmoid。校准后 LogLoss 通常会下降这意味着你告诉用户“这把七成胜率”时长期看真的有七成能赢。这一步是很多玩具项目忽略的但恰恰是 LeaguePredictor 能不能被信任的关键。4. 避坑与排查LeaguePredictor 落地时最容易翻车的五件事4.1 现象离线 AUC 0.8上线预测全是五五开原因通常是推理时的特征编码和训练时不一致比如英雄映射表没保存、新英雄不在映射里被静默丢弃导致输入向量大面积为零。解决把hero_to_idx序列化成 JSON 随模型一起发布推理前校验每个英雄 ID 都在表内遇到未知 ID 直接报错而不是填零。4.2 现象模型对某些阵容永远给同一方高胜率原因多半是训练数据里蓝红方样本不均衡或者标签定义有偏。检查y.mean()是否接近 0.5如果明显偏离要么补充另一方视角的数据要么在训练时加class_weightbalanced。别小看这个偏斜的标签会让模型学出“蓝色方必胜”这种废话。4.3 现象换了新版本后准确率断崖下跌英雄强度随 patch 变化旧模型在新版本上会失准。解决按 patch 分桶监控 AUC一旦某版本连续低于阈值就触发重训。工程上把 patch 作为特征之一也有帮助但更稳的是定期用新数据微调而不是指望模型自己泛化版本差异。4.4 现象训练集准确率 0.99验证集 0.55典型过拟合。稀疏高维特征下树模型很容易记住训练样本。排查顺序先看min_data_in_leaf是不是太小再看num_leaves是不是太大最后检查有没有把对局 ID 之类的唯一标识误当特征。逻辑回归这边则看C是不是设得过大。4.5 现象预测延迟高接口扛不住并发原因常是把校准和编码都放在请求路径里实时算。解决编码逻辑用 numpy 向量化别用 Python 循环逐行拼模型用 LightGBM 的predict单条推理本身很快瓶颈往往在特征组装。把英雄映射做成字典查表单次推理控制在毫秒级不难。5. 把胜率做成能用的东西校准曲线、置信区间与一个实用技巧模型训完只是半成品真正让它可用的是验证和呈现。我习惯先画校准曲线把预测概率分桶看每个桶里实际胜率是否贴近预测值。如果 0.6 到 0.7 这一桶实际只有 0.5说明模型在这个区间过度自信需要重新校准或补充该区间样本。这条曲线比任何单一指标都直观也是说服别人“这个数字能信”的最有力证据。import numpy as np from sklearn.calibration import calibration_curve prob_true, prob_pred calibration_curve(y_val, cal_prob, n_bins10) for pt, pp in zip(prob_true, prob_pred): print(f预测均值 {pp:.3f} - 实际胜率 {pt:.3f})除了校准给胜率配一个置信区间也很实用。简单做法是用验证集上的分桶标准差估计或者用 bootstrap 重采样模型输出。这样用户看到的不只是“62%”而是“62%±4%”对低置信度的对局会有更理性的预期。参数上n_bins取 10 比较平衡样本少时降到 5避免每桶样本太少导致曲线抖动。最后一个我常用的技巧把模型输出和“阵容相似度”结合。对于当前对局在历史数据里找英雄重合度最高的若干局看这些局的实际胜率作为模型预测的交叉验证。如果模型说 70% 但相似阵容历史只有 45%那大概率是模型在某个特征上过拟合了。这个技巧不需要额外训练纯查表却能挡掉不少离谱预测。做这类项目我最大的习惯是任何一次指标提升先问一句“是不是泄漏”。被数据泄漏坑过太多次之后我宁可要一个 0.58 但诚实的模型也不要一个 0.9 但上线就崩的幻觉。希望帮到你。本文还有配套的精品资源点击获取

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号