如何训练具有多个变量的 ML 模型?

数据挖掘 机器学习 Python scikit-学习
2021-10-03 11:05:45

这些天我正在尝试学习机器学习概念。我理解在传统的机器学习数据中,我们会有特征标签我脑子里有以下玩具数据,其中有“units_sold”和“num_employees”等功能以及“cost_$”标签。我想训练模型来学习这些特征和特定“城市”和“商店”的标签。例如,如果我执行线性回归,模型会学习城市的截距和系数,并存储与之相关的数据。当我输入明年的units_sold 和num_employees 时,我得到了预测。

city        store   units_sold  num_employees   cost_$
New York    A       10          4               11000
New York    B       12          4               11890
New York    C       14          5               15260
New York    D       17          6               17340
London      A       23          5               22770
London      B       27          6               25650
London      C       22          3               21450
Paris       A       4           2               5200
Paris       B       7           3               9590

我正在尝试集思广益,想知道如何解决这个问题?

2个回答

这是非常少的数据,因此对其进行大量操作非常困难。特别是考虑到您希望在没有任何历史数据基础的情况下获得“明年”的估计值。

但是,如果您希望能够在给定输入特征(城市、商店、units_sold 和 num_employees)的情况下估算成本,那么这个问题设置在机器学习中是非常标准的。

首先,我会将您的数据放入 pandas DataFrame 中,然后使用数值对您的分类特征进行编码。我这样做是随机的,但我认为通过获取商店的经纬度以及有关社区的一些数据(密度、财富等)可以获得更好的结果。

import pandas as pd

data = {'city': ['New York', 'New York', 'New York', 'New York', 'London', 'London', 'London', 'Paris', 'Paris'],
        'store': ['A', 'B', 'C', 'D', 'A', 'B', 'C', 'A', 'B'],
        'units_sold': [10, 12, 14, 17, 23, 27, 22, 4, 7],
        'num_employees': [4,4,5,6,5,6,3,2,3],
        'cost': [11000, 11890, 15260, 17340, 22770, 25650, 21450, 5200, 9560]}

df = pd.DataFrame(data)

df['store'] =df['store'].astype('category').cat.codes
df['city'] =df['city'].astype('category').cat.codes

当我使用非常少的数据时,我总是喜欢使用一些可视化来让我对数据有一些直觉。让我们首先看看这些特征是如何相关的。

import matplotlib.pyplot as plt

plt.matshow(df.corr())
plt.xticks(np.arange(5), df.columns, rotation=90)
plt.yticks(np.arange(5), df.columns, rotation=0)
plt.colorbar()
plt.show()

在此处输入图像描述

我们可以看到成本与units_sold 直接相关。我想这并不奇怪。但它也与 num_employees 相关,并且与城市密切相关。

如果我们绘制 num_employees 和 units_sold,我们可以更清楚地看到上面观察到的相关性。

在此处输入图像描述

预测模型

现在我们希望能够为模型提供我们的输入并估算成本。

让我们首先将我们的数据放入训练和测试集中。对于如此小的数据集,这是非常有问题的,因为您很有可能最终得到一个忽略城市或商店类型的训练集。这将显着影响模型预测其从未见过的数据的输出的能力。

数据的标签是成本。

import numpy as np
from sklearn.model_selection import train_test_split

X = np.asarray(df[['city', 'num_employees', 'store', 'units_sold']])
Y = np.asarray(df['cost'])

X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, shuffle= True)

让我们从标准线性回归开始

从 sklearn.linear_model 导入线性回归

from sklearn.linear_model import LinearRegression

lineReg = LinearRegression()
lineReg.fit(X_train, y_train)
print('Score: ', lineReg.score(X_test, y_test))
print('Weights: ', lineReg.coef_)

plt.plot(lineReg.predict(X_test))
plt.plot(y_test)
plt.show()

分数:0.963554136721
权重:[506.87136393 -15.48157725 376.79379444 920.01939237]

在此处输入图像描述

更好的选择是使用岭回归。

from sklearn import linear_model
reg = linear_model.Ridge (alpha = .5)
reg.fit(X_train, y_train)
print('Score: ', reg.score(X_test, y_test))
print('Weights: ', reg.coef_)

plt.plot(reg.predict(X_test))
plt.plot(y_test)
plt.show()

分数:0.971197683706
权重:[129.78467277 2.034588
97.11724313 877.73906409]

在此处输入图像描述

如果您再次拆分并重新运行这两个模型,您会发现由于数据有限,它们的性能差异很大,正如我们预期的那样。但是,对于简单的线性回归,效果要明显得多。

为了更好地了解实际结果,让我们做一些有点顽皮的事情。我们将一遍又一遍地拆分数据以获得不同的模型并获得它们的平均分数。

scores = []
coefs = []
for i in range(1000):
    X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, shuffle= True)
    lineReg = LinearRegression()
    lineReg.fit(X_train, y_train)
    scores.append(lineReg.score(X_test, y_test))
    coefs.append(lineReg.coef_)
print('Linear Regression')
print(np.mean(scores))
print(np.mean(coefs, axis=0))

scores = []
coefs = []
for i in range(1000):
    X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, shuffle= True)
    lineReg = linear_model.Ridge (alpha = .5)
    lineReg.fit(X_train, y_train)
    scores.append(lineReg.score(X_test, y_test))
    coefs.append(lineReg.coef_)
print('\nRidge Regression')
print(np.mean(scores))
print(np.mean(coefs, axis=0))

线性回归
-1.43683760609
[ 1284.47358731 1251.8762943 -706.31897708 846.5465552 ]

岭回归
0.900877146134
[ 228.05312491 95.333063785 1873.498873785 1873.495

我们可以看到,在 1000 次试验中,岭回归是迄今为止最好的模型。

现在,您可以使用此模型来估算成本,方法是向模型传递一个具有与数据集相同顺序的特征的向量,如下所示

reg.predict([[2,  4,  1,  12]])

结果得分是

数组([12853.2132658])


这不足以可靠地进行任何机器学习回归。但是,您可以深入了解哪些因素对您的成本影响最大。

您特别提到了线性回归。为此,我们可以使用 PySpark VectorAssembler 之类的工具从多列中创建一个向量。

例如,对于要传递给线性回归的几列 CRIM、ZN、INDUS 等,您可以创建一个新的数据框,如下所示。

from pyspark.ml.feature import VectorAssembler
vectorAssembler = VectorAssembler(inputCols = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PT', 'B', 'LSTAT'], outputCol = 'features')
vhouse_df = vectorAssembler.transform(house_df)
vhouse_df = vhouse_df.select(['features', 'label'])
vhouse_df.show(3)