尽管人们普遍对机器学习 (ML)感兴趣,但在实时环境中有效使用 ML 却是一个复杂的问题,框架开发者对此并未给予足够的关注。几乎每种语言都有一个框架来实现机器学习的“学习”部分,但很少有框架支持机器学习的“预测”部分。
在训练 ML 模型之后,如何基于该模型来构建实时应用程序?使用很多工具包,您都必须构建自己的应用程序。我们刚开始看到专注于机器学习预测方面的框架。
之前有一篇文章提供了 Redis-ML 模块中可用功能的概述,所以在本文中,我们将深入了解机器学习——以一种易于理解的方式讲解一些技术,并展示如何使用 Redis 补充机器学习管道。举个例子,我们将逐步了解一段示例程序的代码,该程序可根据社区的不同特征预测房屋的中位价。
本文中的示例代码是使用 Python 3 编写的,使用各种可免费获得的机器学习软件包。需要使用 pip3 或您首选的软件包管理器安装以下包,才可运行这些示例
您还需要一个 Redis 4.0.0 实例和 Redis-ML 模块。Redis-ML 模块背后的开发者 Shay Nativ 创建了一个 Docker 容器,其中预加载了 Redis 4.0.0 和 Redis-ML 模块。要将该容器与本文中的代码结合使用,请使用以下命令启动容器
docker run -it -p 6379:6379 shaynativ/redis-ml
Docker 会自动下载并运行容器,将容器的默认 Redis 端口 (6379) 映射到您的计算机。
要构建房屋价格预测器,我们将使用一种称为线性回归的机器学习技术。
早在算法机器学习被发明之前,线性回归就已经是统计学家的工具箱的一部分。通过线性回归,我们可以尝试根据一个或多个已知量(自变量)来预测某个结果(有时称为因变量)。要让线性回归发挥作用,我们必须能够使用一条直线准确预估我们的结果。
在上图中,取自维基百科线性回归文章,我们可以看到我们的数据点如何围绕一条理想直线聚集。该数据集很适用于线性回归。实际上,线性回归用于对现实世界中各种问题进行建模,在这种问题中,通过观测到的线性关系可以准确预估某个结果,例如根据平方英尺计算房屋价格,或根据高中成绩和 SAT 分数计算大学 GPA。
从代数我们知道一条线由形为 y=b+ax 的方程表示,因此要“学习”这种形式的模型,我们需要应用算法来发现线的参数——斜率和截距。事实上,没什么花哨的,在算法机器学习问世之前,大多数统计学家会手工“拟合”这些模型。如今,使用计算机查找线的参数要普遍得多,并且可以使用各种工具包(TensorFlow、Scikit、Apache Spark)来解决线性回归问题。要记住的重要一点是,一旦我们学习了线性回归模型,我们就会有一个预测结果的数学公式,该公式可以由任何系统实现。
我们通过一个执行线性回归和使用流行的 Python scikit-learn 包和 Boston 住房数据集发现模型参数的示例来完成这项工作。
Boston 住房数据集是一个经典的数据集,用于教授统计学和机器学习。该数据集使用社区特征(例如一栋房屋的平均房间数、距波士顿主要就业中心距离或犯罪率)来预测波士顿地区一个社区的平均房价。为了便于可视化线性回归过程,我们将使用数据的单个特征,即每户平均房间数(RM)列。
Boston 住房数据集作为 scikit-learn 包的一部分提供,因此,让我们首先绘制我们的数据以可视化房间数 (RM) 和平均价格 (MEDV) 之间的关系
虽然不是一条完美的直线,但我们可以看到平均房间数和一个社区的平均房价之间存在相当强的线性关系。我们甚至可以绘制关系的理想化表示,并观察数据点如何围绕它聚集。
以下代码演示了如何使用 scikit 加载 Boston 住房数据集。Boston 住房数据集包含用于预测房价的十二个不同特征,因此在加载数据集后,我们从数据中提取第五列(RM 列)的数据作为我们的样本。
from sklearn.datasets import load_boston boston = load_boston() boston_RM = boston.data[:,5] boston_PRICE = boston.target
现在,我们将我们的数据分成两组,一组训练集和一组测试集。对于我们的示例,我们从前 400 个样本创建训练集,从剩余的 106 个样本创建测试集。
# slice the data into train and test sets x_train = boston_RM[:400].reshape(-1, 1) x_test = boston_RM[400:].reshape(-1, 1) y_train = boston.target[:400] y_test = boston.target[400:]
这种拆分方法可确保我们始终以相同的集合运行以获得可重复的结果。
现在我们已经构建了训练和测试集,我们可以使用 scikit 提供的 LinearRegression 模型为我们的数据拟合一条直线
lm = LinearRegression() lm.fit(x_train, y_train) coef = lm.coef_[0] int = lm.intercept_ print('Coef: {coef}, Intercept: {int}'.format(coef=coef, int=int))
在运行代码后,我们发现 scikit 已经为我们的数据拟合了一条直线,其系数为 9.40550212,截距为 -35.26094818316348。
现在有了这些参数,即可实现一个线性模型,根据指定邻里的房屋平均房间数来预测波士顿地区的房价。有了此模型后,如何构建可轻松进行实时预测并应用到应用程序或网站的应用程序?
Scikit 库 提供了一个能够评估训练模型的预测功能,但应用程序中使用该功能需要实现其他服务,才能使其快速而可靠。这正是 Redis 可以增强机器学习系统的地方。
借助一个新的模块 API,Redis-ML 模块能将标准线性回归作为原生数据类型添加进来。该模块不仅可以创建线性回归,还可以使用线性回归来预测值。
若要将线性回归添加到 Redis 中,则需要使用 ML.LINREG.SET 命令将线性回归添加到数据库。ML.LINGREG.SET 命令格式如下
ML.LINREG.SET key intercept coeef [...]
惯例是,Redis-ML 模块中的所有命令都以模块标识符 ML 开头。所有线性回归命令都以 LINGREG 为前缀。
若要将 Redis 设为使用我们在 scikit 中拟合的行预测波士顿房价的引擎,我们首先需要使用 loadmodule 指令加载 Redis-ML 模块。
redis-server --loadmodule /path/to/redis-ml/module.so
然后,我们通过执行 ML.LINGREG.SET 命令并使用来自 scikit 常量的数据来设置一个键来表示我们的线性回归。记住,截距是所提供的第一个值,并且系数按特征顺序提供。从我们的 scikit 代码开始,拟合一个回归行到房屋数据,我们确定我们的行对 RM 变量有 9.40550212 的系数,截距为 -35.26094818316348。我们可以使用 ML.LINGREG.SET 命令设置一个 Redis 键来计算该线性关系
127.0.0.1:6379> ML.LINREG.SET boston_house_price:rm-only -35.26094818316348 9.40550212 OK
我们创建boston_house_price:rm-only键后,可以反反复复地使用 ML.LINGREG.PREDICT 命令来预测某邻里的房价中位数。如果要预测平均每所房屋 6.2 个房间的邻里的房价中位数,我们将运行以下命令
127.0.0.1:6379> ML.LINREG.PREDICT boston_house_price:rm-only 6.2 "23.053164960836519”
Redis 预测该邻里的房价中位数为 23,053 美元(记住,这里的房价单位是千美元)。
理解如何使用 redis-cli 运行 ML.LINREG 命令非常有帮助,但我们更可能在应用程序中这么做。我们可以扩展拟合回归行的 Python 代码来自动创建 boston_house_price:rm-only 键。在 Redis 中创建该键后,我们实现一个测试,使用我们的测试数据从 Redis 生成预测。
r = redis.StrictRedis('localhost', 6379) r.execute_command("ML.LINREG.SET", "boston_house_price:rm-only", "-35.26094818316348", "9.40550212", ) redis_predict = [] for x in x_test: y = r.execute_command("ML.LINREG.PREDICT", "boston_house_price:rm-only", x[0]) redis_predict.append(float(y))
我们还可以使用 predict 例程为相同数据集生成 scikit 预测
y_predict = lm.predict(x_test)
为了比较,我们已绘制结果图。在下面的图表中,黑圈表示数据集中测试数据的实际价格。蓝色的标记 (+) 表示 Scikit 预测的值,而洋红色的标记 (x) 表示 Redis 预测的值。
如你所见,Redis 和 scikit 基于房间数平均值得出了关于房屋中位价相同的预测。虽然线性回归可能无法正确预测每个数据点的准确价格,但它提供了一种根据社区的一些可观察特征估算未知价格的有用方式。
在本帖中,我们深入探讨了 Redis-ML 的线性回归功能。我们研究了如何使用流行的 scikit Python 包为一些住房数据拟合一条线性回归线,然后使用 Redis 4.0.0 和 Redis-ML 模块创建住房价格预测引擎。
在本系列的下一部分中,我们将研究如何使用 Redis-ML 来实现一个用于分类的引擎,这是机器学习中的另一种问题,该问题试图根据先前的示例确定未知数据的类别。