打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
使用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('\n') 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数据集上实现了这两个模型。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
ML之LiR&2PolyR:使用线性回归LiR、二次多项式回归2PolyR模型在披萨数据集上拟合(train)、价格回归预测(test)
我用 Python 算了下:编程教室的用户数哪天能到100万
用Python开始机器学习(3:数据拟合与广义线性回归)
R语言用加性多元线性回归、随机森林、弹性网络模型预测鲍鱼年龄和可视化
Python遇见机器学习 ---- 线性回归算法 Linear Regression
python中numpy包使用方法总结
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服