使用Python的多项式回归

机器学习中的线性回归要求因变量和自变量之间的关系是线性的。如果数据的分布更复杂,如下图所示,该怎么办?线性模型可以用于拟合非线性数据吗?我们如何生成最佳捕获数据的曲线呢?我们将在这篇文章中回答这些问题。

目录

为什么使用多项式回归

过度拟合与欠拟合

偏差与差异权衡取舍

将多项式回归应用于波士顿住房数据集。

为什么使用多项式回归?

为了理解多项式回归的必要性,让我们先生成一些随机机器学习数据集。

import numpy as npimport matplotlib.pyplot as pltnp.random.seed(0)x = 2 - 3 * np.random.normal(0, 1, 20)y = x - 2 * (x ** 2) + 0.5 * (x ** 3) + np.random.normal(-3, 3, 20)plt.scatter(x,y, s=10)plt.show()

生成的数据看起来像

让我们将机器学习中的线性回归模型应用于此数据集。Python代码如下:

import numpy as npimport matplotlib.pyplot as pltfrom sklearn.linear_model import LinearRegressionnp.random.seed(0)x = 2 - 3 * np.random.normal(0, 1, 20)y = x - 2 * (x ** 2) + 0.5 * (x ** 3) + np.random.normal(-3, 3, 20)# transforming the data to include another axisx = x[:, np.newaxis]y = y[:, np.newaxis]model = LinearRegression()model.fit(x, y)y_pred = model.predict(x)plt.scatter(x, y, s=10)plt.plot(x, y_pred, color='r')plt.show()

最佳拟合线的图是

我们可以看到直线无法捕获数据中的模式。这是一个不拟合的例子。计算线RMSE和R得分给出:

RMSE of linear regression is 15.908242501429998.

R2 score of linear regression is 0.6386750054827146

为了克服不拟合,我们需要增加模型的复杂性。

为了生成一个高阶方程,我们可以添加原始特征的幂作为新特征。线性模型,

可以转化为

这仍然被认为是线性模型,因为与特征相关的系数/权重仍然是线性的。x只是一个特征。然而我们拟合的曲线本质上是二次曲线。

为了将原始特征转换成更高阶的项,我们将使用scikit-learn提供的多项式特征类。接下来,我们使用线性回归对机器学习模型进行训练。Python代码如下:

import operatorimport numpy as npimport matplotlib.pyplot as pltfrom sklearn.linear_model import LinearRegressionfrom sklearn.metrics import mean_squared_error, r2_scorefrom sklearn.preprocessing import PolynomialFeaturesnp.random.seed(0)x = 2 - 3 * np.random.normal(0, 1, 20)y = x - 2 * (x ** 2) + 0.5 * (x ** 3) + np.random.normal(-3, 3, 20)# transforming the data to include another axisx = x[:, np.newaxis]y = y[:, np.newaxis]polynomial_features= PolynomialFeatures(degree=2)x_poly = polynomial_features.fit_transform(x)model = LinearRegression()model.fit(x_poly, y)y_poly_pred = model.predict(x_poly)rmse = np.sqrt(mean_squared_error(y,y_poly_pred))r2 = r2_score(y,y_poly_pred)print(rmse)print(r2)plt.scatter(x, y, s=10)# sort the values of x before line plotsort_axis = operator.itemgetter(0)sorted_zip = sorted(zip(x,y_poly_pred), key=sort_axis)x, y_poly_pred = zip(*sorted_zip)plt.plot(x, y_poly_pred, color='m')plt.show()

To generate polynomial features (here 2nd degree polynomial)

------------------------------------------------------------

polynomial_features = PolynomialFeatures(degree=2)

x_poly = polynomial_features.fit_transform(x)

Explaination

------------

Let's take the first three rows of X:

[[-3.29215704]

[ 0.79952837]

[-0.93621395]]

If we apply polynomial transformation of degree 2, the feature vectors become

[[-3.29215704 10.83829796]

[ 0.79952837 0.63924562]

[-0.93621395 0.87649656]]

在转换后的特征上拟合线性回归模型得到如下图所示

从图中可以清楚地看出,二次曲线能够比线性线更好地拟合数据。计算RMSE和R得分给出:

RMSE of polynomial regression is 10.120437473614711.

R2 of polynomial regression is 0.8537647164420812.

我们可以看到,与线性相比,RMSE下降和R分数增加

如果我们尝试拟合一个三次曲线(degree=3)到数据集,我们可以看到它通过的数据点比二次曲线和直线更多。

三次曲线的指标是

RMSE is 3.449895507408725

R2 score is 0.9830071790386679

下面是机器学习数据集上拟合线性,二次和三次曲线的比较。

如果我们进一步将degree增加到20,我们可以看到曲线通过更多数据点。下面是degree 3和degree 20曲线的比较。

对于degree= 20,模型还捕获数据中的噪声。这是一个过度拟合的例子。即使这个模型传递了大部分数据,它也无法推广看不见的数据。

