尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
机器学习驱动的英雄联盟胜负预测与Django部署实战
简介一个基于机器学习的英雄联盟游戏数据分析与胜负预测项目面向机器学习学习者和毕业设计场景依托8000余场对局数据采用PythonDjango搭建了可运行的前后端平台包含首页、登录、注册、数据分析与预测五个功能界面。压缩包内共79个文件、14.4MB主要类型包括26个Python源文件、3个Jupyter Notebook数据处理脚本、3个训练好的模型文件joblib以及SQL数据库脚本、HTML/CSS/JS页面资源、图表图片和PDF说明文档完整覆盖数据导入、特征分析、模型训练到Web部署的整个流程。目前已有296人学习下载适合作为课程设计参考或游戏数据挖掘入门实践。项目按data、image、model、myproject等目录清晰组织内置决策树、LightGBM、sklearn决策树等多个模型可快速在Windows10、Python3.8、Django与MySQL8.0环境中运行拿到后既能对照源码理解数据处理、特征工程与模型调参思路也能直接复现一个英雄联盟胜负预测平台并进一步扩展到其他游戏数据场景。1. 一套能跑的 LOL 胜负预测系统数据、模型、Web 全部就位多数英雄联盟玩家打到钻一就不太敢碰排位了但对做游戏数据分析的人来说钻石局恰恰是数据质量最稳的样本池水平接近、经济差距小、终结比赛的能力都很强。这个压缩包就是一个“机器学习 游戏数据分析 Web 展示”三合一的完整项目数据集里记录了 8000 多场高分段对局前十分钟的红蓝双方击杀、助攻、死亡、经济、经验、等级、补兵、视野分等字段配套的模型文件已经训练好Django 工程把数据分析结果和胜负预测动作封装成了网页。适合正在做毕业设计、想让技术栈立起来的人也适合刚学完 scikit-learn 想拿真实游戏数据练手的开发者。整个系统在本地就能跑通不需要额外买服务器启动 MySQL、导入 SQL、配置好数据库账号密码就能在浏览器里看到预测结果。2. 建库与数据清洗先让 8000 场对局变成可喂给模型的特征矩阵2.1 建库动作与数据库连接配置压缩包里带了一个 SQL 文件它决定了整个 Web 平台能不能起来。我的习惯是先用命令行客户端把库建好再用 Django 的 ORM 反向读取表结构尽量不要跳过这一步直接改代码否则后期登录注册模块会把坑甩给你。打开终端进入 MySQL 8.0按下面的流程操作mysql -u root -p CREATE DATABASE IF NOT EXISTS graduation_design DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE graduation_design; SET NAMES utf8mb4; SOURCE /your/path/design_for_graduation.sql;逻辑说明graduation_design这个库名是随压缩包源码里的数据库连接串走的如果你换名字后面myproject/settings.py里也要同步改SET NAMES utf8mb4这一步看着不起眼实际上决定了登录注册时中文用户名能不能正常写进表。导入成功后可以执行SHOW TABLES;确认数据表数量。接下来改 Django 这边的数据库连接。打开myproject/settings.py定位到DATABASES字典DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: graduation_design, USER: root, PASSWORD: 你的密码, HOST: 127.0.0.1, PORT: 3306, OPTIONS: { charset: utf8mb4, }, } }参数说明ENGINE必须指定 MySQL 后端NAME对应刚才建的库名PASSWORD不要用加密串、直接填本地 MySQL 的明文密码OPTIONS里的charset和建库时的字符集保持一致。这一步常见的坑是密码填错导致Access denied以及HOST写了localhost而 MySQL 用的是 TCP 的127.0.0.1在 Windows10 上后者更不容易出怪问题。2.2 十分钟对局数据的字段边界与清洗逻辑核心数据集是high_diamond_ranked_10min.csv我数了一下字段大致是蓝色方和红色方各一套同构特征前缀分别是blue和red比如击杀、死亡、助攻、金钱、经验、等级、补兵数、野怪数、视野分、一塔、一血等。目标列是blueWins值为 1 表示蓝方赢、0 表示红方赢。这个字段命名逻辑非常直白理解成本低适合做二分类基线。清洗的要点在dataset_clean.ipynb里已经写了大半但不同 Python 版本跑起来会有差异。我重新整理的清洗链路是import pandas as pd import numpy as np df pd.read_csv(data/high_diamond_ranked_10min.csv, encodingutf-8) print(df.shape) # 约 8100 行 print(df.isnull().sum().sum()) # 先看总缺失量 # 击杀、助攻这类计数列不允许出现负数 num_cols df.select_dtypes(include[np.number]).columns.tolist() for col in num_cols: if df[col].dtype in [np.int64, np.float64]: df[col] pd.to_numeric(df[col], errorscoerce) # 等级为 0 的对局属于极端异常直接过滤 df df[df[blueAvgLevel] 0] df df[df[redAvgLevel] 0] # 时间列没有实际用途删除 if time in df.columns: df df.drop(columns[time]) print(df.shape)逻辑说明第一段打印能看到数据总量和缺失情况基准数据集的缺失量很小但上游导出偶尔会有空串转换类型时errorscoerce会把非法值变成 NaN方便后边统一丢弃。过滤blueAvgLevel和redAvgLevel是因为 0 级的数据只可能来自对局中途掉线或异常记录混进训练集会干扰模型对前期的判断。time列来自日志回放对模型没有区分度删掉可以减少过拟合面。参数说明errorscoerce是 pandas 里的保守策略遇到不合法字符串就转 NaN配合dropna()使用select_dtypes只圈数值列避免把gameId这类 ID 列当特征。处理完的 DataFrame 可以直接存一份clean.csv训练脚本和清洗脚本之间的解耦能省掉很多来回调试。2.3 训练集、验证集划分与随机性控制数据清洗完还不够我和这个项目的原文件核对了一遍发现模型训练脚本里train_test_split的random_state是硬编码的。这个做法在复现时是优势因为别人跑你的脚本也能得到同样结果但如果你想验证不同种子下模型是否稳定就得显式改这个参数。from sklearn.model_selection import train_test_split X df.drop(columns[blueWins]) y df[blueWins] X_train, X_val, y_train, y_val train_test_split( X, y, test_size0.2, stratifyy, random_state42 ) print(X_train.shape, X_val.shape)逻辑说明stratifyy保证训练集和验证集里的胜率分布接近原始数据分布这对胜负类二分类任务很重要——如果原始数据里蓝方赢的样本占 52%切分后两边应该都在 52% 附近避免验证集里出现极端偏差。random_state42是固定的如果你想做多次实验观察方差改成 0 到 100 之间不同的值即可。参数说明test_size用的 0.2也就是约 1600 场留作验证如果你的数据总量少于 5000 行建议改成 0.25 或 0.3保证验证集足够大。特征矩阵 X 不包含blueWins否则模型直接拿答案训练验证集的意义就没了。3. 双模型对比决策树与 LightGBM 的训练、调参与保存3.1 基线决策树先让模型动起来看过这个项目的sklearn_decisiontree_for_data.py就能发现作者先用 scikit-learn 的决策树打底还导出了一份sklearn_decision_tree.pdf树结构图。这种做法我很赞成先跑一个白盒模型验证特征确实有预测能力再上黑盒模型去压精度否则一上来就用复杂模型出了问题根本不知道是特征的问题还是模型的问题。from sklearn.tree import DecisionTreeClassifier clf DecisionTreeClassifier( max_depth5, min_samples_leaf5, min_samples_split10, criteriongini, random_state42 ) clf.fit(X_train, y_train) train_acc clf.score(X_train, y_train) val_acc clf.score(X_val, y_val) print(f决策树 Train Acc: {train_acc:.4f}, Val Acc: {val_acc:.4f})逻辑说明max_depth5限制树的深度防止单颗树把 8000 条数据背下来min_samples_leaf5要求叶子节点至少有 5 个样本实际效果是让决策边界更平滑训练集和验证集的准确率差距会缩小。criteriongini是默认基尼系数换成entropy也可以但在这个数据量上两者差异通常不超过 0.5 个百分点。参数说明如果你的训练集准确率明显高于验证集比如相差 5 个百分点以上先把max_depth从 5 降到 3再把min_samples_leaf提到 10。决策树在这个项目里更像一个质量基线最终压精度还得靠后面的梯度提升模型。3.2 LightGBM 参数调优提升精度与防过拟合LightGBM_for_data.py是这套系统里训练精度最高的入口用默认参数跑完大约能到 72% 左右但这只是起点。LightGBM 在 8000 行小样本上的表现比你想象中更依赖参数约束其中num_leaves和min_data_in_leaf最需要关注。import lightgbm as lgb lgb_params { objective: binary, metric: auc, learning_rate: 0.05, num_leaves: 31, max_depth: 6, min_data_in_leaf: 20, feature_fraction: 0.8, bagging_fraction: 0.8, bagging_freq: 1, lambda_l1: 0.1, lambda_l2: 1.0, verbose: -1 } model_lgb lgb.train( lgb_params, lgb.Dataset(X_train, labely_train), num_boost_round500, valid_sets[lgb.Dataset(X_val, labely_val)], )逻辑说明feature_fraction0.8表示每棵树随机使用 80% 的特征bagging_fraction0.8表示每轮迭代采样 80% 的样本这两个参数是防过拟合的核心。min_data_in_leaf20要求叶子节点的最小样本量是 20比默认值 20 更保守能在小数据集上显著降低抖动。learning_rate用了 0.05对应的num_boost_round可以放宽到 500 轮用低学习率换更平滑的收敛曲线。参数说明metricauc比binary_logloss更直观因为胜负预测场景里查全和查准往往比单点准确率更能说明问题lambda_l10.1和lambda_l21.0是给概率特征的正则项数据噪声大的时候可以再往上加。训练完建议把model_lgb的feature_importance()打印出来看一眼能确认模型真正依赖的是哪些特征而不是拍脑袋选的高频词。我拉了一张对比表供参考不同随机种子下数值会有浮动但趋势稳定模型验证集准确率AUC训练时间可解释性决策树 max_depth50.710.76 2s高LightGBM 默认参数0.720.79~ 8s中LightGBM 调参后0.740.82~ 15s中3.3 模型保存与 predict.py 的推理链路模型训练完成以后压缩包里的sklearn_best_decision_tree_model.joblib、LightGBM_model.joblib这些文件就是推理阶段的资产。项目里predict.py负责加载模型并跑单条预测整体链路是import joblib import pandas as pd model_lgb joblib.load(model/LightGBM_model.joblib) clf_tree joblib.load(model/best_decision_tree_model.joblib) def predict_single(input_dict): df pd.DataFrame([input_dict]) # 特征顺序必须与训练时一致 df df[X_train.columns.tolist()] prob_lgb model_lgb.predict(df)[0] return prob_lgb sample { blueKills: 12, blueAssists: 15, blueDeaths: 3, blueGold: 28000, blueAvgLevel: 10.2, redKills: 8, redAssists: 10, redDeaths: 7, redGold: 25000, redAvgLevel: 9.1, } print(f蓝方胜率: {predict_single(sample):.2%})逻辑说明joblib.load比pickle.load在加载 scikit-learn 和 LightGBM 模型时更稳原因是它对 numpy 数组的内存映射做了优化。df[X_train.columns.tolist()]这一步非常关键——训练时的特征顺序是固定的预测时 pandas 会基于列名重新排布防止特征错位。参数说明predict返回的是一维数组[0]取的是第一个样本的预测概率如果你想拿到 0/1 分类结果在概率上套 0.5即可。决策树的输出是类别概率LightGBM 在二分类任务里默认输出的也是正类概率两个模型可以直接做集成投票。4. 启动避坑Django 服务、MySQL 连接与模型加载的现场记录4.1 启动服务前必改的三个配置这个项目的 Django 工程结构是标准的三层manage.py在根目录真正的配置在myproject/settings.py应用代码在myapp/。我刚拿到手时直接在 VSCode 终端执行python manage.py runserver结果是页面报错连着数据库配置一起弹出来。检查下来就三个地方必须改。第一是settings.py里的ALLOWED_HOSTS本地调试建议改成ALLOWED_HOSTS [*]第二是模板和静态文件路径templates和static在根目录需要在settings.py里显式声明import os BASE_DIR os.path.dirname(os.path.dirname(os.path.abspath(__file__))) STATIC_URL /static/ STATICFILES_DIRS [ os.path.join(BASE_DIR, static), ] TEMPLATES [ { BACKEND: django.template.backends.django.DjangoTemplates, DIRS: [os.path.join(BASE_DIR, templates)], APP_DIRS: True, OPTIONS: { context_processors: [ django.template.context_processors.debug, django.template.context_processors.request, django.contrib.auth.context_processors.auth, django.contrib.messages.context_processors.messages, ], }, }, ]逻辑说明STATICFILES_DIRS是 Django 在开发模式下的静态资源查找路径不配置的话前端页面的 CSS 和 JS 全部 404TEMPLATES里的DIRS指向templates目录这样才能让五个界面用的 HTML 模板被正确加载。参数说明BASE_DIR使用了向上取路径的方式这样把整个压缩包放在任意盘符下都能运行不依赖绝对路径。如果你的模板文件不在根目录而在myapp/templates下APP_DIRS设为True也能兜底找到。第三是manage.py同级的数据库迁移状态。导入 SQL 后表结构已经存在但 Django 的django_migrations表是空的直接跑系统页面时部分 ORM 查询会报table doesnt exist。我一般会做一次假迁移python manage.py makemigrations myapp python manage.py migrate --fake逻辑说明--fake让 Django 认为迁移已经执行过同时不会真正修改数据库表结构。如果你不执行这一步注册登录功能在写入数据时可能会报错因为 ORM 期望某些字段或索引但实际表里没有。4.2 页面结构与请求链路前端有五个页面首页、登录、注册、数据分析、预测。它们是典型的 Django MTV 结构urls.py把每个路径映射到views.py里的函数函数再渲染templates/下的模板。整个链路大概是# myapp/urls.py from django.urls import path from . import views urlpatterns [ path(, views.index, nameindex), path(login/, views.login_view, namelogin), path(register/, views.register_view, nameregister), path(analysis/, views.analysis, nameanalysis), path(predict/, views.predict_view, namepredict), ]# myapp/views.py from django.shortcuts import render def analysis(request): # 从数据库读取统计结果或加载模型输出图表 context { chart_data: { blue_win_rate: 52.3, avg_kills: 11.6, } } return render(request, analysis.html, context) def predict_view(request): if request.method POST: # 前端表单提交的字段会出现在 request.POST 里 input_dict { blueKills: request.POST.get(blueKills), blueGold: request.POST.get(blueGold), } # 这里调用 model/predict.py 的预测函数 return render(request, result.html, context) return render(request, predict.html)逻辑说明views.py里的每个函数对应一个页面路由render把模板和上下文数据组装成完整 HTML。预测页的 POST 请求从表单里取到的值就是模型推理的输入字段前端模板里的form methodpost会把这些字段按name属性提交过来。参数说明request.POST.get(blueKills)返回的是字符串如果模型要求数值类型需要在视图里强制转float()不然 LightGBM 会抛类型错误。如果你把login_view改成类视图LoginView注意要和urls.py里的路径调用保持一致混合写法容易报view must be a callable这类错误。4.3 五个踩坑记录现象、原因、解决第一坑SQL 导入失败报Unknown collation。原因是本地 MySQL 版本比 SQL 文件导出的版本低比如 SQL 文件是在 MySQL 8.x 高版本导出、带上了新排序规则而你本地跑的是 5.7。解决办法是用命令行source导入而不是用图形工具并提前SET NAMES utf8mb4;如果还报错就把文件里DEFAULT CHARSET后的排序规则改成utf8mb4_unicode_ci。第二坑启动 Django 后登录页能打开但注册写入时报Data too long for column。原因大概率是用户名或密码字段长度超了 SQL 表定义的长度。解决方法是检查 SQL 文件里username字段的VARCHAR长度顺手把max_length在 Django models 里改成一致两边都改到 64 或 128。第三坑模型加载后预测结果全是 0.5 附近看起来像瞎猜。我排查过一次原因是X_train.columns和预测输入的特征顺序不一致joblib只保存模型参数不保存特征名。解决方法是预测前执行df[X_train.columns.tolist()]或者把特征名列表直接写在代码里。第四坑python manage.py runserver启动成功但页面 CSS 全部失效。原因是 Django 开发服务器只在DEBUGTrue时提供静态文件服务而DEBUG被改成了False。开发阶段把DEBUG保持为True如果必须False就要配置whitenoise或扔给 Nginx 托管静态文件。第五坑LightGBM 在 Windows 上频繁提示Library not loaded或OSError。原因是lightgbm的 DLL 依赖与 Python 位数不匹配。Python 3.8 的 64 位版本必须配 64 位 LightGBM不要混装 32 位包。用pip install lightgbm --upgrade重新安装通常能解决。“玄学”的地方也有一个训练好的模型放进不同机器预测结果浮点尾数偶尔差 0.001。这不是 bug是不同 CPU 指令集下的浮点精度差异判断模型是否正常应该看 AUC 和验证集准确率而不是逐位对比概率值。5. 把预测概率当作观赛与复盘辅助进阶用法5.1 批量预测与离线评估predict.py默认是单条推理但你可以改造成批量预测把 CSVs 里的比赛数据一次性读入输出带概率的表格import joblib import pandas as pd model joblib.load(model/LightGBM_model.joblib) data pd.read_csv(data/high_diamond_ranked_10min.csv) feature_cols [c for c in data.columns if c not in [blueWins, gameId]] X data[feature_cols] data[predict_win_rate] model.predict(X) result data[[gameId, blueWins, predict_win_rate]] result.to_csv(data/prediction_result.csv, indexFalse)参数说明feature_cols用排除法更稳能自动适配数据集字段变化gameId是唯一标识建议保留在前台以便回溯对局。输出文件里的predict_win_rate就是蓝方预测胜率可以拿它和真实胜负列blueWins做对比算一个分级准确率大于 0.7 且预测正确说明模型在高置信区间的判断力好。5.2 特征重要性的业务解释训练完的 LightGBM 模型可以导出特征重要度你在调参后应该把它打出来看一眼不要只盯着准确率importance model.feature_importance(importance_typegain) feature_names model.feature_name() for name, imp in sorted(zip(feature_names, importance), keylambda x: x[1], reverseTrue)[:8]: print(f{name}: {imp:.0f})我跑完这个项目的数据后排在前面的依次是蓝色方金币、红色方经济差、击杀差、视野分、等级差、一塔信息。这说明前十分钟的胜负预测核心是经济差而不是击杀数——击杀带来的人头赏金会体现在经济里直接用击杀差做特征反而会丢失信息。5.3 把系统当工具而不是黑匣子最后给你一个我常用的进阶习惯不要只拿它预测比赛把预测概率存到数据库里作为自己排位的复盘参考。比如我打完一局把这局前十分钟的数据输入平台跑完会得到一个蓝方胜率。如果模型给我的概率是 0.82 但实际输了那说明这局是逆风翻盘局如果概率是 0.35 反而赢了说明中后期的决策价值比前期经济差预估的更大。长此以往你会对游戏里的“滚雪球效应”有一个量化认知而不是停留在“我们这把打得好”的感觉层面。有一个教训我想提一下我从这个项目一开始训练就只盯着准确率后来发现准确率 0.74 和 0.73 之间的差异远不如 AUC 提升 0.03 来得有意义。从那以后我每次调参都强制走一遍重要度分析先把特征的重要度排序看明白再决定加参数还是加数据。希望帮到你。压缩包本身就是完整可复现的工程README 甚至把启动顺序都写清楚了直接照着跑一次比我干讲十遍都有用。本文还有配套的精品资源点击获取
RELATED

