
ML-For-Beginners用 Pickle 序列化 Scikit-learn 模型并通过 Flask 构建 UFO 预测 Web 应用【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners本课是 ML-For-Beginners 课程第 3 周Web App 部分的核心实战课使用约 8 万条来自 NUFORCNational UFO Reporting Center的 UFO 目击记录训练一个逻辑回归模型学习把训练好的模型用 Pickle 序列化成.pkl文件再将其接入一个 Flask Web 应用让用户在网页表单中输入目击时长秒、纬度、经度即可获得该 UFO 最可能出现在哪个国家的预测结果。读完本文你可以掌握「数据清洗 → 训练 → 序列化 → Web 服务化」这条把机器学习模型推向野外in the wild的完整链路并能对照 solution 目录 中的成品代码自行复现整个应用。一、为什么要把模型放进 Web 应用在 Notebook 里训练模型只是第一步。在真实业务中数据科学团队训练出的模型往往需要被一个 Web 或移动端应用消费——而你的 Web 架构选择甚至会反过来影响模型该怎么训练、以什么格式导出。在动手之前需要回答几个关键问题是 Web 应用还是移动端应用如果构建的是移动端应用或需要在 IoT 场景使用模型可以考虑 TensorFlow Lite把模型用于 Android 或 iOS 应用。模型部署在哪里云端还是本地是否需要离线支持应用是否必须在断网状态下工作模型是用什么技术栈训练的这决定了你需要哪些配套工具TensorFlow该生态系统提供把 TensorFlow 模型转换为可在 Web 应用中使用的形式的能力对应工具是 TensorFlow.jsPyTorch可以把模型导出为 ONNXOpen Neural Network Exchange格式供使用 Onnx Runtime 的 JavaScript Web 应用调用。课程后续会在 Scikit-learn 训练的模型上探索这一路线Lobe.ai / Azure Custom Vision 等 ML SaaS 平台这类平台提供把模型导出到多个平台的能力包括构建一个供在线应用在云端查询的定制化 API。此外还有一种更激进的做法构建一个完整的 Flask Web 应用让模型直接在 Web 浏览器中训练在 JavaScript 语境下可用 TensorFlow.js 实现。本课的设定是我们一直在使用基于 Python 的 Notebook因此重点走从 Notebook 导出训练好的模型转换为 Python 构建的 Web 应用可读取的格式这条路径即本文的主线Pickle Flask。二、两个核心工具Flask 与 Pickle本课只需要两个都运行在 Python 上的工具Flask由创造者自称为micro-framework的微框架用 Python 提供 Web 框架的基础功能并内置模板引擎Jinja2 mustache 风格语法用于构建网页。PicklePython 标准库模块负责序列化serialize与反序列化de-serializePython 对象结构。pickle a model 就是把模型的内部结构序列化、扁平化使其可以作为普通文件后缀为.pkl在 Web 服务中加载。⚠️ 需要注意Pickle 本身并不具备安全性——对来源不明的.pkl文件执行pickle.load即 un-pickle存在执行任意代码的风险在生产环境中务必只加载自己生成的模型文件。三、数据准备8 万条 UFO 目击记录本课数据来自 NUFORC对应仓库中的 ufos.csv。该文件约含 8 万行记录80,000 条目击事件表头为datetime, city, state, country, shape, duration (seconds), duration (hours/min), comments, date posted, latitude, longitude其中country字段取值有限实测主要为us、ca、gb、au、de及空值comments字段则包含一些有趣的描述例如长描述A man emerges from a beam of light that shines on a grassy field at night and he runs towards the Texas Instruments parking lot短描述the lights chased us接下来在课程提供的空白 notebook 中按步骤完成清洗完整可运行的版本见 solution/notebook.ipynb3.1 导入依赖并读取数据import pandas as pd import numpy as np ufos pd.read_csv(./data/ufos.csv) ufos.head()3.2 构造精简 DataFrame 并检查唯一值只保留建模需要的四列并重命名为更清晰的字段名同时检查Country字段的唯一值ufos pd.DataFrame({Seconds: ufos[duration (seconds)], Country: ufos[country], Latitude: ufos[latitude], Longitude: ufos[longitude]}) ufos.Country.unique()3.3 剔除空值并过滤时长范围丢弃含 null 的行并只保留目击时长在 160 秒之间的记录把数据量压缩到模型易处理的规模ufos.dropna(inplaceTrue) ufos ufos[(ufos[Seconds] 1) (ufos[Seconds] 60)] ufos.info()3.4 用 LabelEncoder 对国家做数值编码导入 Scikit-learn 的LabelEncoder把国家文本转换为数字。注意LabelEncoder 按字母顺序编码过滤后剩下的 5 个国家对应的编码为Australia0、Canada1、Germany2、UK(gb)3、US(us)4——这正是后面 Flask 应用里countries列表的顺序依据。from sklearn.preprocessing import LabelEncoder ufos[Country] LabelEncoder().fit_transform(ufos[Country]) ufos.head()编码后的数据形如Seconds Country Latitude Longitude 2 20.0 3 53.200000 -2.916667 3 20.0 4 28.978333 -96.645833 14 30.0 4 35.823889 -80.253611 23 60.0 4 45.582778 -122.352222 24 3.0 3 51.783333 -0.783333四、训练模型逻辑回归预测国家4.1 划分特征与训练/测试集选取Seconds、Latitude、Longitude三个特征作为 X 向量Country作为标签 y——目标是输入时长与经纬度输出国家编码from sklearn.model_selection import train_test_split Selected_features [Seconds, Latitude, Longitude] X ufos[Selected_features] y ufos[Country] X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state0)test_size0.2表示 20% 数据用于测试random_state0固定随机种子保证结果可复现。4.2 训练并评估from sklearn.metrics import accuracy_score, classification_report from sklearn.linear_model import LogisticRegression model LogisticRegression() model.fit(X_train, y_train) predictions model.predict(X_test) print(classification_report(y_test, predictions)) print(Predicted labels: , predictions) print(Accuracy: , accuracy_score(y_test, predictions))文档给出的准确率约为95%——这并不令人意外因为Country与Latitude/Longitude强相关经纬度本身就基本决定了国家。这个模型并不革命性但它是一个很好的练习从原始数据清洗、导出到把模型真正用起来。五、pickle 你的模型训练完成后只需几行代码即可把模型序列化为ufo-model.pkl。序列化后应重新加载该.pkl文件并用样例数据验证确保加载的模型与原模型行为一致import pickle model_filename ufo-model.pkl pickle.dump(model, open(model_filename, wb)) model pickle.load(open(ufo-model.pkl, rb)) print(model.predict([[50, 44, -12]]))模型返回3即编码表中 UK英国的国家码。仓库的 solution/ufo-model.pkl 就是本课训练产出的成品模型文件约 1KB可直接用于验证 Flask 应用。这里值得强调一个关键点送进模型做预测的数据形状完全取决于模型当初是怎么训练的。本模型要求一个[seconds, latitude, longitude]的三元素样本如果训练时特征顺序、数量或编码方式变了消费端必须同步修改。在专业环境中训练模型的人和使用模型构建 Web/移动应用的人之间必须有清晰的沟通。六、构建 Flask Web 应用6.1 目录结构在存放notebook.ipynb与ufo-model.pkl的目录旁创建web-app文件夹其中包含static/css与templates两个子目录web-app/ static/ css/ templates/ notebook.ipynb ufo-model.pkl6.2 requirements.txtPython 应用的package.json在web-app下创建requirements.txt列出应用所需依赖与 solution 中的实际文件 一致scikit-learn pandas numpy flask然后安装cd web-app pip install -r requirements.txt6.3 static/css/styles.css页面样式body { width: 100%; height: 100%; font-family: Helvetica; background: black; color: #fff; text-align: center; letter-spacing: 1.4px; font-size: 30px; } input { min-width: 150px; } .grid { width: 300px; border: 1px solid #2d2d2d; display: grid; justify-content: center; margin: 20px auto; } .box { color: #fff; background: #2d2d2d; padding: 12px; display: inline-block; }黑色背景 白色文字 深灰卡片.grid/.box构成了这个UFO 主题页面的视觉基调。6.4 templates/index.html模板与表单!DOCTYPE html html head meta charsetUTF-8 title UFO Appearance Prediction! /title link relstylesheet href{{ url_for(static, filenamecss/styles.css) }} /head body div classgrid div classbox pAccording to the number of seconds, latitude and longitude, which country is likely to have reported seeing a UFO?/p form action{{ url_for(predict)}} methodpost input typenumber nameseconds placeholderSeconds requiredrequired min0 max60 / input typetext namelatitude placeholderLatitude requiredrequired / input typetext namelongitude placeholderLongitude requiredrequired / button typesubmit classbtnPredict country where the UFO is seen/button /form p{{ prediction_text }}/p /div /div /body /html注意其中的mustache 模板语法{{ }}{{ url_for(static, filenamecss/styles.css) }}由 Flask 解析出静态资源 URL表单的action{{ url_for(predict) }}把提交指向名为predict的视图函数即/predict路由方法为 POST{{ prediction_text }}是占位符由app.py在响应时传入预测结果文本。这与仓库中 solution/templates/index.html 的成品模板一致。6.5 app.py驱动模型消费与预测展示import numpy as np from flask import Flask, request, render_template import pickle app Flask(__name__) model pickle.load(open(./ufo-model.pkl, rb)) app.route(/) def home(): return render_template(index.html) app.route(/predict, methods[POST]) def predict(): int_features [int(x) for x in request.form.values()] final_features [np.array(int_features)] prediction model.predict(final_features) output prediction[0] countries [Australia, Canada, Germany, UK, US] return render_template( index.html, prediction_textLikely country: {}.format(countries[output]) ) if __name__ __main__: app.run(debugTrue)运行python app.py或python3 app.py即可在本地启动 Web 服务器填写表单即可得到答案。代码逐段拆解如下依赖加载与应用启动Flask(__name__)实例创建应用模型导入pickle.load(open(./ufo-model.pkl, rb))在应用启动时一次性加载 pickled 模型。这里open使用rb二进制读模式与序列化时的wb写模式对应/路由渲染index.html首页/predict路由表单 POST 后触发request.form.values()收集三个表单值逐个int(x)转换后封装为np.array并再包一层列表[np.array(...)]构成形状为 (1, 3) 的二维样本——这正对应模型训练时X_train的二维矩阵形状model.predict(final_features)返回预测的国家编码取prediction[0]用硬编码列表countries [Australia, Canada, Germany, UK, US]把编码还原为可读国家名。再次注意这个列表的顺序必须与 LabelEncoder 的字母序编码严格一致最终把prediction_textLikely country: {国家名}传回模板渲染。 提示app.run(debugTrue)会开启 Flask 调试模式任何代码改动都会即时生效、无需重启服务器。但切勿在生产应用启用此模式调试模式会暴露交互式控制台。一个值得注意的源码级细节solution 中的成品 app.py 加载模型的路径是pickle.load(open(../ufo-model.pkl, rb))相对当前 README 版本中的./ufo-model.pkl多向上一级——因为仓库中成品模型文件ufo-model.pkl与notebook.ipynb同放在 solution/ 目录而app.py位于其下的web-app/子目录中。这说明.pkl文件与app.py的相对位置由你的目录布局决定按自己实际的文件摆放位置调整该路径即可。从源码结构看整个 Flask 应用的职责非常单一把表单的三个整数转成 (1, 3) 的 numpy 数组 → 交给模型 → 把编码映射回国家名。这也是本课的核心认知——用 Flask pickled 模型消费模型本身相当直接最难的是搞清楚该送什么形状的数据给模型而这完全取决于训练阶段的设计。七、挑战与延伸阅读 Challenge在 Flask 应用内直接训练不必非要在 Notebook 中训练再导入模型——可以尝试直接在 Flask 应用内训练把 Notebook 中数据清洗之后的 Python 代码搬进应用新增一个名为train的路由来完成训练。思考这种方式的优缺点例如训练逻辑与 Web 服务耦合、部署包需要携带数据、启动时间变长好处是模型与代码永远一致等。Assignment换一个模型按 assignment.md 的要求用前面 Regression 课程中的任一模型例如南瓜数据集上的回归模型重做这个 Web 应用可以保留样式也可以重新设计以呼应南瓜数据务必同步修改输入项以匹配新模型的训练方式。评分标准应用应能按预期运行并部署到云端Exemplary存在瑕疵或意外结果Adequate应用无法正常工作Needs Improvement。Review Self Study尝试列出你所能想到的、用 JavaScript 或 Python 构建 Web 应用来消费机器学习模型的方式。思考架构问题模型应该留在应用内部还是放在云端如果放云端该如何访问它为一个应用级 ML Web 方案画出架构模型图。八、本课要点回顾环节关键操作关键知识点数据清洗dropna 时长过滤1~60 秒把 8 万条原始记录压缩到建模可用规模特征工程LabelEncoder().fit_transform按字母序编码Australia0 … UK3, US4训练LogisticRegressiontrain_test_split(test_size0.2, random_state0)准确率约 95%因经纬度与国家强相关序列化pickle.dump/pickle.load.pkl后缀序列化后必须重新加载验证Pickle 有安全风险Web 化Flask 路由/与/predictrequirements.txt管理依赖输入需转成 (1, 3) 二维数组编码映射表顺序必须与编码一致部署pip install -r requirements.txtpython app.pydebugTrue仅限开发环境通过这条「Notebook 清洗训练 → Pickle 序列化 → Flask 服务化」的最小完整链路你完成了 ML-For-Beginners 课程中从会训练模型到能让用户在浏览器里使用模型的跨越后续课程还会在 Scikit-learn 模型上探索 ONNX 导出等面向 JavaScript 消费端的模型格式。【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考