<center> <img src = "https://i.imgur.com/AmFJfEn.jpg"> </center> ## Prerequisite ### Linear regression 在了解 Polynomial regression 之前,我們先看到 Linear regression,它擁有跟其相接近的特質,差別在於 Linear regression 相較來說只將輸出與單一一個輸入定義線性關係,Linear regression 所建立的模型會是一條直線,而該直線會偏向與周圍數據建立最貼近彼此的平面關係。 相對於 Linear regression,Polynomial regression 能更加容易建構出與複雜數據間的關係,但也要小心 Polynomial Regression 會產生過度擬合數據的問題 (overfitting)。 ### Gradient descent 為了使模型更貼近數據,使用 Gradient descent 是一種方法。 而梯度下降法 (Gradient descent) 是拿來求出最低的損失函數 (loss function) 的參數,藉由 Gradient descent 不斷更新模型的參數,我們可以發現模型可以更加擬和原先所給定的數據集,從而使的損失函數的數值 (loss value) 越來越小。 > :bulb: What is loss function / loss value > 在透過 Regression model (Ex: Polynomial Regression),我們希望能藉由模型去貼近原先所給定的數據,使得模型能精準去預估我們所給予的輸出相對應的輸入。 > > 但要能了解我們訓練模型的輸出跟實際輸出,我們會使用 loss function 來定義,其中它產生的 **loss value 便是實際數值和預測數值的差** 其中,Regression model 所常用的 loss function 包含: 1. 均方誤差 (Mean square error a.k.a MSE) $$ MSE = \frac{1}{n} \sum^n_{i=1}(y_i - \hat{y}_i)^2 $$ 2. 平均絕對值誤差 (Mean absolute error a.k.a MAE) $$ MAE = \frac{1}{n} \sum^n_{i=1}|y_i - \hat{y}_i| $$ 其中 $\hat{y}$ 為模型估計的輸出,而 $y$ 為原本資料輸入所對應的輸出 3. 開根均方誤差 (Root MSE / RMSE) $$ RMSE = \sqrt{\frac{1}{n} \sum^n_{i=1}(y_i - \hat{y}_i)^2} $$ 為了避免均方誤差 (MSE) loss value 過大, RMSE 將其開根 :::info **Choose MSE or MAE ?** * MAE (Mean Absolute Error): 選擇它的優點在於,其損失函數對於與大多數資料相差較多的**異常值 (outlier)** 較不敏感,但也因於此 MAE 不能預測偏差,因為其損失函數只考慮絕對值得差異。 * MSE (Mean Squared Error): MSE 在是一个凸函數,容易使用梯度下降算法進行優化,因为它使用平方誤差計算資料間的差異,所以導致其損失函數對偏差的敏感。 但在選擇 MAE 或 MS的同時,數據的性質和分析模型的具體要求才是選擇哪種 Loss function 放在 Regression model 的重點。 ::: ## Goal Polynomial Regression 是一種希望透過數據使用多項式預測函數來建模,並且未知的模型參數也是通過數據來估計的回歸模型。 ## Background > 這裡的輸入可稱為自變量,輸出可稱為因變量 Polynomial Regression 期望透過輸入 $x$ 來與輸出 $y$ 的關係建立模型,其中判斷函數為 $n$ 之多項式,相較於 Linear Regression 中,$n=1$,$y = \beta_0 + \beta_1 x$,Polynomial Regression 更容易拿來用於模擬非線性變量之間的關係。 而兩者目標是確定係數的值,可以使預估出來的輸出值和實際值的差異最小化。 Polynomial Regression 的基本思想是將原始輸入來建立多項式的項,使得預測函數可以再線性回歸模型中使用,被表示为一个多項式方程 $$ y = \beta_0 + \beta_1 x + \beta_2 x^2 + ... + \beta_n x^n $$ 其中,$x$ 為原先資料的輸入項,$y$ 為輸出項,$\beta_0$ 是 $y$ 的偏差值,$\beta_1, \beta_2, ... \beta_n$ 為多項式的係數。 Polynomial Regression 的建立模型目的是確定係數值,可以使輸出實際值和预測值之間的差異最小。 而優化過程可以用優化算法来完成,例如梯度下降或最小二乘法。 最後只要係數被確定,多項式方程就可以用来根據輸入量的新值輸出進行預測。 ## Implementation 在這個部分,我們可以先使用 `scikit-learn` 的 library 來先試試看 如果尚未安裝,使用 `pip install scikit-learn` ### Prepare data ```python # Number of data points in each cluster num_points = 500 # Generate data for three clusters cluster1 = np.random.normal(loc=[2, 2], scale=[0.5, 0.5], size=(num_points, 2)) cluster2 = np.random.normal(loc=[6, 6], scale=[0.7, 0.7], size=(num_points, 2)) cluster3 = np.random.normal(loc=[4, 8], scale=[0.4, 0.6], size=(num_points, 2)) # Combine the clusters x = np.concatenate((cluster1[:, 0], cluster2[:, 0], cluster3[:, 0])) y = np.concatenate((cluster1[:, 1], cluster2[:, 1], cluster3[:, 1])) ``` ![](https://hackmd.io/_uploads/SJFkTM7ah.png) ### Create the polynomial features ```python degree = 1 poly = PolynomialFeatures(degree=degree, include_bias=True) poly_features = poly.fit_transform(x.reshape(-1, 1)) # x.reshape(-1, 1) is a 2D array with one column ``` ### Create Model ```python from sklearn.linear_model import LinearRegression poly_reg_model = LinearRegression() poly_reg_model.fit(poly_features, y) y_predicted = poly_reg_model.predict(poly_features) ``` ![](https://hackmd.io/_uploads/HJs0nfQah.png) ### Evaluation ```python # calculate loss, MSE, MAE from sklearn.metrics import mean_squared_error, mean_absolute_error print("Accuracy: ", poly_reg_model.score(poly_features, y)) print("MSE: ", mean_squared_error(y, y_predicted)) print("MAE: ", mean_absolute_error(y, y_predicted)) ``` ## From Scratch 在 From Scratch 的部分僅使用 `numpy` ### Create the feature matrix ```python class CustomFeatureTransformer: def __init__(self, degree, is_bias=True): self.is_bias = is_bias self.degree = degree def transform(self, x = None): if x is None: raise ValueError('x is None') if self.is_bias: x = np.c_[np.ones(x.shape[0]), x] for i in range(2, self.degree + 1): x = np.c_[x, x[:, 1] ** i] return x def fit_transform(self, x): return self.transform(x) ``` ### Create Model ```python class CustomLinearRegression: def __init__(self): self.w = None def fit(self, x, y): self.w = np.linalg.inv(x.T.dot(x)).dot(x.T).dot(y) def predict(self, x): return x.dot(self.w) def score(self, x, y): y_pred = self.predict(x) return 1 - ((y - y_pred)**2).sum() / ((y - y.mean())**2).sum() ``` ### Evaluation ```python class MAE: def __call__(self, y, y_pred): return np.mean(np.abs(y - y_pred)) def gradient(self, y, y_pred): return np.sign(y - y_pred) class MSE: def __call__(self, y, y_pred): return np.mean((y - y_pred)**2) def gradient(self, y, y_pred): return 2 * (y_pred - y) ``` ## More example [Titanic - Machine Learning from Disaster](https://www.kaggle.com/competitions/titanic/overview) ## Reference 歡迎更仔細閱讀以下相關內容以了解本篇知識 * [python机器学习-线性回归(LinearRegression)算法](https://blog.csdn.net/Arwen_H/article/details/82181288) * [機器/深度學習: 基礎介紹-損失函數(loss function)](https://chih-sheng-huang821.medium.com/%E6%A9%9F%E5%99%A8-%E6%B7%B1%E5%BA%A6%E5%AD%B8%E7%BF%92-%E5%9F%BA%E7%A4%8E%E4%BB%8B%E7%B4%B9-%E6%90%8D%E5%A4%B1%E5%87%BD%E6%95%B8-loss-function-2dcac5ebb6cb) * [Polynomial Regression in Python using scikit-learn](https://data36.com/polynomial-regression-python-scikit-learn/)