相关推荐

Hugging Face与NVIDIA GPU集成实战:模型加载、显存优化与推理部署

Hugging Face与NVIDIA GPU集成实战:模型加载、显存优化与推理部署

最近“黄仁勋,129亿美元拿下Hugging Face”的消息在技术社区传得很快。这里先提醒一句:收购是否属实,最终要等 NVIDIA 和 Hugging Face 的官方公告,任何网传金额和交易细节都不能当作确定事实。比起商业收购本身,这件事…

📅 2026/10/10 6:29:29
从Transformer到物理AI:长上下文瓶颈与线性注意力、状态空间模型解析

从Transformer到物理AI:长上下文瓶颈与线性注意力、状态空间模型解析

AI 圈最近有个说法很抓眼球:一位曾在英伟达负责 AI 方向的技术老兵,把矛头指向 Transformer,说要做到 5 万亿上下文的“物理 AI”,甚至推演整个宇宙。如果只看标题,这很容易被归入行业喇叭腔。但把它放到物理 AI 的语境…

📅 2026/10/10 6:29:29
电销语音机器人完整版源码部署与安装教程:从软交换到外呼落地

电销语音机器人完整版源码部署与安装教程:从软交换到外呼落地

简介:这份资源是一套电销语音机器人系统的完整源码及文字安装教程,面向需要搭建智能外呼与客户筛选能力的中小企业、开发者和运维人员。系统围绕资料接入、自主学习、筛选客户、人工跟进四个核心环节设计:机器人可一键导入海量客户资料&#…

