学会如何将机器学习模型从开发带到生产,使用例如 Google Colab 等工具来构建模型,并使用 Docker 部署可扩展的应用。
探索MLOps之旅(注:MLOps是机器学习操作的简称)
MLOps是什么东西?
MLOps,即机器学习运维,是指将机器学习(ML)系统集成到生产环境中,并确保这些系统能够持续地被测试、监控和重新训练。它弥合了开发模型的数据科学家与负责应用程序部署和管理的操作团队之间的差距。
MLOps 流程
将MLOps视为确保你的机器学习模型不会仅仅是一次性开发然后被束之高阁的一种方式。相反,这些模型会持续被优化并部署,就像你每天都会用到的其他软件产品一样。(注:MLOps为机器学习运营)
想象你在最喜欢的购物应用中使用推荐系统。每次你浏览时,后台的机器学习模型都会为你推荐产品。但当用户行为改变,或有新商品加入时,情况又会如何?这就是MLOps发挥作用的时候。
在这篇教程中,我们将从模型在 Google Colab 上的初始开发一直带到一个可以投入生产的系统。该系统可以通过 Flask 和 Docker 在可扩展环境中部署。无论你是刚开始接触这个领域还是希望巩固你对 MLOps 的理解,我们会通过动手实操、代码片段和清晰的解释一步步引导你完成每一步。
重要材料如下: GitHub - NoManNayeem/MLOps-Flask-Product-Recommendation-System: 这是一个简单的基于Flask的web应用,使用机器学习模型来推荐产品的系统…github.comhttps://colab.research.google.com/drive/1HrWT4Zy7ivKn-09fWu0gL8iKxg-UV6QJ?usp=sharing
合成数据集的生成在使用机器学习模型时,高质量的数据非常重要。然而,现实世界中的数据往往难以获得,而且可能并不总是适合用于实验或模型构建,尤其是在刚开始的时候。这就是合成数据发挥作用的时候了。
在本节中,我们将专注于生成一个合成数据集(synthetic dataset),该数据集模拟用户与产品的互动记录。想象一下在线购物或流媒体平台中使用的推荐系统。对于每个用户,系统会记录他们对不同产品的评分或互动行为。这一信息构成了推荐系统的基石。
但是如果你没有这些数据怎么办?解决办法是生成模仿用户与产品在真实世界中互动的合成数据。
热度图:用户与产品互动
为什么合成数据?合成数据让我们可以:
- 模拟真实交互:我们可以建模用户与产品之间的交互,并创建一个能代表这些行为的数据集。
- 实验模型:它非常适合用来测试不同的机器学习模型,而无需依赖敏感或专有的数据。
- 处理数据稀缺:当真实数据稀缺时,合成数据集可以填补这一空缺。
线形图和条形图
让我们来看看代码,生成一个用于产品推荐系统的合成数据吧。
# 导入所需的库
import pandas as pd # 用于处理表格数据
import numpy as np # 用于生成随机数据
# 步骤1:定义用户和商品的数目
# 假设我们的电子商务平台有1000名用户和500个商品。
num_users = 1000
num_products = 500
# 步骤2:创建用户数据
# 每个用户有ID,年龄,性别和位置。
user_data = {
'user_id': np.arange(1, num_users + 1), # 生成用户ID从1到1000
'age': np.random.randint(18, 70, size=num_users), # 年龄在18到70之间随机生成
'gender': np.random.choice(['M', 'F'], size=num_users), # 随机分配性别为男(M)或女(F)
'location': np.random.choice(['Urban', 'Suburban', 'Rural'], size=num_users) # 随机分配位置类型
}
# 将用户数据字典转换为pandas DataFrame
users_df = pd.DataFrame(user_data)
# 步骤3:生成并创建商品数据
# 每个商品有ID,类别,价格和评分。
product_data = {
'product_id': np.arange(1, num_products + 1), # 生成商品ID从1到500
'category': np.random.choice(['Electronics', 'Clothing', 'Home', 'Books'], size=num_products), # 随机分配商品类别
'price': np.round(np.random.uniform(5, 500, size=num_products), 2), # 价格在$5到$500之间随机生成,保留两位小数
'rating': np.round(np.random.uniform(1, 5, size=num_products), 1) # 评分在1到5之间随机生成,保留一位小数
}
# 将商品数据字典转换为pandas DataFrame
products_df = pd.DataFrame(product_data)
# 步骤4:创建用户商品互动数据
# 我们模拟用户与商品的互动方式。例如,用户可以对商品进行评分或购买。
interaction_data = {
'user_id': np.random.choice(users_df['user_id'], size=5000), # 随机选择与商品互动的用户
'product_id': np.random.choice(products_df['product_id'], size=5000), # 随机选择被互动的商品
'rating': np.random.randint(1, 6, size=5000), # 为这些互动分配随机评分(1到5星)
'timestamp': pd.date_range(start='2023-01-01', periods=5000, freq='T') # 生成互动的随机时间戳,每分钟一个时间戳
}
# 将互动数据字典转换为pandas DataFrame
interactions_df = pd.DataFrame(interaction_data)
# 让我们查看每个数据集的前几行
users_df.head(), products_df.head(), interactions_df.head
通过这段代码,我们构建了一个场景,其中1000名用户与500种产品互动,提供用户的人口统计信息、产品详情以及用户对产品的互动数据,例如评分。这个数据集现在可以用来训练推荐系统。
现代商业中移动应用的战略优势利用数字环境获得竞争优势我们的生活将因这些适应性强的应用程序而变得更加便捷…… 数据准备预处理是将任何数据输入机器学习模型前的重要步骤。模型可能无法正常运行,或者存在偏差或不准确性。预处理的主要目的是清洗和格式化数据,使其更易于模型理解。
数据预处理步骤
让我们来深入探讨一下一些常见的预处理技术,主要关注我们之前生成的推荐系统数据集。
预处理的步骤:- 处理缺失值 :
在现实世界的数据集中,经常会遇到一些缺失值。例如,用户可能没有对某些产品进行评分,或者产品信息不完整。在这种情况下,我们将检查缺失值并相应地进行处理(不过在这个合成的数据集中,我们可能根本不会遇到缺失值)。 - 编码分类变量 :
机器学习模型需要处理数值数据,所以我们需要将分类变量(如gender
和category
)转换为数值格式。例如,gender
会被转换成 1 或 0,category
会被转换成不同的整数。为此,我们将使用标签编码——一种简单的将分类标签转换为整数的技术。 - 创建用户-产品评分矩阵 :
我们需要将交互数据集转换成一个矩阵,方便机器学习模型理解——一个矩阵,每一行代表一个用户,每一列代表一个产品,矩阵中的值是用户给的产品评分数据。 - 将数据分为训练集和测试集 :
为了评估我们的模型,我们将交互数据分为训练集和测试集。模型会在一部分数据上进行训练,在另一部分数据上进行测试,以此来评估模型的表现。
这是实现这些预处理步骤的代码示例:
# 导入预处理所需的库
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
# 步骤1:处理缺失值
# 检查所有数据集中的缺失值情况
print("用户数据中的缺失值:\n", users_df.isnull().sum())
print("产品数据中的缺失值:\n", products_df.isnull().sum())
print("交互数据中的缺失值:\n", interactions_df.isnull().sum())
# 步骤2:编码分类变量
label_encoder = LabelEncoder()
# 将用户数据中的性别列进行编码(男 -> 0, 女 -> 1)
users_df['gender_encoded'] = label_encoder.fit_transform(users_df['gender'])
# 对用户数据中的位置列进行编码
users_df['location_encoded'] = label_encoder.fit_transform(users_df['location'])
# 对产品数据的类别列进行编码
products_df['category_encoded'] = label_encoder.fit_transform(products_df['category'])
# 步骤3:创建用户-产品评分值矩阵
user_product_matrix = interactions_df.pivot_table(index='user_id', columns='product_id', values='rating').fillna(0)
# 步骤4:将数据集划分为训练集和测试集
train_data, test_data = train_test_split(interactions_df, test_size=0.2, random_state=42)
# 显示预处理后的数据的前几行以验证
print("用户-产品矩阵:\n", user_product_matrix.head())
print("训练数据样本:\n", train_data.head())
print("测试数据样本:\n", test_data.head())
通过这段代码,我们成功了:实现了目标。
- 处理了任何存在的缺失值。
- 将分类特征转化为数值。
- 创建了用户产品矩阵以进行进一步分析。
- 拆分数据为训练集和测试集以便评估模型。
现在我们已经准备好数据,该轮到我们构建并训练机器学习模型了。对于我们的推荐系统,我们将使用一种名为奇异值分解(SVD)的协作过滤技术。SVD是推荐系统中最常用的技巧之一,尤其是在处理类似我们之前生成的用户-产品交互这种矩阵数据时。
模型搭建
我们接下来要做的就是一步一步地搭建并训练模型:
模型搭建步骤:- 准备 Surprise 库所需的数据 :
我们使用的 Surprise 库构建推荐模型时,期望数据格式为三列,分别表示user_id
,product_id
和rating
。我们将使用预处理的交互数据来调整为这种格式。 - 训练集和测试集划分 :
就像传统机器学习一样,我们将数据划分为训练集和测试集。在这里,我们将使用 80% 的数据进行训练,20% 的数据进行测试,以便评估模型在未见过的数据上的表现。 - 训练模型(SVD) :
我们将使用 奇异值分解(SVD) 进行协同过滤。SVD 将用户-产品交互矩阵分解为较小的矩阵,这些矩阵表示用户和产品在低维度空间中的情况。这有助于我们预测尚未评分的产品。 - 测试模型 :
模型训练完成后,我们将用测试数据来测试模型,看看它能否准确预测用户尚未评分的产品。 - 评估模型性能 :
最后,我们将使用 均方根误差(RMSE) 评估模型的性能,这可以让我们了解预测评分与实际评分之间的差距。
探索电信行业的快速演变
电信行业正在经历一场巨大的变革。
随着快速的技术……
www.linkedin.com](https://www.linkedin.com/pulse/telco-beyond-connectivity-observation-how-nayeem-islam-nbxhc/?trackingId=6cmGsEjHTtOYz5uITHhtKw%3D%3D&source=post_page-----ec65bd8cf07f--------------------------------)
以下是实现这些步骤的代码:
# 安装Surprise库
!pip install scikit-surprise
# 导入所需的库
from surprise import Dataset, Reader, SVD
from surprise.model_selection import train_test_split as surprise_train_test_split
from surprise.model_selection import cross_validate
from surprise import accuracy
# 步骤1:为Surprise准备数据集
reader = Reader(rating_scale=(1, 5)) # 数据集中的评分为1到5分
data = Dataset.load_from_df(interactions_df[['user_id', 'product_id', 'rating']], reader)
# 步骤2:将数据集划分为训练集和测试集
trainset, testset = surprise_train_test_split(data, test_size=0.2)
# 步骤3:训练SVD算法
model = SVD() # 初始化SVD算法
model.fit(trainset) # 在训练集上训练
# 步骤4:在测试集上进行测试
predictions = model.test(testset)
# 步骤5:使用RMSE进行性能评估
rmse = accuracy.rmse(predictions)
这段代码能帮我们:
- 训练一个SVD模型来预测用户对产品的评分情况。
- 测试模型的准确性并使用RMSE(RMSE值越低,模型性能越好)来评估其性能。
SVD的解释:
SVD 对复杂的矩阵(例如用户-产品矩阵)进行分解,将其拆分成更简单的部分,这样可以更容易地预测缺失值(即,根据用户的先前互动来预测用户可能喜欢哪些产品)。
https://www.linkedin.com/pulse/demystifying-modern-ai-comprehensive-guide-ml-dl-generative-islam-osagc/?trackingId=6cmGsEjHTtOYz5uITHhtKw%3D%3D 揭秘现代AI:从机器学习到生成模型的全面指南
让我们保存模型吧一旦训练好了机器学习模型,保存模型至关重要,这样我们在将来部署或使用模型时就不用每次都重新训练。在本节中,我们将介绍如何将训练好的模型保存到文件,以及如果你在类似Google Colab的环境中工作,如何直接将模型下载到你的本地计算机上。
模型保存功能
保存模型的关键步骤- 为什么要保存模型呢?
训练一个机器学习模型可能需要耗费大量时间和资源。通过在模型训练完成后保存它,我们可以在未来的预测中重复利用它,而无需从头开始重新训练。 - 如何保存模型?
我们将使用 Python 内置的 pickle 库来序列化并保存训练好的模型到文件中。Pickle 允许我们将 Python 对象转换为可以写入文件的字节序列,并在以后重新加载使用。 - 下载模型(可选):
如果你在类似 Google Colab 这样的云端环境中工作,你可能希望把保存的模型下载到本地电脑。我们可以用 Colab 内置的files.download()
函数轻松下载模型文件。
以下代码用于保存和下载训练后的模型:
import pickle
# 步骤 1:将训练好的 SVD 模型保存到文件里
model_filename = 'svd_model.pkl'
with open(model_filename, 'wb') as model_file:
pickle.dump(model, model_file)
print(f"模型保存到 {model_filename}")
# 如果在 Google Colab 中运行,下载该模型文件
from google.colab import files
files.download(model_filename)
这个简单的过程确保我们的模型能够安全保存以备将来使用。一旦保存,该模型可以被加载并用于进行预测,无需再次训练。这在将机器学习模型部署到生产环境时特别有用。
关于技术领导力的真相:成功所需的真实要素为什么成为技术领导不仅仅是成为最好的程序员——以及如果你想在这个角色上取得成功应该怎么做。更多内容请点击…www.linkedin.com 监控模型表现评估机器学习模型的表现是 MLOps 生命周期中非常重要的一部分。一旦模型经过训练和测试,就使用各种评估指标来评估其表现。接下来我们要看两个常用的指标,比如均方根误差(RMSE)和平均绝对误差(MAE),这两个指标用来衡量预测评分和实际评分的接近程度。
模型性能评价指标
一个常用的模型评估标准:- 均方根误差 (RMSE) :
RMSE 测量预测评分与实际评分之间平均误差的大小。较低的 RMSE 表示模型性能更好。由于它先平方误差再求平均,因此对大误差特别敏感。 - 平均绝对误差 (MAE) :
MAE 计算预测评分与实际评分之间的平均绝对差异。比 RMSE 更简单的指标,常用于获得更直观的预测准确性。 - 性能报告 :
通过将这些指标整合到一个简单的性能报告中,我们可以更好地理解模型的准确性,并识别改进的领域。
以下为使用RMSE和MAE来评估模型表现并生成一份性能报告的代码:
# 第一步:计算 MAE(平均绝对误差)
mae = accuracy.mae(predictions)
# 第二步:生成一个简单的性能报告
performance_report = {
'RMSE': rmse,
'MAE': mae
}
# 展示性能评估
print("模型性能评估:")
for metric, score in performance_report.items():
print(f"{metric}: {score:.4f}")
指标解释:
- RMSE有助于凸显那些预测误差较大的模型,在重大误差更成问题的情况下更有用。
- MAE更清晰直观地展示预测偏差的程度,不会过分惩罚较大的误差,使评估更加平滑。
这两个指标一起使用可以提供对模型准确性和稳定性的均衡看法。
在软件开发中平衡质量和过度设计:构建灵活系统的指南……真正的软件质量不是关于预测未来,而是关于创造灵活、适应性强的系统。……www.linkedin.com 开发Flask应用现在我们已经训练好了机器学习模型,并将其保存起来,下一步是搭建一个网络应用程序,让用户能够与模型进行互动。我们将使用 Flask ,这是一个轻量级的 Python 网络框架,来创建一个简单的用户界面,让使用者可以输入一个用户ID和一个产品ID以获取推荐。
系统架构
以下我们将讨论:
- 构建 Flask 应用 以提供模型推荐。
- 设计一个让用户输入选择的界面。
- 把 Flask 应用容器化 以便轻松部署。
- 创建 Flask 应用:
我们将创建一个简单的 Flask 应用程序,允许用户输入用户 ID 和产品 ID。提交之后,该应用将使用训练好的 SVD 模型来预测该组合的评分。 - 构建用户界面:
使用 HTML 和 Bootstrap,我们将创建一个简洁而响应式的表单,以获取用户和产品 ID。提交表单之后,应用将显示预测评分。 - Docker 化 Flask 应用:
我们将使用 Docker 来打包 Flask 应用及其依赖项到一个容器中,可以在任何地方运行。
项目结构如下:
📂 MLOps_Flask_Recommendation_System
│
├── 📂 model
│ └── svd_model.pkl # 训练好的SVD模型文件
│
├── 📂 templates # Flask应用的HTML模板
│ ├── index.html # 用户选择产品或服务的首页
│ └── result.html # 显示推荐结果的页面
│
├── 📂 venv # 虚拟环境目录(可选)
│
├── .dockerignore # Docker构建时需要忽略的文件/目录
├── .gitignore # Git仓库中需要忽略的文件/目录
├── app.py # 主Flask应用文件
├── Dockerfile # Flask应用的Docker配置文件
├── docker-compose.yml # 运行应用于容器中的Docker Compose文件
├── requirements.txt # Python依赖项
├── README.md # 项目描述及使用说明
app.py 文件:
from flask import Flask, render_template, request
import pickle
import os
# 启动 Flask 应用
app = Flask(__name__)
# 加载保存的 SVD 模型
model_path = os.path.join('model', 'svd_model.pkl')
with open(model_path, 'rb') as model_file:
model = pickle.load(model_file)
# 示例用户和产品ID数据
users = list(range(1, 1001))
products = list(range(1, 501))
@app.route('/')
def index():
return render_template('index.html', users=users, products=products)
@app.route('/recommend', methods=['POST'])
def recommend():
user_id = int(request.form['user_id'])
product_id = int(request.form['product_id'])
# 预测推荐评分
prediction = model.predict(user_id, product_id)
return render_template('result.html', user_id=user_id, product_id=product_id, predicted_rating=prediction.est)
if __name__ == '__main__':
# 如果直接运行此脚本:
app.run(host='0.0.0.0', port=5000)
用户界面(UI)
index.html:此页面让用户可以从下拉列表中选择一个用户ID和一个产品ID,并提交请求来获取推荐。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>产品推荐页面</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
<h1 class="text-center">产品推荐工具</h1>
<form action="/recommend" method="POST" class="mt-4">
<div class="mb-3">
<label for="user_id" class="form-label">请选择用户ID</label>
<select name="user_id" class="form-select">
{% for user in users %}
<option value="{{ user }}">{{ user }}</option>
{% endfor %}
</select>
</div>
<div class="mb-3">
<label for="product_id" class="form-label">请选择产品ID</label>
<select name="product_id" class="form-select">
{% for product in products %}
<option value="{{ product }}">{{ product }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary">获取推荐结果</button>
</form>
</div>
<script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
index.html
result.html:一旦推荐被做出,页面会显示所选用户和产品的预计评分。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>推荐评分结果</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- з本页面显示推荐结果 -->
</head>
<body>
<div class="container mt-5">
<h1 class="text-center">推荐结果</h1>
<p class="text-center">用户ID <strong>{{ user_id }}</strong> 和产品ID <strong>{{ product_id }}</strong> 的预测评分是 <strong>{{ predicted_rating }}</strong> 分。</p>
<div class="text-center">
<a href="/" class="btn btn-primary">返回主页</a>
</div>
</div>
<script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
result.html
使用Python进行数据仓库:数据仓库的基础知识 数据仓库的基础知识 为什么数据仓库很重要 在当今这个以数据驱动的世界里,企业生成并处理大量数据……www.linkedin.com Docker化 Dockerfile(Docker 文件):我们将创建一个Dockerfile文件,将Flask应用容器化,使其能够更方便地在任何机器或云上运行。
# 使用官方的 Python 运行时作为基础镜像
FROM python:3.10-slim
# 设置容器内的工作目录
WORKDIR /app
# 安装构建所需的依赖工具和 Python 开发库
RUN apt-get update && apt-get install -y \
gcc \
build-essential \
python3-dev \
&& rm -rf /var/lib/apt/lists/*
# 将当前目录的内容复制到容器的 /app 目录下
COPY . /app
# 安装 requirements.txt 文件中列出的所有依赖包
RUN pip install --no-cache-dir -r requirements.txt
# 将端口 5000 暴露出去
EXPOSE 5000
# 设置环境变量
ENV FLASK_APP=app.py
# 运行应用
CMD ["flask", "run", "--host=0.0.0.0"]
这里有一个docker-compose.yml文件:
我们将使用Docker Compose来搭建容器,并将应用程序的端口设置为5000。
version: '3.8'
services:
flask_app:
build: .
ports:
- "5000:5000" # 将容器的5000端口映射到主机的5000端口
volumes:
- .:/app # 将主机当前目录挂载到容器的/app目录
environment:
FLASK_APP: app.py # 设置环境变量FLASK_APP的值为app.py
command: flask run --host=0.0.0.0 # 启动flask应用,监听所有网络接口
项目的需求文件:requirements.txt:
这里有一个简单的requirements文件来确保所有依赖项都能被正确安装。
Flask
scikit-surprise
numpy==1.21.6
这个 Flask 应用允许用户输入用户 ID 和产品 ID 来获取推荐,基于之前训练的模型。它被完全容器化使用 Docker,便于部署和使用。
破解产品市场匹配的秘诀:初创企业指南如何识别、实现并利用产品市场契合以取得初创企业成功 寻找产品市场契合的艰难旅程…www.linkedin.com 要使用Docker封装Flask应用一旦本地成功构建并运行了 Flask 应用程序,下一步就是确保它能在不同的环境中一致地部署。Docker 允许我们将整个应用程序及其依赖打包成一个容器,这个容器可以在任何机器上运行,从而让部署变得更加简单。
部署
下面列出Docker化Flask应用的关键点:
-
为什么使用 Docker?
Docker 为你的应用程序提供一个标准化的运行环境,无论它部署在哪里。这避免了“在我的机器上可以运行”这类问题,确保开发、测试和生产环境中的设置保持一致。 -
Dockerfile
Dockerfile 包含构建容器所需的 Docker 指令。它指定了基础镜像文件,安装必要的依赖项,并运行 Flask 应用。 - Docker Compose
Docker Compose 让我们能够管理多容器的 Docker 应用程序。尽管在这种情况下我们只需要一个容器来运行 Flask 应用,但使用 Compose 可以轻松地配置端口和管理卷。
这里是一个用于构建容器中 Flask 应用程序的 Dockerfile
。
# 使用官方 Python 3.10-slim 运行时作为父镜像
FROM python:3.10-slim
# 设置工作目录为 /app
WORKDIR /app
# 安装构建所需的依赖和 Python 开发工具
RUN apt-get update && apt-get install -y \
gcc \
build-essential \
python3-dev \
&& rm -rf /var/lib/apt/lists/*
# 复制当前目录的内容到 /app
COPY . /app
# 安装 requirements.txt 文件中指定的依赖包
RUN pip install --no-cache-dir -r requirements.txt
# 将端口 5000 暴露出去
EXPOSE 5000
# 设置环境变量
ENV FLASK_APP=app.py
# 启动应用
CMD ["flask", "run", "--host=0.0.0.0"]
解释:
- 基础镜像:我们使用
python:3.10-slim
作为基础镜像,这是一个精简的Python镜像。 - 工作目录:我们将容器的工作目录设置为
/app
。 - 安装依赖:我们安装必需的依赖项,复制应用文件,并安装所需的Python包。
- 暴露端口:我们暴露端口
5000
,让应用可以从外部访问。 - 运行Flask:我们使用
CMD
启动Flask应用。
Docker Compose 让管理和运行容器变得更简单。下面是一个 docker-compose.yml
文件。
version: '3.8'
services:
flask_app:
build: .
ports:
- "5000:5000"
volumes:
- .:/app
环境变量:
FLASK_APP: app.py # 设置FLASK_APP环境变量为app.py
命令:
flask run --host=0.0.0.0
解释:
- 构建:
build: .
命令让 Docker Compose 从当前文件夹构建镜像。 - 端口映射:容器中的端口
5000
映射到了主机机器的端口5000
。 - 卷:将项目目录挂载到容器中,方便随时更新应用代码。
要在 Docker 容器中构建并运行 Flask 应用程序,可以使用以下命令:
- 制作 Docker 镜像 :
docker-compose build
注:docker-compose build
是一个常用的 Docker Compose 命令,用于构建应用的镜像。
- 启动容器 (例如:
docker start
):
docker-compose up (启动容器)
运行这些命令后,Flask应用程序可以通过http://localhost:5000
访问。
现在我们已经有了一个运行良好的Flask应用,模型的集成,并通过Docker进行容器化部署,你可以采取几个进一步的步骤来进一步提升项目的可扩展性、自动化和监控能力。
步骤前瞻:
- CI/CD 流水线:持续集成(CI)和持续部署(CD)确保每次有新的代码被推送至仓库时,更改会自动进行测试、构建并部署到测试或生产环境。可以使用Jenkins、GitLab CI或GitHub Actions等工具来自动化这些任务。
- 监控和日志记录:对于生产系统,监控应用程序的健康状况和性能至关重要。可以集成像Prometheus和Grafana这样的监控工具来跟踪响应时间、错误率和资源使用等指标。另外,通过设置ELK Stack(Elasticsearch、Logstash、Kibana)这样的日志框架,可以收集和分析日志来追踪问题。
- 使用Kubernetes进行编排:对于更大规模的系统,Kubernetes这样的编排平台是必不可少的。Kubernetes可以跨不同服务器管理多个Docker容器,自动处理负载均衡、扩展和故障转移,适合高度可扩展的微服务架构。
- 使用MLflow进行模型版本管理:随着项目的演进,追踪不同版本的模型对可再现性很重要。工具如MLflow允许追踪实验结果、管理模型版本并轻松部署模型。它也有助于比较不同模型以选择最佳性能者。
- 超参数调优:为了提高推荐模型的准确度,可以使用GridSearchCV或RandomizedSearchCV等工具进行超参数调优。这允许优化SVD模型的参数以获得更好的性能表现。
nayeem-islam.vercel.app
探索:Kubernetes 用于编排一旦应用程序变大,你可以从 Docker Compose 迁移到 Kubernetes 来扩展和管理跨集群的多个容器。Kubernetes 可以处理:
Kubernetes 的架构
- 负载均衡:确保流量均匀地分布在各个容器上。
- 自动伸缩:根据流量和负载情况自动扩展或收缩。
- 自动恢复:自动重启异常的容器。
本文教程涵盖了构建和部署推荐系统的完整MLOps生命周期流程。从合成数据集生成和训练模型到创建Flask网络应用程序并将其Docker化部署,我们探讨了将机器学习集成到实际应用中所需的基本要素。
NoManNayeem - 简介全栈开发工程师(Python/Go/Node.js)| 技术项目经理 | 技术倡导者 | 数据科学从业人士 | 讲师…github.com共同学习,写下你的评论
评论加载中...
作者其他优质文章