使用sklearn进行在线实时预测(构建可用模型)

本文章向大家介绍如何使用sklearn进行在线实时预测(构建真实世界中可用的模型),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Python 作为当前机器学习中使用最多的一门编程语言,有很多对应的机器学习库,最常用的莫过于 scikit-learn 了。我们介绍下如何使用sklearn进行实时预测。先来看下典型的机器学习工作流。


解释下上面的这张图片:

  •   绿色方框圈出来的表示将数据切分为训练集和测试集。
  •   红色方框的上半部分表示对训练数据进行特征处理,然后再对处理后的数据进行训练,生成 model。
  •   红色方框的下半部分表示对测试数据进行特征处理,然后使用训练得到的 model 进行预测。
  •   红色方框的右下角部分表示对模型进行评估,评估可以分为离线和在线。

典型的 ML 模型

介绍完了典型的机器学习工作流了之后,来看下典型的 ML 模型。

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier

# 加载鸢尾花数据
iris = load_iris()
# 创建包含特征名称的 DataFrame
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['species'] = pd.Categorical.from_codes(iris.target, iris.target_names)

# 生成标记,切分训练集、测试集
df['is_train'] = np.random.uniform(0, 1, len(df)) <= .75
train, test = df[df['is_train']==True], df[df['is_train']==False]

# 生成 X 和 y
features = df.columns[:4]
y = pd.factorize(train['species'])[0]

model = RandomForestClassifier(n_jobs=2)

# 训练模型
model.fit(train[features], y)
# 预测数据
model.predict(test[features])

上面的模型对鸢尾花数据进行训练生成一个模型,之后该模型对测试数据进行预测,预测结果为每条数据属于哪种类别。


模型的保存和加载

上面我们已经训练生成了模型,但是如果我们程序关闭后,保存在内存中的模型对象也会随之消失,也就是说下次如果我们想要使用模型预测时,需要重新进行训练,如何解决这个问题呢?

很简单,既然内存中的对象会随着程序的关闭而消失,我们能不能将训练好的模型保存成文件,如果需要预测的话,直接从文件中加载生成模型呢?答案是可以的。

sklearn 提供了 joblib 模型,能够实现完成模型的保存和加载。

from sklearn.externals import joblib

# 保存模型到 model.joblib 文件
joblib.dump(model, "model.joblib" ,compress=1)

# 加载模型文件,生成模型对象
new_model = joblib.load("model.joblib")

new_pred_data = [[0.5, 0.4, 0.7, 0.1]]
# 使用加载生成的模型预测新样本
new_model.predict(new_pred_data)

构建实时预测

前面说到的运行方式是在离线环境中运行,在真实世界中,我们很多时候需要在线实时预测,一种解决方案是将模型服务化,在我们这个场景就是,我告诉你一个鸢尾花的 sepal_length, sepal_width, petal_length, petal_width 之后,你能够快速告诉我这个鸢尾花的类型,借助 flask 等 web 框架,开发一个 web service,实现实时预测。

因为依赖于 flask 框架,没有安装的需要安装下:

pip install flask

创建一个 ml_web.py 文件,内容如下:

# coding=utf-8
from urlparse import urljoin

import flask
from flask import Flask, request, url_for, Response
from sklearn.externals import joblib

app = Flask(__name__)

# 加载模型
model = joblib.load("model.joblib")


@app.route("/", methods=["GET"])
def index():
    with app.test_request_context():
        # 生成每个函数监听的url以及该url的参数
        result = {"predict_iris": {"url": url_for("predict_iris"),
                                   "params": ["sepal_length", "sepal_width", "petal_length", "petal_width"]}}

        result_body = flask.json.dumps(result)

        return Response(result_body, mimetype="application/json")


@app.route("/ml/predict_iris", methods=["GET"])
def predict_iris():
    request_args = request.args

    # 如果没有传入参数,返回提示信息
    if not request_args:
        result = {
            "message": "请输入参数:sepal_length, sepal_width, petal_length, petal_width"
        }
        result_body = flask.json.dumps(result, ensure_ascii=False)
        return Response(result_body, mimetype="application/json")

    # 获取请求参数
    sepal_length = float(request_args.get("sepal_length", "-1"))
    sepal_width = float(request_args.get("sepal_width", "-1"))
    petal_length = float(request_args.get("petal_length", "-1"))
    petal_width = float(request_args.get("petal_width", -1))

    # 构建特征矩阵
    vec = [[sepal_length, sepal_width, petal_length, petal_width]]
    print("vec: {0}".format(vec))

    # 生成预测结果
    predict_result = int(model.predict(vec)[0])
    print("predict_result: {0}".format(predict_result))

    # 构造返回数据
    result = {
        "features": {
            "sepal_length": sepal_length,
            "sepal_width": sepal_width,
            "petal_length": petal_length,
            "petal_width": petal_width
        },
        "result": predict_result
    }

    result_body = flask.json.dumps(result, ensure_ascii=False)
    return Response(result_body,  mimetype="application/json")