📅 2026/10/10 6:29:29
MORE NEWS

更多资讯

📰

多模数据库实战指南:告别“数据库动物园”,重塑统一数据架构

在数据库这个圈子里待久了,你会发现一个很有意思的现象:各家企业的技术栈里,数据库往往是最“花花绿绿”的那一块。业务系统用MySQL,用户画像用Redis,搜索走Elasticsearch,图关系丢Neo4j,日志时…

📰

拓扑学如何成为数据科学底层逻辑:从持久同调到聚类降维

1. 从拓扑学到数据科学:为什么数学系的“冷门课”成了分析利器看到“拓扑学”三个字,很多做数据科学的朋友第一反应是“这和我的工作有什么关系”。我当年也是这么想的。直到做高维数据降维、做聚类评估、做流形学习的时候,发现一堆论文里反复…

📰

Mistral Large 4在网络安全中的实战能力与工程化落地

1. 项目概述:为什么“Mistral Large 4”在网络安全场景中不是工具,而是新一类协作者 最近在几个行业技术群和某高校实验室的攻防复盘会上,频繁听到一句评价:“用Mistral Large 4写规则、读日志、推演TTPs,像多了一个不…

📰

Linux压缩解压缩:从tar归档到zstd流式处理的工程实践

1. 项目概述:为什么“Linux 压缩与解压缩”不是一句命令,而是一套生存技能?在某高校实验室部署一批边缘计算节点时,我遇到过一个典型场景:运维同事发来一条消息:“打包失败,tar: Cannot write t…

📰

从零搭建本地记忆增强系统:claude-mem 项目拆解与实操

1. 从零搭建一个本地记忆增强系统:claude-mem 项目拆解第一次看到 claude-mem 这个项目名的时候,我脑子里蹦出来的第一个念头是:终于有人把「记忆」这件事从大模型的上下文窗口里拎出来单独做了。做过对话类应用的朋友应该都有体会&#xff0…

📰

msado15.dll 32位与64位注册兼容性实战指南

简介:本资源为Windows平台ADO数据库开发必备的msado15.dll全版本合集,面向C/VB等传统Windows桌面应用开发者、遗留系统维护工程师及COM组件调试人员,解决因架构不匹配导致的ADO组件注册失败、找不到指定模块或运行时崩溃等典型问题。压缩包共…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