为了防止过度拟合,我们可以添加更多的训练样本,以便算法不会学习系统中的噪声并且可以变得更加通用。(注意:如果数据本身就是噪声,则添加更多数据可能会成为问题)。

我们如何选择最佳机器学习模型呢?要回答这个问题,我们需要了解偏差与方差的权衡。

偏见与差异的权衡取舍

偏差是指由于机器学习模型在拟合数据时的简单假设而导致的误差。高偏差意味着模型无法捕获数据中的模式,这导致欠拟合。

方差是指由于复杂模型试图拟合数据而导致的误差。高方差意味着模型通过大多数数据点,导致数据过度拟合。

下图总结了我们的学习经历。

从下图可以看出,随着模型复杂度的增加,偏差减小,方差增大,反之亦然。理想情况下,机器学习模型应该具有低方差和低偏差。但实际上,两者兼而有之是不可能的。因此,为了得到一个既能在训练上表现良好,又能在不可见数据上表现良好的模型,需要进行权衡。

到目前为止,我们已经涵盖了多项式回归背后的大部分理论。

将多项式回归应用于Boston Housing数据集

导入所需的Python库

import numpy as npimport matplotlib.pyplot as plt import pandas as pd import seaborn as sns %matplotlib inline

加载数据

from sklearn.datasets import load_bostonboston_dataset = load_boston()boston = pd.DataFrame(boston_dataset.data, columns=boston_dataset.feature_names)boston['MEDV'] = boston_dataset.target

数据可视化

# set the size of the figuresns.set(rc={'figure.figsize':(11.7,8.27)})# plot a histogram showing the distribution of the target valuessns.distplot(boston['MEDV'], bins=30)plt.show()

相关矩阵

# compute the pair wise correlation for all columns correlation_matrix = boston.corr().round(2)# use the heatmap function from seaborn to plot the correlation matrix# annot = True to print the values inside the squaresns.heatmap(data=correlation_matrix, annot=True)

观察

从上面的协同图可以看出MEDV与LSTAT, RM有很强的相关性

RAD和TAX是stronly相关的,所以为了避免多重共线性,我们不将其包含在特性中

plt.figure(figsize=(20, 5))features = ['LSTAT', 'RM']target = boston['MEDV']for i, col in enumerate(features): plt.subplot(1, len(features) , i+1) x = boston[col] y = target plt.scatter(x, y, marker='o') plt.title(col) plt.xlabel(col) plt.ylabel('MEDV')

我们可以看到LSTAT的变化并不完全是线性的。让我们应用二次多项式回归和检验。

将机器学习数据集分成训练和测试集

Python代码如下:

from sklearn.model_selection import train_test_splitX = pd.DataFrame(np.c_[boston['LSTAT'], boston['RM']], columns = ['LSTAT','RM'])Y = boston['MEDV']# splits the training and test data set in 80% : 20%# assign random_state to any value.This ensures consistency.X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = 0.2, random_state=5)

让我们定义一个函数,它将原始特征转换为给定度数的多项式特征,然后对其应用线性回归。

from sklearn.preprocessing import PolynomialFeaturesdef create_polynomial_regression_model(degree): "Creates a polynomial regression model for the given degree" poly_features = PolynomialFeatures(degree=degree) # transform the features to higher degree features. X_train_poly = poly_features.fit_transform(X_train) # fit the transformed features to Linear Regression poly_model = LinearRegression() poly_model.fit(X_train_poly, Y_train) # predicting on training data-set y_train_predicted = poly_model.predict(X_train_poly) # predicting on test data-set y_test_predict = poly_model.predict(poly_features.fit_transform(X_test)) # evaluating the model on training dataset rmse_train = np.sqrt(mean_squared_error(Y_train, y_train_predicted)) r2_train = r2_score(Y_train, y_train_predicted) # evaluating the model on test dataset rmse_test = np.sqrt(mean_squared_error(Y_test, y_test_predict)) r2_test = r2_score(Y_test, y_test_predict) print("The model performance for the training set") print("-------------------------------------------") print("RMSE of training set is {}".format(rmse_train)) print("R2 score of training set is {}".format(r2_train)) print("") print("The model performance for the test set") print("-------------------------------------------") print("RMSE of test set is {}".format(rmse_test)) print("R2 score of test set is {}".format(r2_test))

接下来,调用degree=2

create_polynomial_regression_model(2)

使用多项式回归的模型的性能:

The model performance for the training set

-------------------------------------------

RMSE of training set is 4.703071027847756

R2 score of training set is 0.7425094297364765

The model performance for the test set

-------------------------------------------

RMSE of test set is 3.784819884545044

R2 score of test set is 0.8170372495892174

结论

在本机器学习系列中,我们介绍了线性回归,多项式回归,并在Boston Housing数据集上实现了这两个模型。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181010A02R5R00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注腾讯云开发者

领取腾讯云代金券