十種常見的迴歸演算法總結和介紹
線性迴歸是機器學習中最簡單的演算法,它可以通過不同的方式進行訓練。 在本文中,我們將介紹以下回歸演算法:線性迴歸、Robust 迴歸、Ridge 迴歸、LASSO 迴歸、Elastic Net、多項式迴歸、多層感知機、隨機森林迴歸和支援向量機。除此以外,本文還將介紹用於評估迴歸模型的最常用指標,包括均方誤差 (MSE)、均方根誤差 (RMSE) 和平均絕對誤差 (MAE)。
匯入庫和讀取資料
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import hvplot.pandas %matplotlib inline sns.set_style("whitegrid") plt.style.use("fivethirtyeight") USAhousing = pd.read_csv('../usa-housing/USA_Housing.csv') USAhousing.head()
探索性資料分析 (EDA)
下一步將建立一些簡單的圖表來檢查資料。 進行EDA將幫助我們熟悉資料和獲得資料的資訊,尤其是對迴歸模型影響最大的異常值。
USAhousing.info() <class 'pandas.core.frame.DataFrame'> RangeIndex: 5000 entries, 0 to 4999 Data columns (total 7 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Avg. Area Income 5000 non-null float64 1 Avg. Area House Age 5000 non-null float64 2 Avg. Area Number of Rooms 5000 non-null float64 3 Avg. Area Number of Bedrooms 5000 non-null float64 4 Area Population 5000 non-null float64 5 Price 5000 non-null float64 6 Address 5000 non-null object dtypes: float64(6), object(1) memory usage: 273.6+ KB
檢視資料集的描述
USAhousing.describe()
訓練前的準備
我們將從訓練一個線性迴歸模型開始,訓練之前需要確定資料的特徵和目標,訓練的特徵的 X ,目標變數的 y ,在本例中我們的目標為 Price 列。
之後,將資料分成訓練集和測試集。 我們將在訓練集上訓練我們的模型,然後使用測試集來評估模型。
from sklearn.model_selection import train_test_split X = USAhousing[['Avg. Area Income', 'Avg. Area House Age', 'Avg. Area Number of Rooms', 'Avg. Area Number of Bedrooms', 'Area Population']] y = USAhousing['Price'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
為了評估迴歸模型還建立了一些輔助函式。
from sklearn import metrics from sklearn.model_selection import cross_val_score def cross_val(model): pred = cross_val_score(model, X, y, cv=10) return pred.mean() def print_evaluate(true, predicted): mae = metrics.mean_absolute_error(true, predicted) mse = metrics.mean_squared_error(true, predicted) rmse = np.sqrt(metrics.mean_squared_error(true, predicted)) r2_square = metrics.r2_score(true, predicted) print('MAE:', mae) print('MSE:', mse) print('RMSE:', rmse) print('R2 Square', r2_square) print('__________________________________') def evaluate(true, predicted): mae = metrics.mean_absolute_error(true, predicted) mse = metrics.mean_squared_error(true, predicted) rmse = np.sqrt(metrics.mean_squared_error(true, predicted)) r2_square = metrics.r2_score(true, predicted) return mae, mse, rmse, r2_square
訓練迴歸模型
對於線性迴歸而言,一般都會有以下的假設:
線性假設:線性迴歸假設輸入和輸出之間的關係是線性的。所以可能需要轉換資料以使關係線性化(例如,指數關係的對數轉換)。
去除噪音:線性迴歸假設您的輸入和輸出變數沒有噪聲。這對於輸出變數最重要,如果可能希望刪除輸出變數 (y) 中的異常值。
去除共線性:當具有高度相關的輸入變數時,線性迴歸將會過擬合。需要將輸入資料進行相關性計算並刪除最相關的。
高斯分佈:如果輸入和輸出變數具有高斯分佈,線性迴歸將會做出更可靠的預測。對於分佈的轉換可以對變數使用變換(例如 log 或 BoxCox)以使它們的分佈看起來更像高斯分佈。
對資料進行處理:使用標準化或歸一化重新調整輸入變數,線性迴歸通常會做出更可靠的預測。
from sklearn.preprocessing import StandardScaler from sklearn.pipeline import Pipeline pipeline = Pipeline([ ('std_scalar', StandardScaler()) ]) X_train = pipeline.fit_transform(X_train) X_test = pipeline.transform(X_test)
下面我們開始進行迴歸迴歸演算法的示例
1、線性迴歸和評價指標
from sklearn.linear_model import LinearRegression lin_reg = LinearRegression(normalize=True) lin_reg.fit(X_train,y_train)
有了第一個模型,那麼就要知道評價模型的指標,以下是迴歸問題的三個常見評估指標:
平均絕對誤差 (MAE) 是誤差絕對值的平均值:
均方誤差 (MSE) 是均方誤差的平均值:
均方根誤差 (RMSE) 是均方誤差的平方根:
這三個指標中:
- MAE 是最容易理解的,因為它是平均誤差。
- MSE 比 MAE 更受歡迎,因為 MSE “懲罰”更大的錯誤,這在現實世界中往往很有用。
- RMSE 比 MSE 更受歡迎,因為 RMSE 可以用“y”單位解釋
這些都是損失函式,我們的訓練目標就是最小化他們。
test_pred = lin_reg.predict(X_test) train_pred = lin_reg.predict(X_train) print('Test set evaluation:\n_____________________________________') print_evaluate(y_test, test_pred) print('Train set evaluation:\n_____________________________________') print_evaluate(y_train, train_pred) results_df = pd.DataFrame( data=[["Linear Regression", *evaluate(y_test, test_pred) , cross_val(LinearRegression())]], columns=['Model', 'MAE', 'MSE', 'RMSE', 'R2 Square', "Cross Validation"]) Test set evaluation: _____________________________________ MAE: 81135.56609336878 MSE: 10068422551.40088 RMSE: 100341.52954485436 R2 Square 0.9146818498754016 __________________________________ Train set evaluation: _____________________________________ MAE: 81480.49973174892 MSE: 10287043161.197224 RMSE: 101425.06180031257 R2 Square 0.9192986579075526 __________________________________
2、Robust迴歸
Robust迴歸是一種迴歸分析形式,它的目標是克服傳統引數和非引數方法的一些侷限性,旨在不受基礎資料生成過程違反迴歸假設的過度影響。
當資料包含異常值時,則會考慮Robust迴歸。 在存在異常值的情況下,最小二乘估計效率低下並且可能存在偏差。 因為最小二乘預測被拖向離群值,並且因為估計的方差被人為誇大,結果是離群值可以被掩蓋了。
隨機樣本共識——RANSAC
隨機樣本共識 (RANSAC) 是一種迭代方法,它從一組觀察到的包含異常值的資料中估計數學模型的引數,而異常值不會對估計值產生影響。 因此它也可以理解為一種異常值檢測方法。
一個基本的假設是,資料由“內值”和“異常值”組成,“內值”即資料的分佈可以用一組模型引數來解釋,但可能受噪聲影響,“異常值”是不符合模型的資料。RANSAC還假設,給定一組(通常很小)內點,存在一個程式可以估計模型的引數,以最優地解釋或擬合該資料。
from sklearn.linear_model import RANSACRegressor model = RANSACRegressor(base_estimator=LinearRegression(), max_trials=100) model.fit(X_train, y_train) test_pred = model.predict(X_test) train_pred = model.predict(X_train) print('Test set evaluation:\n_____________________________________') print_evaluate(y_test, test_pred) print('====================================') print('Train set evaluation:\n_____________________________________') print_evaluate(y_train, train_pred) results_df_2 = pd.DataFrame( data=[["Robust Regression", *evaluate(y_test, test_pred) , cross_val(RANSACRegressor())]], columns=['Model', 'MAE', 'MSE', 'RMSE', 'R2 Square', "Cross Validation"] ) results_df = results_df.append(results_df_2, ignore_index=True) Test set evaluation: _____________________________________ MAE: 84645.31069259303 MSE: 10996805871.555056 RMSE: 104865.65630155115 R2 Square 0.9068148829222649 __________________________________ ==================================== Train set evaluation: _____________________________________ MAE: 84956.48056962446 MSE: 11363196455.35414 RMSE: 106598.29480509592 R2 Square 0.9108562888249323 _________________________________
3、Ridge迴歸
Ridge迴歸通過對係數的大小施加懲罰來解決普通最小二乘法的一些問題。 Ridge係數最小化懲罰殘差平方和
alpha >= 0 是控制收縮量的複雜性引數:alpha 值越大,收縮量越大,因此係數對共線性的魯棒性更強。
Ridge迴歸是一個 L2 懲罰模型。 將權重的平方和新增到最小二乘成本函式。
from sklearn.linear_model import Ridge model = Ridge(alpha=100, solver='cholesky', tol=0.0001, random_state=42) model.fit(X_train, y_train) pred = model.predict(X_test) test_pred = model.predict(X_test) train_pred = model.predict(X_train) print('Test set evaluation:\n_____________________________________') print_evaluate(y_test, test_pred) print('====================================') print('Train set evaluation:\n_____________________________________') print_evaluate(y_train, train_pred) results_df_2 = pd.DataFrame( data=[["Ridge Regression", *evaluate(y_test, test_pred) , cross_val(Ridge())]], columns=['Model', 'MAE', 'MSE', 'RMSE', 'R2 Square', "Cross Validation"] ) results_df = results_df.append(results_df_2, ignore_index=True) Test set evaluation: _____________________________________ MAE: 81428.64835535336 MSE: 10153269900.892609 RMSE: 100763.43533689494 R2 Square 0.9139628674464607 __________________________________ ==================================== Train set evaluation: _____________________________________ MAE: 81972.39058585509 MSE: 10382929615.14346 RMSE: 101896.66145239233 R2 Square 0.9185464334441484 __________________________________
4、LASSO 迴歸
LASSO 迴歸是一種估計稀疏係數的線性模型。 在數學上,它由一個用 L1 先驗作為正則化器訓練的線性模型組成。 最小化的目標函式是:
from sklearn.linear_model import Lasso model = Lasso(alpha=0.1, precompute=True, # warm_start=True, positive=True, selection='random', random_state=42) model.fit(X_train, y_train) test_pred = model.predict(X_test) train_pred = model.predict(X_train) print('Test set evaluation:\n_____________________________________') print_evaluate(y_test, test_pred) print('====================================') print('Train set evaluation:\n_____________________________________') print_evaluate(y_train, train_pred) results_df_2 = pd.DataFrame( data=[["Lasso Regression", *evaluate(y_test, test_pred) , cross_val(Lasso())]], columns=['Model', 'MAE', 'MSE', 'RMSE', 'R2 Square', "Cross Validation"] ) results_df = results_df.append(results_df_2, ignore_index=True) Test set evaluation: _____________________________________ MAE: 81135.6985172622 MSE: 10068453390.364521 RMSE: 100341.68321472648 R2 Square 0.914681588551116 __________________________________ ==================================== Train set evaluation: _____________________________________ MAE: 81480.63002185506 MSE: 10287043196.634295 RMSE: 101425.0619750084 R2 Square 0.9192986576295505 __________________________________
5、Elastic Net
Elastic Net 使用 L1 和 L2 先驗作為正則化器進行訓練。 這種組合允許學習一個稀疏模型,其中很少有像 Lasso 那樣的非零權重,同時仍然保持 Ridge 的正則化屬性。
當多個特徵相互關聯時,Elastic Net絡很有用。 Lasso 可能會隨機選擇關聯特徵其中之一,而 Elastic Net 可能會同時選擇兩者。 Elastic Net最小化的目標函式是:
from sklearn.linear_model import ElasticNet model = ElasticNet(alpha=0.1, l1_ratio=0.9, selection='random', random_state=42) model.fit(X_train, y_train) test_pred = model.predict(X_test) train_pred = model.predict(X_train) print('Test set evaluation:\n_____________________________________') print_evaluate(y_test, test_pred) print('====================================') print('Train set evaluation:\n_____________________________________') print_evaluate(y_train, train_pred) results_df_2 = pd.DataFrame( data=[["Elastic Net Regression", *evaluate(y_test, test_pred) , cross_val(ElasticNet())]], columns=['Model', 'MAE', 'MSE', 'RMSE', 'R2 Square', "Cross Validation"] ) results_df = results_df.append(results_df_2, ignore_index=True) Test set evaluation: _____________________________________ MAE: 81184.43147330945 MSE: 10078050168.470106 RMSE: 100389.49232100991 R2 Square 0.9146002670381437 __________________________________ ==================================== Train set evaluation: _____________________________________ MAE: 81577.88831531754 MSE: 10299274948.101461 RMSE: 101485.34351373829 R2 Square 0.9192027001474953 __________________________________
6、多項式迴歸
機器學習中的一種常見模式是使用在資料的非線性函式上訓練的線性模型。 這種方法保持了線性方法通常快速的效能,同時允許它們適應更廣泛的資料。
可以通過從係數構造多項式特徵來擴充套件簡單的線性迴歸。 在標準線性迴歸中,可能有一個看起來像這樣的二維資料模型:
如果我們想對資料擬合拋物面而不是平面,我們可以將特徵組合成二階多項式,使模型看起來像這樣:
這仍然是一個線性模型:那麼如果我們建立一個新的變數
通過重新標記資料,那麼公式可以寫成
可以看到到生成的多項式迴歸屬於上面的同一類線性模型(即模型在 w 中是線性的),並且可以通過相同的技術求解。 通過考慮使用這些基函式構建的高維空間內的線性擬合,該模型可以靈活地擬合更廣泛的資料範圍。
from sklearn.preprocessing import PolynomialFeatures poly_reg = PolynomialFeatures(degree=2) X_train_2_d = poly_reg.fit_transform(X_train) X_test_2_d = poly_reg.transform(X_test) lin_reg = LinearRegression(normalize=True) lin_reg.fit(X_train_2_d,y_train) test_pred = lin_reg.predict(X_test_2_d) train_pred = lin_reg.predict(X_train_2_d) print('Test set evaluation:\n_____________________________________') print_evaluate(y_test, test_pred) print('====================================') print('Train set evaluation:\n_____________________________________') print_evaluate(y_train, train_pred) results_df_2 = pd.DataFrame( data=[["Polynomail Regression", *evaluate(y_test, test_pred), 0]], columns=['Model', 'MAE', 'MSE', 'RMSE', 'R2 Square', 'Cross Validation'] ) results_df = results_df.append(results_df_2, ignore_index=True) Test set evaluation: _____________________________________ MAE: 81174.51844119698 MSE: 10081983997.620703 RMSE: 100409.0832426066 R2 Square 0.9145669324195059 __________________________________ ==================================== Train set evaluation: _____________________________________ MAE: 81363.0618562117 MSE: 10266487151.007816 RMSE: 101323.67517519198 R2 Square 0.9194599187853729 __________________________________
7、隨機梯度下降
梯度下降是一種非常通用的優化演算法,能夠為各種問題找到最佳解決方案。 梯度下降的一般思想是迭代地調整引數以最小化成本函式。 梯度下降測量誤差函式相對於引數向量的區域性梯度,它沿著梯度下降的方向前進。 一旦梯度為零,就達到了最小值。
from sklearn.linear_model import SGDRegressor sgd_reg = SGDRegressor(n_iter_no_change=250, penalty=None, eta0=0.0001, max_iter=100000) sgd_reg.fit(X_train, y_train) test_pred = sgd_reg.predict(X_test) train_pred = sgd_reg.predict(X_train) print('Test set evaluation:\n_____________________________________') print_evaluate(y_test, test_pred) print('====================================') print('Train set evaluation:\n_____________________________________') print_evaluate(y_train, train_pred) results_df_2 = pd.DataFrame( data=[["Stochastic Gradient Descent", *evaluate(y_test, test_pred), 0]], columns=['Model', 'MAE', 'MSE', 'RMSE', 'R2 Square', 'Cross Validation'] ) results_df = results_df.append(results_df_2, ignore_index=True) Test set evaluation: _____________________________________ MAE: 81135.56682170597 MSE: 10068422777.172981 RMSE: 100341.53066987259 R2 Square 0.914681847962246 __________________________________ ==================================== Train set evaluation: _____________________________________ MAE: 81480.49901528798 MSE: 10287043161.228634 RMSE: 101425.06180046742 R2 Square 0.9192986579073061 __________________________________
8、多層感知機
多層感知機相對於簡單迴歸任務的好處是簡單的線性迴歸模型只能學習特徵和目標之間的線性關係,因此無法學習複雜的非線性關係。 由於每一層都存在啟用函式,多層感知機有能力學習特徵和目標之間的複雜關係。
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Input, Dense, Activation, Dropout from tensorflow.keras.optimizers import Adam X_train = np.array(X_train) X_test = np.array(X_test) y_train = np.array(y_train) y_test = np.array(y_test) model = Sequential() model.add(Dense(X_train.shape[1], activation='relu')) model.add(Dense(32, activation='relu')) # model.add(Dropout(0.2)) model.add(Dense(64, activation='relu')) # model.add(Dropout(0.2)) model.add(Dense(128, activation='relu')) # model.add(Dropout(0.2)) model.add(Dense(512, activation='relu')) model.add(Dropout(0.1)) model.add(Dense(1)) model.compile(optimizer=Adam(0.00001), loss='mse') r = model.fit(X_train, y_train, validation_data=(X_test,y_test), batch_size=1, epochs=100) pd.DataFrame({'True Values': y_test, 'Predicted Values': pred}).hvplot.scatter(x='True Values', y='Predicted Values') pd.DataFrame(r.history)
pd.DataFrame(r.history).hvplot.line(y=['loss', 'val_loss'])
test_pred = model.predict(X_test) train_pred = model.predict(X_train) print('Test set evaluation:\n_____________________________________') print_evaluate(y_test, test_pred) print('Train set evaluation:\n_____________________________________') print_evaluate(y_train, train_pred) results_df_2 = pd.DataFrame( data=[["Artficial Neural Network", *evaluate(y_test, test_pred), 0]], columns=['Model', 'MAE', 'MSE', 'RMSE', 'R2 Square', 'Cross Validation'] ) results_df = results_df.append(results_df_2, ignore_index=True) Test set evaluation: _____________________________________ MAE: 101035.09313018023 MSE: 16331712517.46175 RMSE: 127795.58880282899 R2 Square 0.8616077649459881 __________________________________ Train set evaluation: _____________________________________ MAE: 102671.5714851714 MSE: 17107402549.511665 RMSE: 130795.2695991398 R2 Square 0.8657932776379376 __________________________________
9、隨機森林迴歸
from sklearn.ensemble import RandomForestRegressor rf_reg = RandomForestRegressor(n_estimators=1000) rf_reg.fit(X_train, y_train) test_pred = rf_reg.predict(X_test) train_pred = rf_reg.predict(X_train) print('Test set evaluation:\n_____________________________________') print_evaluate(y_test, test_pred) print('Train set evaluation:\n_____________________________________') print_evaluate(y_train, train_pred) results_df_2 = pd.DataFrame( data=[["Random Forest Regressor", *evaluate(y_test, test_pred), 0]], columns=['Model', 'MAE', 'MSE', 'RMSE', 'R2 Square', 'Cross Validation'] ) results_df = results_df.append(results_df_2, ignore_index=True) Test set evaluation: _____________________________________ MAE: 94032.15903928125 MSE: 14073007326.955029 RMSE: 118629.70676417871 R2 Square 0.8807476597554337 __________________________________ Train set evaluation: _____________________________________ MAE: 35289.68268023927 MSE: 1979246136.9966476 RMSE: 44488.71921056671 R2 Square 0.9844729124701823 __________________________________
10、支援向量機
from sklearn.svm import SVR svm_reg = SVR(kernel='rbf', C=1000000, epsilon=0.001) svm_reg.fit(X_train, y_train) test_pred = svm_reg.predict(X_test) train_pred = svm_reg.predict(X_train) print('Test set evaluation:\n_____________________________________') print_evaluate(y_test, test_pred) print('Train set evaluation:\n_____________________________________') print_evaluate(y_train, train_pred) results_df_2 = pd.DataFrame( data=[["SVM Regressor", *evaluate(y_test, test_pred), 0]], columns=['Model', 'MAE', 'MSE', 'RMSE', 'R2 Square', 'Cross Validation'] ) results_df = results_df.append(results_df_2, ignore_index=True) Test set evaluation: _____________________________________ MAE: 87205.73051021634 MSE: 11720932765.275513 RMSE: 108263.25676458987 R2 Square 0.9006787511983232 __________________________________ Train set evaluation: _____________________________________ MAE: 73692.5684807321 MSE: 9363827731.411337 RMSE: 96766.87310960986 R2 Square 0.9265412370487783 __________________________________
結果對比
以上就是我們常見的10個迴歸演算法,下面看看結果的對比
results_df
results_df.set_index('Model', inplace=True) results_df['R2 Square'].plot(kind='barh', figsize=(12, 8))
可以看到,雖然本例的差別很小(這是因為資料集的原因),但是每個演算法還是有細微的差別的,我們可以根據不同的實際情況選擇表現較好的演算法。
總結
在本文中,我們介紹了機器學習中的常見的線性迴歸演算法包括:
- 常見的線性迴歸模型(Ridge、Lasso、ElasticNet……)
- 模型使用的方法
- 採用學習演算法對模型中的係數進行估計
- 如何評估線性迴歸模型
- Spring中實現非同步呼叫的方式有哪些?
- 帶引數的全型別 Python 裝飾器
- 整理了幾個Python正則表示式,拿走就能用!
- 設計模式之狀態模式
- 如何實現資料庫讀一致性
- SOLID:開閉原則Go程式碼實戰
- React中如何引入CSS呢
- 慢查詢 MySQL 定位優化技巧,從10s優化到300ms
- 一個新視角:前端框架們都卷錯方向了?
- 編碼中的Adapter,不僅是一種設計模式,更是一種架構理念與解決方案
- 手寫程式語言-遞迴函式是如何實現的?
- 一文搞懂模糊匹配:定義、過程與技術
- 新來個阿里 P7,僅花 2 小時,做出一個多執行緒永動任務,看完直接跪了
- Puzzlescript,一種開發H5益智遊戲的引擎
- @Autowired和@Resource到底什麼區別,你明白了嗎?
- “四招”守護個人資訊保安
- CSS transition 小技巧!如何保留 hover 的狀態?
- React如此受歡迎離不開這4個主要原則
- 我是怎麼入行做風控的
- 重溫三十年前對於 NN 的批判:神經網路無法實現可解釋 AI