天天看點

python多項式回歸_使用Python的多項式回歸

機器學習中的線性回歸要求因變量和自變量之間的關系是線性的。如果資料的分布更複雜,如下圖所示,該怎麼辦?線性模型可以用于拟合非線性資料嗎?我們如何生成最佳捕獲資料的曲線呢?我們将在這篇文章中回答這些問題。

python多項式回歸_使用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多項式回歸_使用Python的多項式回歸

讓我們将機器學習中的線性回歸模型應用于此資料集。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()

最佳拟合線的圖是

python多項式回歸_使用Python的多項式回歸

我們可以看到直線無法捕獲資料中的模式。這是一個不拟合的例子。計算線RMSE和R²得分給出:RMSE of linear regression is 15.908242501429998.

R2 score of linear regression is 0.6386750054827146

為了克服不拟合,我們需要增加模型的複雜性。

為了生成一個高階方程,我們可以添加原始特征的幂作為新特征。線性模型,

python多項式回歸_使用Python的多項式回歸

可以轉化為

python多項式回歸_使用Python的多項式回歸

這仍然被認為是線性模型,因為與特征相關的系數/權重仍然是線性的。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()

python多項式回歸_使用Python的多項式回歸

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]]

在轉換後的特征上拟合線性回歸模型得到如下圖所示

python多項式回歸_使用Python的多項式回歸

從圖中可以清楚地看出,二次曲線能夠比線性線更好地拟合資料。計算RMSE和R²得分給出:RMSE of polynomial regression is 10.120437473614711.

R2 of polynomial regression is 0.8537647164420812.

我們可以看到,與線性相比,RMSE下降和R²分數增加

如果我們嘗試拟合一個三次曲線(degree=3)到資料集,我們可以看到它通過的資料點比二次曲線和直線更多。

python多項式回歸_使用Python的多項式回歸

三次曲線的名額是RMSE is 3.449895507408725

R2 score is 0.9830071790386679

下面是機器學習資料集上拟合線性,二次和三次曲線的比較。

python多項式回歸_使用Python的多項式回歸

如果我們進一步将degree增加到20,我們可以看到曲線通過更多資料點。下面是degree 3和degree 20曲線的比較。

python多項式回歸_使用Python的多項式回歸

對于degree= 20,模型還捕獲資料中的噪聲。這是一個過度拟合的例子。即使這個模型傳遞了大部分資料,它也無法推廣看不見的資料。為了防止過度拟合,我們可以添加更多的訓練樣本,以便算法不會學習系統中的噪聲并且可以變得更加通用。(注意:如果資料本身就是噪聲,則添加更多資料可能會成為問題)。

我們如何選擇最佳機器學習模型呢?要回答這個問題,我們需要了解偏差與方差的權衡。

偏見與差異的權衡取舍

偏差是指由于機器學習模型在拟合資料時的簡單假設而導緻的誤差。高偏差意味着模型無法捕獲資料中的模式,這導緻欠拟合。

方差是指由于複雜模型試圖拟合資料而導緻的誤差。高方差意味着模型通過大多數資料點,導緻資料過度拟合。

下圖總結了我們的學習經曆。

python多項式回歸_使用Python的多項式回歸

從下圖可以看出,随着模型複雜度的增加,偏差減小,方差增大,反之亦然。理想情況下,機器學習模型應該具有低方差和低偏差。但實際上,兩者兼而有之是不可能的。是以,為了得到一個既能在訓練上表現良好,又能在不可見資料上表現良好的模型,需要進行權衡。

python多項式回歸_使用Python的多項式回歸

到目前為止,我們已經涵蓋了多項式回歸背後的大部分理論。

将多項式回歸應用于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()

python多項式回歸_使用Python的多項式回歸

相關矩陣

# 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)

python多項式回歸_使用Python的多項式回歸

觀察從上面的協同圖可以看出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')

python多項式回歸_使用Python的多項式回歸
python多項式回歸_使用Python的多項式回歸

我們可以看到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))

python多項式回歸_使用Python的多項式回歸

接下來,調用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資料集上實作了這兩個模型。