ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于Python的大学生就业预测与可视化平台开发实战

基于Python的大学生就业预测与可视化平台开发实战 简介这是一份基于Python的大学生就业情况分析平台完整项目实例面向具备Python基础的高校学生、研究人员及软件开发者帮助其掌握就业数据采集、清洗、建模预测与可视化展示的全流程实现。资源包共1个docx文档大小仅84KB虽体量精简但内容覆盖项目背景、系统架构、功能模块、数据库设计、API接口规范、前后端代码及部署方案并附有完整程序、GUI设计和代码详解。文档还针对多源异构数据集成、数据隐私、特征提取与模型适配等关键挑战给出解决思路支持高校、政府、企业和学生等多类用户场景。文档内含完整数据库脚本与GUI布局说明读者可逐步搭建环境运行调试深入理解数据流与业务逻辑。已有181人学习下载适合用于数据分析、数据库设计与全栈开发实训也便于在此基础上扩展知识图谱、深度学习等高级功能。1. 就业分析平台不是「做个网页」从学生表到预测与看板的一条完整链路教育大数据这个方向落到「基于 Python 的就业分析平台」上最容易被误解成做一个能看两眼的网页。实际上大学生就业情况智能预测与可视化系统的核心是把「数据库建表 → 数据清洗 → 特征工程 → 模型预测 → GUI 展示」整条链路打通让就业指导中心的老师不用碰代码也能点按操作提前圈出可能就业困难的学生。这类项目的价值不在算法有多深逻辑回归就足够出彩真正的难点是链路完整、口径自洽、每步都能复现。适合三类人正在做大数据相关毕业设计的学生校级就业数据岗位的从业者以及想亲手把机器学习接进业务系统、而不是只停留在跑通示例的开发者。2. 用 MySQL 把就业数据管起来建表、清洗与统计口径2.1 表结构设计学生、成绩、实习、就业四张表怎么拆先说环境。这类项目第一步永远不是写模型而是把 Python 环境装干净建议 Python 3.9 以上用 venv 建独立环境别把 pandas、pymysql、scikit-learn 这些装进全局解释器否则后期换项目时依赖打架会非常痛苦。在 VSCode 里配好解释器路径后按下面这份清单装依赖即可python -m venv .venv source .venv/bin/activate # Windows 下用 .venv\Scripts\activate pip install pandas pymysql sqlalchemy scikit-learn matplotlib openpyxl joblibpymysql 负责连 MySQLsqlalchemy 负责让 pandas 的 read_sql 更省心openpyxl 用来读教务导出的 Excel后面训练模型和画图全靠这批包。数据库选型上题目既然点名了数据库就用 MySQL 5.7 或 8.0别贪图省事换 SQLite——MySQL 能完整展示建库、增删改查、字符集管理更贴合教育大数据场景的评审预期。还要明确一点学生就业数据量级就是几千到几万行单机 MySQL 完全够用别为了「大数据」三个字去上 Hadoop、Spark 那套集群部署策略那只会把答辩时间耗在运维上。表结构我一般拆成四张而不是把所有字段堆在一张大宽表里CREATE DATABASE IF NOT EXISTS employment_db DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci; USE employment_db; CREATE TABLE student ( student_id VARCHAR(20) PRIMARY KEY, name VARCHAR(50) NOT NULL, gender TINYINT COMMENT 0-女 1-男, birthplace VARCHAR(50) COMMENT 生源地省份, city_type TINYINT COMMENT 0-农村 1-城市, college VARCHAR(50), major VARCHAR(50), is_party_member TINYINT DEFAULT 0 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE score ( id INT AUTO_INCREMENT PRIMARY KEY, student_id VARCHAR(20) NOT NULL, course_name VARCHAR(50), credit DECIMAL(4,1), score DECIMAL(5,1), semester VARCHAR(20), KEY idx_sid (student_id), CONSTRAINT fk_score_student FOREIGN KEY (student_id) REFERENCES student(student_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE internship ( id INT AUTO_INCREMENT PRIMARY KEY, student_id VARCHAR(20) NOT NULL, company_industry VARCHAR(50), duration_month INT, is_major_match TINYINT COMMENT 0-不对口 1-对口, has_offer TINYINT COMMENT 实习后是否拿到转正意向, KEY idx_sid (student_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE employment ( student_id VARCHAR(20) PRIMARY KEY, status TINYINT COMMENT 0-已就业 1-待就业, salary DECIMAL(10,2), work_type VARCHAR(30), employ_date DATE, CONSTRAINT fk_emp_student FOREIGN KEY (student_id) REFERENCES student(student_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;拆表的理由是数据来源不同、更新频率不同score 是每学期追加的internship 是实习期填的employment 是毕业季才有。外键约束保证学号在成绩表里不会变成无主数据给 score.student_id 加普通索引因为特征工程阶段要按学号聚合没有索引的 GROUP BY 在几万行上也能跑但别养成坏习惯。这里有个细节我不建议在 student 表上用 ON DELETE CASCADE教务数据删了要留痕宁可写删除逻辑时先做状态标记。2.2 数据清洗与编码空值、异常值、脏类型一次处理干净教务系统导出的 Excel 永远不会干净这是做就业平台的第一道坎也是最容易让新手翻车的地方。常见的脏数据有列名带着前后空格、成绩写成「92.5分」、性别是「男 」带空格、实习记录整行缺失。清洗原则很简单主键和关键属性不能空缺失率超过三成的列直接放弃而不是硬填数值先转类型再处理异常值。下面这段是我常用的清理脚本按表分别处理后再合并不要一上来就全表 dropnaimport pandas as pd from sqlalchemy import create_engine engine create_engine( mysqlpymysql://root:123456localhost:3306/employment_db?charsetutf8mb4 ) # 成绩表先转数值脏字符串全部变 NaN score_df pd.read_sql(SELECT student_id, course_name, score FROM score, engine) score_df[score] pd.to_numeric(score_df[score], errorscoerce) score_df score_df.dropna(subset[score]) # 实习表没有实习记录的学生用 0 填充时长单独留一个布尔特征 intern_df pd.read_sql( SELECT student_id, duration_month, is_major_match, has_offer FROM internship, engine ) intern_df intern_df.fillna(0) intern_df[has_offer] intern_df[has_offer].map({1: 1, 0: 0}).fillna(0).astype(int)逻辑说明pd.to_numeric 加 errorscoerce 会把「92.5分」这种值直接转成 NaN接着 dropna 把脏成绩行剔除这是处理脏格式最稳的组合。实习表里没有记录的学生duration_month 和 is_major_match 填 0 是正确的因为「没参加实习」和「参加 0 个月」在业务上等价但 has_offer 这种二值字段填 0 前要确认原始数据里确实没有「缺失」和「否」两种独立含义否则会污染标签。关于数据库连接GUI 单用户场景下一条连接足够重点是用完就还。我习惯把连接放进上下文管理器靠 with 语句自动 close如果后面要做可视化大屏、多个图表同时刷新查询再考虑 DBUtils 的 PooledDB 或 SQLAlchemy 连接池否则反复开关连接会出现 Cant connect 和 Too many connections。这一步属于常见的 mysql 连接池使用场景毕业设计阶段别过度设计。2.3 统计口径定死就业率、平均薪资怎么算才不打架可视化展示的数字和模型训练的标签必须同口径这是我做这类系统时最先写进文档的一条纪律。就业率的定义先写清楚分母是应就业学生数分子是已就业人数升学、出国、暂不就业的学生要不要排除必须在项目说明里写明否则同一个数字在不同页面会打架。一个最典型的统计坑是 LEFT JOIN 的过滤条件写错位置-- 各学院就业率分母是所有在校生分子是就业状态为已就业的人 SELECT s.college, COUNT(DISTINCT e.student_id) AS employed_cnt, COUNT(DISTINCT s.student_id) AS total_cnt, COUNT(DISTINCT e.student_id) / COUNT(DISTINCT s.student_id) AS employ_rate FROM student s LEFT JOIN employment e ON s.student_id e.student_id AND e.status 0 GROUP BY s.college;这里的重点是 e.status 0 必须写在 ON 子句里而不是 WHERE 子句里。写在 WHERE 会把未就业学生整行过滤掉导致分母变小、就业率虚高。薪资统计同理只统计 status 0 且有 salary 记录的人平均数容易受极少数高薪值影响建议同时在 pandas 里算中位数GUI 页面上两个值都展示。3. 特征工程与模型训练把学生画像变成可预测的数值3.1 特征工程学业、实习、生源怎么编码成训练列模型能学到什么取决于你喂什么特征。就业预测最常见的特征组是人口学属性性别、生源地、城乡、学业表现平均分、挂科数、课程门数、实习经历时长、是否对口、转正意向、在校表现党员、竞赛、干部。我一般先写一段聚合 SQL把四张表拉成一张宽表sql SELECT s.student_id, s.gender, s.city_type, s.major, s.is_party_member, AVG(sc.score) AS avg_score, SUM(CASE WHEN sc.score 60 THEN 1 ELSE 0 END) AS fail_cnt, COUNT(sc.course_name) AS course_cnt, IFNULL(MAX(i.duration_month), 0) AS max_intern_duration, IFNULL(SUM(i.is_major_match), 0) AS intern_match_cnt, IFNULL(MAX(i.has_offer), 0) AS has_offer FROM student s LEFT JOIN score sc ON s.student_id sc.student_id LEFT JOIN internship i ON s.student_id i.student_id GROUP BY s.student_id, s.gender, s.city_type, s.major, s.is_party_member raw pd.read_sql(sql, engine)这里用 IFNULL 而不是在 Python 里 fillna是因为 SQL 聚合完直接给 pandas 会更省事。注意 GROUP BY 后面必须把 student_id 之外的所有非聚合列都列全否则 MySQL 5.7 默认的 ONLY_FULL_GROUP_BY 模式会直接报错。宽表出来后真正的特征工程才开始核心是跨专业可比性。同样是平均分 85数学系和艺术系难度完全不同所以专业内排名比绝对分数更有区分度feats raw.copy() feats feats[feats[avg_score].notna()] # 没有任何成绩记录的学生剔除 # 专业内部的成绩百分位让分数跨专业可比 feats[gpa_pct] feats.groupby(major)[avg_score].rank(pctTrue) # 高基数类别用频次编码别用 one-hot也别用目标编码 major_freq feats[major].value_counts() feats[major_freq] feats[major].map(major_freq) # 标签1 表示待就业把少数类设成正类 label pd.read_sql(SELECT student_id, status FROM employment, engine) label[target] (label[status] 1).astype(int) data feats.merge(label.drop(columns[status]), onstudent_id, howinner)专业这种高基数类别one-hot 会产生几十列稀疏特征小数据上反而拖累逻辑回归目标编码虽然能提精度但直接用全量数据算均值会引入标签泄露新手别碰频次编码最稳。gpa_pct 用 rank(pctTrue) 算的是每个学生在他自己专业里的排位这样模型学到的是「在同学中处于什么水平」而不是一个绝对值。这里必须强调标签时间口径特征只能取预测时点之前能拿到的数据。如果你把毕业设计成绩、毕业后的转正结果混进特征来预测就业等于用未来预测未来模型在训练集上会好得不真实换一届新数据立刻崩掉。这个坑我放在第 5 章详细说但设计特征的时候就要开始防。3.2 模型选型与参数为什么先逻辑回归再拿随机森林做对照就业预测本质是二分类待就业还是已就业。模型选择我向来先定底线逻辑回归打底随机森林做对照。逻辑回归的优势是系数可以直接解释答辩时老师问「哪个因素影响最大」你直接把系数表拿出来随机森林能处理非线性关系还能输出特征重要性两个模型互为验证。几千上万条数据规模不建议上 XGBoost、LightGBM它们在小数据上容易过拟合调参的时间和收益不成正比而且解释起来绕。基准参数按这张表起步即可模型关键参数默认值到可用改什么选择理由LogisticRegressionC1.0, solverliblinear, max_iter1000特征先标准化C 在 0.1、1、10 里小范围试系数可解释答辩好讲RandomForestClassifiern_estimators300, max_depth6, min_samples_leaf5用 min_samples_leaf 抑制过拟合别追高 n_estimators能输出 feature_importances_和逻辑回归对照树模型不需要特征标准化逻辑回归必须标准化所以训练脚本里两个模型的预处理要分开处理。超参数在小数据上多少有点玄学GridSearchCV 在小范围网格里跑一遍就够了真正的精度提升来自 class_weight 和特征质量而不是把 max_depth 调大。3.3 训练与评估准确率 90% 也不可信混淆矩阵怎么读数据划分的第一原则是 stratify 按标签分层否则随机切分可能把少数类全分到测试集里。第二原则是标准化只能用训练集 fit再用同一套参数 transform 测试集全表 fit 会造成数据泄露。from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_report, confusion_matrix import joblib feature_cols [gender, city_type, is_party_member, avg_score, fail_cnt, course_cnt, max_intern_duration, intern_match_cnt, has_offer, gpa_pct, major_freq] X data[feature_cols].fillna(0) y data[target] # 1 待就业正类是少数类 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, random_state42, stratifyy) scaler StandardScaler() X_train_s scaler.fit_transform(X_train) X_test_s scaler.transform(X_test) clf LogisticRegression(class_weightbalanced, C1.0, solverliblinear, max_iter1000) clf.fit(X_train_s, y_train) print(classification_report(y_test, clf.predict(X_test_s))) print(confusion_matrix(y_test, clf.predict(X_test_s))) joblib.dump({model: clf, scaler: scaler, feature_names: feature_cols}, employment_model.joblib)class_weightbalanced 让模型自动加大少数类的惩罚权重这是对付不平衡数据的第一层手段。random_state42 固定下来是为了复现答辩时老师可能让你重跑一遍结果对不上会非常尴尬。最后用 joblib 保存时我习惯存一个字典而不是只存模型把 feature_names 一起存进去这是给未来的自己留后悔药GUI 端预测时列顺序错了reindex 一下就能救回来。评估阶段最容易被准确率骗。如果就业率是 92%模型全猜已就业也有 92% 准确率但待就业的学生一个都抓不住。所以 classification_report 里重点看正类待就业的 recall混淆矩阵里看右下角真正类有多少。随机森林的对照训练不需要 StandardScalerrf RandomForestClassifier(n_estimators300, max_depth6, min_samples_leaf5, class_weightbalanced, random_state42) rf.fit(X_train, y_train)两个模型哪个 recall 高就用哪个或者把两者概率平均。记住一个经验准确率高不代表预测有用抓到多少真正难就业的学生才是这个系统的 KPI。4. 可视化与 GUI 设计把模型装成教务能点按的系统4.1 可视化选型matplotlib 进 GUI、pyecharts 出大屏就业分析这类 python 数据分析与可视化项目可视化选型通常分两条路要嵌进桌面 GUI就选 matplotlib要做校园大数据可视化大屏就选 pyecharts 生成 HTML它在底层封装的是 ECharts交互效果比 matplotlib 强一个档次。库优势短板本项目用在哪matplotlib标准生态、能直接嵌 Tkinter 画布交互弱、样式偏学术论文插图、GUI 内嵌图表seaborn统计图表好看、一行出相关性热力图依赖 matplotlib交互同样弱特征相关性分析pyecharts图表交互强、能生成可视化大屏嵌 Tkinter 麻烦要借浏览器或 QWebEngineView答辩演示、网页大屏我的选择是主界面用 matplotlib 嵌入图都画在 GUI 右侧面板里另做一个 pyecharts 大屏 HTML 作为演示备用。就业分析里最有说服力的四张图是各学院就业率对比柱状图、近三届就业率趋势折线图、签约薪资分布直方图、特征重要性横向条形图。最后这张图放到 GUI 里答辩时直接告诉老师「挂科数、实习时长、成绩专业排名是影响就业的前三个因素」比念 PPT 有效得多。4.2 GUI 框架tkinter 起步、PyQt5 进阶别一上来就选重型框架GUI 框架的选择我建议按答辩环境的兼容性倒推。tkinter 是标准库任何装了 Python 的机器都能跑打包体积小Matplotlib 官方提供 FigureCanvasTkAgg 直接嵌入缺点是表格控件弱、界面朴素。PyQt5 好看、QTableWidget 强、能嵌 QWebEngineView 加载 pyecharts但打包体积轻松到 80MB 以上答辩机器上缺 DLL 的概率也更高。我的做法是 tkinter ttk.Treeview 做学生信息表格图表用 FigureCanvasTkAgg 嵌 matplotlib功能完全够用。布局采用左侧功能树、右侧主面板的结构功能树放「数据导入」「就业率看板」「单生预测」「批量预测」主面板上方是表单区下方是图表画布。如果以后想升级美观度再迁 PyQt5业务逻辑层和数据访问层分开写的话迁移成本很低。4.3 系统主流程点一次「预测」按钮后端到底做了什么GUI 的主流程其实只有三件事收集表单字段、组装特征向量、调用模型并回显结果。这段代码是整个系统的核心也是最容易踩坑的地方import tkinter as tk from tkinter import ttk import joblib import pandas as pd from matplotlib.figure import Figure from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg pkg joblib.load(employment_model.joblib) model, scaler, feature_names pkg[model], pkg[scaler], pkg[feature_names] def build_feature_row(form_values): # 字段顺序必须和训练时的 feature_names 一致 d { gender: 1 if form_values[gender] 男 else 0, city_type: 1 if form_values[city_type] 城市 else 0, is_party_member: 1 if form_values[is_party] 是 else 0, avg_score: float(form_values[avg_score]), fail_cnt: int(form_values[fail_cnt]), course_cnt: int(form_values[course_cnt]), max_intern_duration: int(form_values[intern_duration]), intern_match_cnt: int(form_values[intern_match_cnt]), has_offer: 1 if form_values[has_offer] 是 else 0, gpa_pct: float(form_values[gpa_pct]), major_freq: int(form_values[major_freq]), } row pd.DataFrame([d]).reindex(columnsfeature_names).fillna(0) return scaler.transform(row) def on_predict_click(): row build_feature_row(form_values) prob model.predict_proba(row)[0][1] # 1 的概率 待就业概率 label_var.set(f预测结果待就业概率 {prob:.1%}) # 写回数据库留作后续对比验证 with engine.connect() as conn: conn.execute( INSERT INTO predict_log(student_id, prob, predict_time) VALUES (%s, %s, NOW()) ON DUPLICATE KEY UPDATE probVALUES(prob), (form_values[student_id], float(prob)), )build_feature_row 里最容易出错的点是GUI 表单字段的顺序由前端布局决定训练时的列顺序由 DataFrame 决定两者没有任何天然关联。reindex(columnsfeature_names) 这一步就是在强行对齐少写这行模型报的维度错误会让你排查半小时。predict_proba 返回的二维数组[0][1] 是正类待就业的概率演示时把小数点后两位转成百分比读给老师听比直接抛一个 0.87 清楚得多。数据库增删改查也是系统完整性的硬指标。学生信息管理页面用 ttk.Treeview 承载表格增删改分别对应 INSERT、UPDATE、DELETE 三条 SQL删数据前先弹确认框这个交互细节在答辩演示时很加分。整个系统跑起来后我还会在左侧功能树加一个「从数据库随机抽一名学生预测」的按钮演示时不需要手填表单点一下自动填完再预测流畅度完全不同。5. 就业预测平台的排查笔记4 个高频坑与对应解法这一章写的是这类大数据相关毕业设计项目里反复翻车的四个位置全部来自真实开发中踩过的坑。每一条都按「现象 → 原因 → 解决」讲清楚希望能帮你绕开同样的路。5.1 模型侧的坑标签泄漏和数据不平衡坑 1训练集准确率 95%换一届新学生数据预测结果全崩现象分类报告漂亮得不像话训练集和测试集都 95% 以上但把模型接到 GUI 里预测下一届学生结果明显不合理或者特征里出现「用未来预测未来」的荒唐逻辑。原因标签泄漏。最常见的是把毕业后的实习转正结果、毕业设计成绩、就业月薪当特征喂进了模型。另一个隐蔽版本是数据清洗时用全量数据算均值、中位数填充缺失值再切训练测试集填充信息已经从测试集流进了训练集。解决特征设计阶段就给每个字段标上「可获取时点」只能使用预测时点之前能拿到的数据。缺失值填充必须在 train_test_split 之后做要么用训练集的统计量填测试集要么干脆用 SimpleImputer 配合 Pipeline。答辩时主动讲出「我排除了所有时点之后才能获得的信息」反而是加分项。坑 2准确率 90% 但待就业学生一个都没抓住现象classification_report 里已就业类的精确率召回率都很高待就业类的 recall 是 0混淆矩阵右下角是 0。原因数据不平衡就业率太高模型学到的策略就是全猜已就业准确率照样好看。解决train_test_split 加 stratifyy 保持切分比例模型加 class_weightbalanced评估指标从 accuracy 换成待就业类的 recall 和 F1。如果想进一步压阈值用 predict_proba 拿到概率后自己定判定线别直接用默认的 0.5具体做法在第 6 章展开。5.2 工程侧的坑模型封装与中文乱码坑 3训练好好的封装进 GUI 一 predict 就报维度错误现象脚本里跑模型一切正常GUI 点击预测按钮后报 X has N features, but the model is expecting M features或者结果明显张冠李戴。原因训练时 DataFrame 的列顺序和 GUI 手拼的特征顺序不一致或者某个类别字段编码方式变了。还有一个隐蔽版本训练环境和 GUI 环境的 scikit-learn 版本不一致旧版本训练出的模型文件被新版本加载时行为异常。解决joblib 保存时把 feature_names 一起存预测前用 reindex(columnsfeature_names) 强制对齐把 requirements.txt 里的 scikit-learn 版本锁死训练和部署用同一套环境。这是模型封装里最常见的坑也是「后悔药」那个习惯的来由。坑 4GUI 图表全是方块MySQL 里中文变问号现象matplotlib 画的图标题、图例全部显示成方块往数据库写学生姓名后查出来是 ???直接执行 SQL 插入中文报 charset 错误。原因matplotlib 默认字体里没有中文字形需要指定中文字体MySQL 连接串没带 charset 参数或者建库时用了默认的 latin1。解决画图前加两行配置plt.rcParams[font.sans-serif] [SimHei] 和 plt.rcParams[axes.unicode_minus] False前者解决中文方块后者解决负号不显示。连接串写成 mysqlpymysql://root:123456localhost:3306/employment_db?charsetutf8mb4建库语句带上 DEFAULT CHARACTER SET utf8mb4。如果部署在 Linux 服务器上SimHei 不存在改用 WenQuanYi Zen Hei 或 Noto Sans CJK SC并在服务器上安装字体。6. 进阶技巧给预测结果加置信度与特征贡献度很多就业预测系统做完就停在「输出一个分类」上但老师真正需要的是「这个判断有多确定为什么这么说」。进阶做法是把分类输出换成概率输出并给出可解释的风险因素这一步让系统从展示结果变成指导行动。先定义双阈值。待就业概率 p 大于等于 0.65 标记为「重点关注」低于 0.35 标记为「就业稳妥」中间区域是「持续观察」。0.35 和 0.65 不是拍脑袋定的它们来自业务代价漏掉一个真正难就业的学生比多联系一个其实没问题的学生代价高得多所以下阈值压到 0.35宁可多观察也不漏人。prob model.predict_proba(row)[0][1] # 待就业概率 if prob 0.65: level 重点关注 elif prob 0.35: level 就业稳妥 else: level 持续观察解释性上逻辑回归的系数可以直接用。对特征系数排序负向系数最大的三个就是风险因素coef pd.Series(model.coef_[0], indexfeature_names).sort_values() top_risks coef.head(3) # 负向系数最大的三个挂科数、实习时长、专业内排名通常位列其中。GUI 里把这三个字段显示成「本学生主要风险因素挂科 4 门、无实习经历、专业排名后 30%」老师一眼就能看懂不是对着一个黑匣子点头。最后给一个验证进阶别只用随机切分做一次时间外验证。拿上一届学生数据训练用新一届数据测试模型泛化能力一目了然。这是就业预测平台从「毕业设计作业」变成「能实际使用的工具」的关键一步。我现在拿到任何分类项目都习惯先看 predict_proba 的概率分布再定阈值模型训完先做时间外验证再往 GUI 里接。这两个习惯救了我好几次也推荐给你。希望帮到你。本文还有配套的精品资源点击获取
返回列表