機器學習中的線性回歸要求因變量和自變量之間的關系是線性的。如果資料的分布更複雜,如下圖所示,該怎麼辦?線性模型可以用于拟合非線性資料嗎?我們如何生成最佳捕獲資料的曲線呢?我們将在這篇文章中回答這些問題。
目錄為什麼使用多項式回歸
過度拟合與欠拟合
偏差與差異權衡取舍
将多項式回歸應用于波士頓住房資料集。
為什麼使用多項式回歸?
為了了解多項式回歸的必要性,讓我們先生成一些随機機器學習資料集。
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資料集上實作了這兩個模型。