Ubuntu搭建flask服务器, 部署sklearn 机器学习模型
本文参考自:flaskapi
说明:系统ubuntu, anaconda虚拟环境, python = 2.7
1. 项目结构和文件说明
.
├── data
│ └── 数据汇总.csv # 需要预测的数据
├── infer.py # 主要文件, 模型加载推理,和flask服务的创建、解析等
├── infer.pyc
├── model
│ └── liner.pkl # 训练好的模型
├── README.md
├── requirements.txt
├── test_post.sh # 程序入口, 启动服务, 通过crul命令发送数据, 模拟POST请求
└── train.py # 训练模型, 并保存
2. 训练
sklearn训练的过程不做赘述, 训练完用pickle序列化成二进制文件,留待后续加载。
注意: 如果数据经过了前处理, 如填补缺失值, 归一化或者值映射等等, 需要把数据处理用管道Pipeline封装, 具体参考生产环境中进行机器学习模型部署(using Flask)
3. 创建Flask服务
通过装饰器创建url对应服务, 函数为请求体的解析,前向计算和返回Response的过程.
# coding=utf-8
import sys
from flask import Flask, request, jsonify
import pandas as pd
from sklearn.externals import joblib
app = Flask(__name__)
@app.route('/predict', methods=['POST'])
def predict():
json_ = request.get_json(force=True) # 这一步解析报错, 检查POST请求的json是不是有错误
query = pd.get_dummies(pd.DataFrame(json_))
query = query.reindex(columns=model_columns, fill_value=0)
prediction = list(reg.predict(query))
return jsonify({"prediction": prediction})
if __name__ == '__main__':
try:
port = int(sys.argv[1])
except Exception as e:
port = 8899 # 自定义服务端端口,用于与客户端访问
# inputs
data = 'data/数据汇总.csv'
data = pd.read_csv(data, encoding='utf-8')
test_data = data.iloc[-6:] # 我用最后六行的数据作测试集
# 提取有效列, label列
include = list(data.columns)
dependent_variable = include[-1]
model_columns = include[:-1]
# 模型文件位置
model_directory = 'model'
model_liner_file_name = '%s/liner.pkl' % model_directory # liner.pkl是我的模型名字
# 加载模型
reg = joblib.load(model_liner_file_name)
print('model loaded{}'.format(model_liner_file_name))
app.run(host='0.0.0.0', port=port, debug=True)
4. 开启服务
开启服务命令:
python2 infer.py 8899 &
sleep 2
注意: python需要通过环境变量或者指定路径指定到需要的环境。推荐anaconda虚拟环境, 我的环境配置文件如下, 可以复制粘贴后通过命令conda env create -f environment.yml
创建虚拟环境:
name: flask
channels:
- defaults
dependencies:
- ca-certificates=2019.1.23=0
- certifi=2019.3.9=py27_0
- libedit=3.1.20181209=hc058e9b_0
- libffi=3.2.1=hd88cf55_4
- libgcc-ng=8.2.0=hdf63c60_1
- libstdcxx-ng=8.2.0=hdf63c60_1
- ncurses=6.1=he6710b0_1
- openssl=1.1.1b=h7b6447c_1
- pip=19.1.1=py27_0
- python=2.7.16=h9bab390_0
- readline=7.0=h7b6447c_5
- setuptools=41.0.1=py27_0
- sqlite=3.28.0=h7b6447c_0
- tk=8.6.8=hbc83047_0
- wheel=0.33.4=py27_0
- zlib=1.2.11=h7b6447c_3
- pip:
- click==7.0
- flask==1.0.2
- itsdangerous==1.1.0
- jinja2==2.10.1
- markupsafe==1.1.1
- numpy==1.16.3
- pandas==0.24.2
- python-dateutil==2.8.0
- pytz==2019.1
- scikit-learn==0.20.3
- scipy==1.2.1
- six==1.12.0
- werkzeug==0.15.4
prefix: /home/geoffrey/.conda/envs/flask
在安装好后, 通过source activate flask
激活环境, 然后执行上面的开启服务命令。
5. 模拟请求
通过crul命令发送请求,-d是发送的json格式请求数据列表, -H "Content-Type: application/json"
是青请求行,指定请求体的json解析格式, -X POST http://localhost:8899/predict
是请求url .注意两点:
- 务必加上请求头格式说明,
- 仔细检查json有没有问题, 我因为json末尾多谢了个逗号,折腾了一中午(⊙﹏⊙)