
ML-For-Beginners 实战用 Flask 与 Pickle 将 Scikit-learn 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 课程的 Web 应用章节中你将完成一次完整的模型落地之旅基于 NUFORC 近一个世纪约 8 万条 UFO 目击记录在 Jupyter Notebook 中完成数据清洗、特征选择与逻辑回归训练将训练好的模型用 Pickle 序列化为.pkl文件再通过 Flask 微框架构建一个可交互的 Web 表单应用让用户输入观测时长、纬度和经度即可预测目击国家。读完本文你将掌握从 Notebook 导出模型、构建 Flask 路由与模板渲染、处理表单数据并驱动模型推理的完整链路并能直接在仓库 3-Web-App/1-Web-App 中找到全部配套文件进行复现。模型落地前的架构考量先回答四个问题把机器学习模型真正用起来in the wild首先要想清楚应用的形态与部署边界。在动手写代码前文档给出了一组必须回答的问题是 Web 应用还是移动应用如果目标是 Android/iOS 或 IoT 场景可以选用 TensorFlow Lite 将模型内嵌到移动端模型放在哪里云端还是本地这决定了推理请求的链路是否需要离线支持应用在无网络环境下是否必须可用模型是用什么技术训练的训练技术直接决定部署工具链TensorFlow可借助 TensorFlow.js 把模型转换后在浏览器/Node.js 中使用PyTorch可导出为 ONNXOpen Neural Network Exchange格式配合 Onnx Runtime 供 JavaScript Web 应用调用Lobe.ai / Azure Custom Vision 等 ML SaaS这类平台通常支持多平台导出甚至可以直接构建云端 API 供在线应用查询。从源码结构看本仓库的姊妹章节 4-Classification/4-Applied 正是 ONNX 导出路线在 Scikit-learn 模型上的落地实践印证了文档中ONNX 路线将在未来课程中探索的规划。而本章采取的是最贴合 Python 技术栈的路线Notebook 训练 → Pickle 序列化 → Flask Web 应用消费。因为此前所有课程都在 Python Notebook 中工作这条路线迁移成本最低也最能完整展示训练—导出—部署—推理的闭环。工具准备Flask 与 Pickle本任务只需要两个 Python 工具Flask由 Pallets 项目维护的微框架micro-framework提供 Web 框架的核心能力路由、请求处理与 Jinja 模板引擎用极少量代码即可渲染 HTML 页面PicklePython 标准库模块用于将 Python 对象结构序列化serialize与反序列化de-serialize。对模型执行 pickle 操作等于把它的结构拍平成字节流便于存储和跨进程传输。序列化产物的标准后缀是.pkl。需要特别警惕的是pickle 本质上并不安全反序列化un-pickle来历不明的文件可能执行恶意代码因此永远不要加载不可信来源的.pkl文件。第一步清洗 UFO 目击数据课程使用 ufos.csv 数据表它由 NUFORC美国国家 UFO 报告中心收集的 8 万余条目击记录构成包含目击发生的city、state、country、物体shape、latitude与longitude等字段以及相当有画面感的comments描述——长如一名男子从照在夜晚草场上的一束光中现身朝德州仪器停车场跑去短如那些灯在追我们。在课程附带的空白 notebook.ipynb 中按以下步骤完成清洗仓库 solution/notebook.ipynb 提供了每一步的实际运行结果可对照1. 导入库并加载数据import pandas as pd import numpy as np ufos pd.read_csv(./data/ufos.csv) ufos.head()2. 抽取需要的列重建一个小型 DataFrame并查看Country的取值分布ufos pd.DataFrame({Seconds: ufos[duration (seconds)], Country: ufos[country],Latitude: ufos[latitude],Longitude: ufos[longitude]}) ufos.Country.unique()3. 去掉空值只保留时长在 160 秒之间的目击记录降低数据量ufos.dropna(inplaceTrue) ufos ufos[(ufos[Seconds] 1) (ufos[Seconds] 60)] ufos.info()4. 用 Scikit-learn 的LabelEncoder把国家文本值按字母序编码为数字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对照 solution/notebook.ipynb 的实际输出可以看到更完整的上下文清洗后数据从 8 万余行收敛为25,863 行Country字段的原始取值为[us, nan, gb, ca, au, de]经LabelEncoder按字母序编码后得到映射0au, 1ca, 2de, 3gb, 4us。这个编码顺序将在后面 Flask 应用把预测数字还原为国家名时被直接引用——训练端与消费端必须严格对齐这是本课程反复强调的关键点。第二步训练逻辑回归分类器接下来划分训练集与测试集并训练模型。选择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)随后用逻辑回归训练并评估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存在天然的地理关联模型本质上是由经纬度反推国家。仓库中的实际运行输出提供了更细粒度的证据测试集共5,173 条accuracy为0.9513但分类报告也暴露出数据不平衡问题——类别 4us独占 4,743 条样本而类别 2de仅 8 条、precision 为 0.00类别 1carecall 仅 0.02。这正是文档提醒的模型本身并不革命但它完整覆盖了从原始数据清洗、特征抽取到模型落地的练习价值。第三步用 Pickle 序列化模型训练完成后用几行代码把模型 pickle 起来再重新加载并做一次推理验证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]]))输入[50, 44, -12]50 秒时长、纬度 44、经度 -12约对应北大西洋东部后模型返回3——即国家编码 3对应gb英国。仓库 solution/notebook.ipynb 的第 29 个单元格记录了相同的输出[3]与该编码表完全吻合。至此ufo-model.pkl就成为了可供任何 Python 进程加载的可移植模型。第四步构建 Flask 应用现在把模型装进一个可视化的 Web 应用。先创建目录结构在存放ufo-model.pkl的notebook.ipynb旁边新建web-app文件夹内部再建static/css与templates两个子目录web-app/ static/ css/ templates/ notebook.ipynb ufo-model.pkl4.1 声明依赖requirements.txtrequirements.txt之于 Python 应用正如package.json之于 JavaScript 应用用于声明运行所需的依赖。写入以下四行并安装scikit-learn pandas numpy flaskcd web-app pip install -r requirements.txt仓库 solution/web-app/requirements.txt 与文档完全一致可直接作为模板。4.2 编写样式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; }4.3 编写模板templates/index.html模板文件同时完成两件事渲染一个向/predict路由 POST 的表单用 Jinja 的胡子语法{{ }}输出应用端传入的prediction_text预测结果!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注意两个细节seconds输入框通过min0 max60在浏览器层约束取值区间与训练时 160 秒的过滤逻辑呼应url_for(static, filenamecss/styles.css)是 Flask 生成静态资源 URL 的推荐写法url_for(predict)则按视图函数名反向解析出/predict路径避免硬编码 URL。仓库 solution/web-app/templates/index.html 提供了成品参考。4.4 编写应用入口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)逐段拆解其工作流导入numpy、Flask 的Flask/request/render_template与pickle创建应用实例在模块加载时即把ufo-model.pkl反序列化为内存中的model对象模型只需加载一次避免每次请求重复读盘根路由/渲染index.html首页/predict路由仅接受 POST收集request.form中所有表单值并转为整数列表包装成 numpy 数组后送入model.predict()得到预测编码用硬编码的国家列表[Australia, Canada, Germany, UK, US]将编码还原为可读文本——该列表的顺序正是此前LabelEncoder的字母序编码0au, 1ca, 2de, 3gb, 4us的镜像将结果作为prediction_text回传模板渲染。路径兼容性提示文档示例中模型路径写作./ufo-model.pkl但仓库 solution/web-app/app.py 中实际使用的是../ufo-model.pkl——因为 solution 目录里ufo-model.pkl与web-app文件夹同级位于solution/下。请务必根据自己模型文件的真实存放位置调整该路径否则应用启动时会因找不到文件而报错。 提示app.run(debugTrue)开启调试模式后代码改动会即时生效无需手动重启服务适合开发期迭代生产环境切勿开启它会暴露调试器并带来安全风险。4.5 启动应用python app.py # 或 python3 app.pyWeb 服务将在本地启动浏览器中即可填写秒数、纬度、经度三个字段回车获得如Likely country: UK的预测答案。深入理解为何数据形状是部署中最容易出错的一环用 Flask pickled 模型的方式消费模型整体链路相当直接文档指出真正的难点在于搞清喂给模型的数据形状——它完全取决于训练时的定义。本模型中训练时model.fit(X_train, y_train)的 X 是 3 个特征Seconds、Latitude、Longitude因此predict()也必须接收形状为(1, 3)的二维数组这就是final_features [np.array(int_features)]再做一层嵌套列表的原因若直接传入一维列表Scikit-learn 会因特征维度不匹配而报错。在真实的工程协作中这恰恰体现了训练团队与消费团队之间清晰沟通的必要性模型输入有几个特征、顺序如何、编码映射是什么都必须有明确约定。在本课程里训练者与使用者是同一个人——你正好可以完整体验这份契约的建立过程。进阶挑战把训练搬进 Flask 应用本章的 Challenge 提供了一个反向思路不在 Notebook 里训练后导入模型而是把 Notebook 中的清洗与训练代码至少从数据清洗之后的部分直接搬进 Flask 应用在一条名为train的路由中完成训练。你可以就此评估两条路线的利弊——例如在应用内训练可以省去序列化/导入环节、数据更新后一键重训但首次请求会阻塞且耗时模型参数与数据要打进同一份部署包难以与工程化部署CI/CD、模型版本管理解耦。这是一个值得动手实验的架构权衡题。延伸学习与作业课程后的自我学习建议列举用 JavaScript 或 Python 构建 ML Web 应用的各种途径重点思考模型应内嵌在应用里还是托管在云端若在云端又该如何访问并画出一张 ML Web 解决方案的架构草图配套作业 assignment.md 要求尝试换用不同的模型完成同样的部署流程是检验本章理解的最佳实践仓库中的完整成品可直接对照solution/web-app 目录下的app.py、requirements.txt、templates/index.html、static/css/styles.css以及solution/ufo-model.pkl预训练模型文件。至此你已经走通了Notebook 训练 → Pickle 序列化 → Flask 表单应用 → 实时预测的完整闭环掌握了把任意 Scikit-learn 模型快速包装成可交互 Web 应用的方法论。【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考