作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
本文是关于在机器学习或人工智能(AI)系统的上下文中使用Python进行实时预测, 使用瓶 休息 API. 这里暴露的架构可以被视为机器学习应用程序从概念验证(PoC)到最小可行产品(MVP)的一种方式.
Python 这难道不是设计实时解决方案时的首选吗. 但是,随着 Tensorflow 和 Scikit-Learn Python是否支持一些最常用的机器学习库, 它在许多地方使用方便 Jupyter Notebook PoCs.
使这个解决方案可行的原因是,与预测相比,训练需要花费很多时间. 如果你把训练想象成看电影然后预测问题答案的过程, 这样一来,就不用在每个新问题之后重新看一遍电影了.
训练是对“电影”的一种压缩视图,而预测是从压缩视图中检索信息. 无论电影是复杂的还是冗长的,它都应该非常快.
让我们用Python中的一个快速的[瓶]示例来实现它!
让我们从概述一个通用的训练和预测架构流程开始:
第一个, 根据目标函数创建一个训练管道来学习过去的数据.
这应该输出两个关键元素:
注意,在训练期间完成的特征工程应该小心保存,以便适用于预测. 在这个过程中可能出现的许多其他问题中,一个常见的问题是 功能扩展 哪些是许多算法所必需的.
如果特征X1从值1缩放到1000,然后用函数重新缩放到[0,1]范围 f(x) = x/max(X1)
,如果预测集的值是2000,会发生什么?
应该提前考虑一些仔细的调整,以便映射函数返回一致的输出,这些输出将在预测时正确计算.
这里有一个主要问题需要解决. 为什么我们要把训练和预测分开呢?
这是绝对正确的,在机器学习的例子和课程的背景下, 预先知道所有数据(包括要预测的数据), 构建预测器的一个非常简单的方法是 堆栈训练和预测数据 (通常称为测试集).
然后, 需要在“训练集”上进行训练,在“测试集”上进行预测才能得到结果, 同时对训练和测试数据进行特征工程, 在相同且独特的管道中进行训练和预测.
然而, 在现实系统中, 你通常有训练数据, 需要预测的数据是在处理过程中输入的. 换句话说, 你看了一次电影,之后你对它有一些问题, 这意味着答案应该是简单和快速的.
此外, 通常没有必要在每次新数据进入时重新训练整个模型,因为训练需要时间(对于某些图像集可能需要数周),并且随着时间的推移应该足够稳定.
这就是为什么训练和预测可以, 或者应该是, 在许多系统上是明显分离的, 这也更好地反映了智能系统(人工或非人工)的学习方式.
训练和预测的分离也是解决过拟合问题的好方法.
在统计学中, “过度拟合”是指“分析结果过于接近或精确地对应于一组特定数据”, 和5月, 因此, 无法拟合额外的数据或可靠地预测未来的观测结果。”.
过度拟合尤其见于具有许多特征的数据集, 或者是训练数据有限的数据集. 这两种情况, 与预测器可以验证的数据相比,数据包含了太多的信息, 其中一些甚至可能与预测变量无关. 在这种情况下,噪声本身可以被解释为一个信号.
控制过拟合的一个好方法是对一部分数据进行训练,并对另一部分数据进行预测. 因此,新数据上的预期误差大致就是该数据集上的测量误差, 假设我们训练的数据代表了系统的现实和它的未来状态.
因此,如果我们设计一个适当的训练和预测管道,以及正确的数据分割, 我们不仅解决了过拟合问题,而且还可以重用该架构来预测新数据.
最后一步是控制新数据上的误差与预期的相同. 总有一个偏移(实际误差总是低于预期), 人们应该确定什么是可接受的转变——但这不是本文的主题.
这就是明确区分训练和预测的好处所在. 如果我们保存了我们的特征工程方法和模型参数, 然后我们可以用这些元素构建一个简单的休息 API.
这里的关键是在API启动时加载模型和参数. 一旦启动并存储在内存中, 每个API调用都会触发ML算法的特征工程计算和“预测”方法. 两者通常都足够快,以确保实时响应.
可以将API设计为接受要预测的唯一示例, 或者几个不同的预测(批量预测).
下面是实现这一原则的最小Python/瓶代码, 与JSON输入和JSON输出(问题在, 回答):
应用程序 = 瓶(__name__)
@应用程序.路线(“/ api / makecalc /”,方法=['文章'])
def makecalc ():
"""
函数在每次API调用时运行
无需重新加载模型
"""
#读取接收到的json
Jsonfile =请求.get_json ()
Res = dict()
为jsonfile中的关键字.键():
#计算和预测
Res [key] = model.预测(doTheCalculation(关键)
#返回json文件
返回jsonify (res)
如果__name__ == '__main__':
# Model在API启动时加载
模型=泡菜.负载(打开(modelfile, rb))
应用程序.运行(debug = True)
请注意,该API可用于根据新数据进行预测, 但我不建议用它来训练模型. 它可以被使用, 但是这会使模型训练代码变得复杂,并且可能对内存资源的要求更高.
让我们以Kaggle数据集,共享单车为例. 假设我们是一家共享单车公司,想要预测每天的自行车租赁数量,以便更好地管理自行车的维护, 物流等方面的业务.
租金主要取决于天气状况, 天气预报也是如此, 该公司可以更好地了解租金何时达到峰值, 尽量避免在这几天进行保养.
首先,我们训练一个模型并将其保存为pickle对象,可以在 Jupyter笔记本.
这里不讨论模型训练和性能, 这只是理解整个过程的一个例子.
然后我们编写将在每个API调用时完成的数据转换:
导入numpy为np
以pd方式导入熊猫
从datetime导入日期
def doTheCalculation(数据):
数据(“dayofyear”)=((“dteday”)
数据(“dteday”).Apply (lambda x: date(x).年,1,1))
.astype(“datetime64 (ns))).Apply (lambda x: x.天)
X = np.数组(数据[[“即时”,“季节”,“年”,“假期”,“工作日”,“workingday”,
‘weathersit’,‘临时’,‘atemp’,‘哼’,‘风速’,‘dayofyear’]])
返回X
这只是一个变量(一年中的一天)的计算,包括月份和精确的日期. 还可以选择要保留的列及其各自的顺序.
然后,我们需要用瓶编写休息 API:
从flask导入flask、request、redirect、url_for、flash、jsonify
从features_calculation导入doTheCalculation
导入json, pickle
以pd方式导入熊猫
导入numpy为np
应用程序 = 瓶(__name__)
@应用程序.路线(“/ api / makecalc /”,方法=['文章'])
def makecalc ():
"""
函数在每次API调用时运行
"""
Jsonfile =请求.get_json ()
数据= pd.read_json (json.转储(jsonfile),东方=“指数”,convert_dates = [' dteday '])
打印(数据)
Res = dict()
Ypred =模型.预测(doTheCalculation(数据)
For I in range(len(ypred)):
Res [i] = ypred[i]
返回jsonify (res)
如果__name__ == '__main__':
Modelfile = ' Modelfile ..泡菜的
模型=泡菜.负载(打开(modelfile rb))
打印(“OK”加载)
应用程序.运行(debug = True)
运行这个程序,默认情况下它将在端口5000上提供API.
如果我们在本地测试请求,仍然使用Python:
导入请求,json
Url = '[http://127 . net.0.0.1:5000 / api / makecalc /] (http://127.0.0.1:5000 / api / makecalc) '
Text = json.转储({" 0 ":{“即时”:1、“dteday”:“2011 - 01 - 01 - t00:00:00.000 z”、“季节”:1、“年”:0,”mnth”:1、“假日”:0,“工作日”:6”workingday”:0,”weathersit”:2,“临时”:0.344167年,“atemp”:0.363625年,“哼”:0.805833年,“风速”:0.160446},
“1”:{“即时”:2,“dteday”:“2011 - 01 - 02 t00:00:00.000 z”、“季节”:1、“年”:0,”mnth”:1、“假日”:0,“工作日”:3”workingday”:0,”weathersit”:2,“临时”:0.363478年,“atemp”:0.353739年,“哼”:0.696087年,“风速”:0.248539},
“2”:{“即时”:3,“dteday”:“2011 - 01 - 03 - t00:00:00.000 z”、“季节”:1、“年”:0,”mnth”:1、“假日”:0,“工作日”:1、“workingday”:1、“weathersit临时“:1,:0.196364年,“atemp”:0.189405年,“哼”:0.437273年,“风速”:0.248309}})
请求包含提供给模型的所有信息. 因此, 我们的模型将以指定日期的自行车租赁预测作为响应(这里我们有三个日期).
headers = {'content-type': '应用程序lication/json', 'Accept-Charset': 'UTF-8'}
R =请求.Post (url, data=text, headers=headers)
打印(r, r.文本)
{
"0": 1063,
"1": 1028,
"2": 1399
}
就是这样! 该服务可以在任何公司的应用程序中轻松使用, 用于维护计划或让用户了解自行车交通, 需求, 以及出租自行车的可用性.
这是许多机器学习系统的主要缺陷, 尤其是PoCs, 是将训练和预测相结合.
如果它们被小心地分开, 对于MVP来说,可以很容易地进行实时预测, 以相当低的开发成本和工作量使用Python/瓶, 特别是如果, 对于许多poc来说, 它最初是由Scikit-learn开发的, Tensorflow,或任何其他Python机器学习库.
然而, 这可能并不适用于所有应用程序, 特别是在特征工程繁重的应用程序中, 或者应用程序检索最接近的匹配项,需要在每次调用时都有最新的可用数据.
无论如何,你需要一遍又一遍地看电影来回答关于它们的问题吗? 同样的规则也适用于机器学习!
在web服务上下文中, 休息ful api由以下几个方面定义:URL, 媒体类型和HTTP方法(GET), 帖子, 等. ). 它们可以作为应用程序之间交换信息的统一方式.
机器学习是计算机科学领域人工智能的一个子集,它通常使用统计技术赋予计算机“学习”的能力.e., 使用数据逐步提高特定任务的性能, 没有被明确编程.
TensorFlow是一个开源软件库,用于跨一系列任务的数据流编程. 它是一个符号数学库,也用于机器学习应用程序,如神经网络.
Scikit-learn, 还sklearn, 是Python编程语言的免费软件机器学习库.
特征工程是使用数据的领域知识来创建使机器学习算法工作的特征的过程. 它用与预测目标相关的附加信息来扩充现有数据.
Jupyter Notebook(以前称为IPython Notebooks)是一个基于web的交互式计算环境,支持Python编程语言.
一个PoC, 或者概念证明, 项目的第一阶段是否证明了项目的可行性.
Guillaume是Kaggle的ML和AI专家. 他在处理大型项目和探索扩展新解决方案方面经验丰富.
世界级的文章,每周发一次.
世界级的文章,每周发一次.