if __name__ == "__main__":
    app.run(port=8000)

在命令行启动它:

$ python ml_web.py
 * Running on http://127.0.0.1:8000/ (Press CTRL+C to quit)

在 PostMan(也可以在浏览器中打开) 中打开 http://127.0.0.1:8000/ml/predict_iris ,得到以下结果:

 

可以看到,这里提示我们输入 sepal_length, sepal_width, petal_length, petal_width 参数,所以我们需要添加上参数重新构造一个请求 url:http://127.0.0.1:8000/ml/predict_iris?sepal_length=10&sepal_width=1&petal_length=3&petal_width=2

再次请求得到的结果如下:

 

可以看到,模型返回的结果为 2,也就是说模型认为这个鸢尾花的类别是 2。


总结

在真实世界中,我们经常需要将模型进行服务化,这里我们借助 flask 框架,将 sklearn 训练后生成的模型文件加载到内存中,针对每次请求传入不同的特征来实时返回不同的预测结果。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的LSTM模型的代码示例,用于地铁客流预测: ```python import numpy as np import pandas as pd from keras.models import Sequential from keras.layers import LSTM, Dense, Dropout from sklearn.preprocessing import MinMaxScaler # 读取数据 data = pd.read_csv('subway_data.csv') # 数据预处理 scaler = MinMaxScaler(feature_range=(0, 1)) scaled_data = scaler.fit_transform(data['passengers'].values.reshape(-1, 1)) # 划分训练集和测试集 train_size = int(len(scaled_data) * 0.8) test_size = len(scaled_data) - train_size train_data = scaled_data[0:train_size, :] test_data = scaled_data[train_size:len(scaled_data), :] # 创建训练集和测试集 def create_dataset(dataset, look_back=1): dataX, dataY = [], [] for i in range(len(dataset) - look_back - 1): a = dataset[i:(i + look_back), 0] dataX.append(a) dataY.append(dataset[i + look_back, 0]) return np.array(dataX), np.array(dataY) look_back = 5 trainX, trainY = create_dataset(train_data, look_back) testX, testY = create_dataset(test_data, look_back) # 将数据转化为LSTM可接受的格式 trainX = np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1])) testX = np.reshape(testX, (testX.shape[0], 1, testX.shape[1])) # 创建LSTM模型 model = Sequential() model.add(LSTM(units=50, return_sequences=True, input_shape=(1, look_back))) model.add(Dropout(0.2)) model.add(LSTM(units=50)) model.add(Dropout(0.2)) model.add(Dense(units=1)) # 编译模型 model.compile(optimizer='adam', loss='mean_squared_error') # 训练模型 model.fit(trainX, trainY, epochs=100, batch_size=32) # 预测未来客流量 train_predict = model.predict(trainX) test_predict = model.predict(testX) # 反归一化处理 train_predict = scaler.inverse_transform(train_predict) trainY = scaler.inverse_transform([trainY]) test_predict = scaler.inverse_transform(test_predict) testY = scaler.inverse_transform([testY]) # 计算误差 trainScore = np.sqrt(mean_squared_error(trainY[0], train_predict[:, 0])) testScore = np.sqrt(mean_squared_error(testY[0], test_predict[:, 0])) print('Train Score: {:.2f} RMSE'.format(trainScore)) print('Test Score: {:.2f} RMSE'.format(testScore)) ``` 这段代码假设你有一个名为'subway_data.csv'的数据文件,其中包含地铁客流量的历史数据。它将数据读入一个Pandas DataFrame中,使用MinMaxScaler进行归一化处理,然后将数据集划分为训练集和测试集。接下来,它创建了一个名为“create_dataset”的函数,用于将数据转换为LSTM可用的格式。然后,它定义了一个简单的LSTM模型,并使用adam优化器和均方误差损失函数编译了模型。最后,它使用训练集拟合模型,并使用测试集对模型进行评估和预测。 请注意,这只是一个简单的示例,并且您可能需要根据您的数据集进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值