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末尾多谢了个逗号,折腾了一中午(⊙﹏⊙)
原文地址:https://www.cnblogs.com/geoffreyone/p/10901052.html