# 機器學習 HW2: Regression
###### tags: `江振國 機器學習2023`
> 目錄
[TOC]
## 檔案結構
* `main_p1.py` : 執行第一題的code,產生以下輸出:
> Problem1_dataset.png
* `main_p2.py` : 執行第二題的code,產生以下輸出:
> Problem2_dataset.png
> Problem2_linear_fitting_plot.png
* `main_p3.py` : 執行第三題的code,產生以下輸出:
> Problem3_dataset.png
> Problem3_polynomial_deg5_fitting_plot.png
> Problem3_polynomial_deg10_fitting_plot.png
> Problem3_polynomial_deg14_fitting_plot.png
* `main_p4.py` : 執行第四題的code,產生以下輸出:
> Problem4_dataset.png
> Problem4-1_linear_fitting_plot.png
> Problem4-2_polynomial_deg5_fitting_plot.png
> Problem4-2_polynomial_deg10_fitting_plot.png
> Problem4-2_polynomial_deg14_fitting_plot.png
* `main_p5.py` : 執行第五題的code,產生以下輸出:
> Problem5_dataset_m10.png
> Problem5_dataset_m80.png
> Problem5_dataset_m320.png
> Problem5_polynomial_deg14_m10_fitting_plot.png
> Problem5_polynomial_deg14_m80_fitting_plot.png
> Problem5_polynomial_deg14_m320_fitting_plot.png
* `main_p6.py` : 執行第六題的code,產生以下輸出:
> Problem6_dataset.png
> Problem6_lambda0_fitting_plot.png
> Problem6_lambda0.001_m_fitting_plot.png
> Problem6_lambda1_m_fitting_plot.png
> Problem6_lambda1000_m_fitting_plot.png
* `util.py`:相關類別與通用函式:
* class :
`LinearDataLoader` `PolynomialDataLoader` `LinearRegressionModel` `LinearRegressionModel_L2`
* function :
`read_dataset` `write_dataset`
## Execution description
### Quick Start
* 安裝相關環境:
```linux=
pip install numpy==1.23.5
pip install matplotlib==3.6.2
pip install scikit-learn==1.1.3
```
* 根據需要執行第一題~第六題,產生指令列輸出結果與圖檔。
```linux=
python main_p1.py
python main_p2.py
python main_p3.py
python main_p4.py
python main_p5.py
python main_p6.py
```
### 第一題
> 執行`main_p1.py`
* #### 產生資料集
* 引入`LinearDataLoader`類別建立`dataloader`物件,此物件會根據加入Gaussion noise $ε$ ~ $N(0, 1)$ 的方程式 $y = 2x + ε$ 產生15筆屬於 $[-3,3]$ 且等間距的點,並畫出Problem1_dataset.png資料分布圖。
### 第二題
> 執行`main_p2.py`
* #### 產生資料集
* `generate`函式會引入`LinearDataLoader`類別建立`dataloader`物件,此物件會根據加入Gaussion noise $ε$ ~ $N(0, 1)$ 的方程式 $y = 2x + ε$ 產生15筆屬於 $[-3,3]$ 且等間距的點,並畫出Problem2_dataset.png資料分布圖。
* #### 線性迴歸
* `linearRegression`函式會引入`LinearRegressionModel`類別建立`model`物件,該類別中的`fit`函式實作了線性迴歸中的$Normal Equation$公式解: $$w_{LIN}=(X^{T}X)^{-1}X^{T}y$$
```linux=
self.theta = np.dot(np.linalg.inv(np.dot(X.T, X)), np.dot(X.T, y))
```
* 得到 $w_{LIN}$ 後,使用`predict`函式計算出 y_predicted 數值,實作基於以下公式: $$ \hat{y_{n}}=w_{LIN}^{T}x_{n}$$
```linux=
preds = np.dot(X, self.theta)
```
* #### 輸出結果
* 呼叫`result_LR`函式畫出fitting plot,並在指令列輸出training error及five-fold cross-validation errors。
> fitting plot :
> Problem2_linear_fitting_plot.png
### 第三題
> 執行`main_p3.py`
* #### 產生資料集
1. `generate`函式會引入`LinearDataLoader`類別建立`dataloader`物件,此物件會根據加入Gaussion noise $ε$ ~ $N(0, 1)$ 的方程式 $y = 2x + ε$ 產生15筆屬於 $[-3,3]$ 且等間距的點,並畫出Problem3_dataset.png資料分布圖。
2. 在`polyFeatures`函式中引入scikit-Learn套件的`PolynomialFeatures`函式,根據第三題的Hint將$X$依照degree 5 ,10, 14轉換成多項式資料。
* #### 多項式迴歸
* `polynomialRegression`函式會引入`LinearRegressionModel`類別建立`model`物件,該類別中的`fit`函式實作線性迴歸中的$Normal Equation$公式解(參第二題-線性迴歸)。
* 得到 $\theta$ 後,使用`predict`函式計算出 y_predicted 數值(參第二題-線性迴歸)。
* #### 輸出結果
* 呼叫`result_LR`函式分別針對degree 5 ,10, 14畫出fitting plot,並在指令列輸出training error及five-fold cross-validation errors
> fitting plot :
> Problem3_polynomial_deg5_fitting_plot.png
> Problem3_polynomial_deg10_fitting_plot.png
> Problem3_polynomial_deg14_fitting_plot.png
### 第四題
> 執行`main_p4.py`
* #### 產生資料集
* `generate`函式會引入`PolynomialDataLoader`類別建立`dataloader`物件,此物件會根據加入Gaussion noise $ε$ ~ $N(0, 0.04)$ 的方程式 $y = sin(2πx) + ε$ 產生15筆屬於 $[0,1]$ 且等間距的點,並畫出Problem4_dataset.png資料分布圖。
* #### 線性迴歸 + 輸出結果
* `linear`函式會引入`main_p2.py`中的`linearRegression`函式,該函式已實作`fit`與`predict函式`(參第二題-線性迴歸)。
* 呼叫`result_LR`函式畫出fitting plot,並在指令列輸出training error及five-fold cross-validation errors。
> fitting plot :
> Problem4-1_linear_fitting_plot.png
* #### 多項式迴歸 + 輸出結果
* `polynomial`函式會引入`main_p3.py`中的`polynomialRegression`函式,該函式已實作`fit`與`predict函式`(參第二題-線性迴歸)。
* 呼叫`result_PR`函式分別針對degree 5 ,10, 14畫出fitting plot,並在指令列輸出training error及five-fold cross-validation errors
> fitting plot :
> Problem4-2_polynomial_deg5_fitting_plot.png
> Problem4-2_polynomial_deg10_fitting_plot.png
> Problem4-2_polynomial_deg14_fitting_plot.png
### 第五題
> 執行`main_p5.py`
* #### 產生資料集
* 分別代入 $m$ = 10, 80, 320至`generate`函式。
* `generate`函式會引入`PolynomialDataLoader`類別建立`dataloader`物件,此物件會根據加入Gaussion noise $ε$ ~ $N(0, 0.04)$ 的方程式 $y = sin(2πx) + ε$ 產生 $m$ 筆屬於 $[0,1]$ 且等間距的點,並畫出Problem5_dataset_m10.png、Problem5_dataset_m80.png、Problem5_dataset_m320.png資料分布圖。
* #### 多項式迴歸 + 輸出結果
* 引入`main_p3.py`中的`polyFeatures`函式,將$X$依照degree 14轉換成多項式資料。
* 引入`main_p3.py`中的`polynomialRegression`函式,該函式已實作`fit`與`predict函式`(參第二題-線性迴歸)。
* 呼叫`result_PR`函式,在degree 14分別針對m 10, 80, 320畫出fitting plot,並在指令列輸出training error及five-fold cross-validation errors
> fitting plot :
> Problem5_polynomial_deg14_m10_fitting_plot.png
> Problem5_polynomial_deg14_m80_fitting_plot.png
> Problem5_polynomial_deg14_m320_fitting_plot.png
### 第六題
> 執行`main_p6.py`
* #### 產生資料集
* $m = 15$
* `generate`函式會引入`PolynomialDataLoader`類別建立`dataloader`物件,此物件會根據加入Gaussion noise $ε$ ~ $N(0, 0.04)$ 的方程式 $y = sin(2πx) + ε$ 產生 $m$ 筆屬於 $[0,1]$ 且等間距的點,並畫出Problem6_dataset.png資料分布圖。
* #### 多項式迴歸 + 輸出結果
* 引入`main_p3.py`中的`polyFeatures`函式,將$X$依照degree 14轉換成多項式資料。
* 定義`polynomialRegression_`函式,首先引入`LinearRegressionModel_L2`類別建立`model`物件,該類別中的`fit`函式實作了線性迴歸中的$Normal Equation + regularization$: $$w_{LIN}=(X^{T}X+λI)^{-1}X^{T}y$$
```python=
# The Normal Equation + L2 Regularization
temp = np.dot(X.T, X).shape
self.theta = np.dot(np.linalg.inv(np.dot(X.T, X) + self.lmda * np.identity(temp[0])), np.dot(X.T, y))
* 接著分別代入 $λ$ = 0 , 0.001/m , 1/m , 1000/m,分別得出各自的$w_{LIN}$,使用`predict`函式計算出 y_predicted 數值,實作基於以下公式: $$ \hat{y_{n}}=w_{LIN}^{T}x_{n}$$
```linux=
preds = np.dot(X, self.theta)
```
* 呼叫`result_PR`函式,在degree 14分別針對 $λ$ = 0 , 0.001/m , 1/m , 1000/m畫出fitting plot,並在指令列輸出training error及five-fold cross-validation errors
> fitting plot :
> Problem6_lambda0_fitting_plot.png
> Problem6_lambda0.001_m_fitting_plot.png
> Problem6_lambda1_m_fitting_plot.png
> Problem6_lambda1000_m_fitting_plot.png
## Experimental results
### 第一題
* Dataset資料分布圖
| m | 說明 | `Problem1_dataset.png` |
| -------- | -------- | -------- |
| 15 | 圖中<span style="color:blue">藍色虛線</span>代表 $y = 2x$ 方程式 |  |
### 第二題
* Dataset資料分布圖
| m | 說明 | `Problem2_dataset.png` |
| -------- | -------- | -------- |
| 15 | 圖中<span style="color:blue">藍色虛線</span>代表 $y = 2x$ 方程式 | |
* Linear Regression fitting plot
> 圖中<span style="color:purple">紫色實線</span>代表模型產生的擬合
| the training error | 5-fold cross-validation errors | Result |
| -------- | -------- | -------- |
| 0.8964992526345636 | [-0.04810712 -1.96706334 -0.44430244 -1.72981605 -1.3645887 ] | |
### 第三題
* Dataset資料分布圖
| m | 說明 | `Problem3_dataset.png` |
| -------- | -------- | -------- |
| 15 | 圖中<span style="color:blue">藍色虛線</span>代表 $y = 2x$ 方程式 | |
* Polynomial Regression fitting plot
> 圖中<span style="color:blue">藍色虛線</span>代表 $y = 2x$ 方程式,<span style="color:purple">紫色實線</span>代表模型產生的擬合
degree | the training error | 5-fold cross-validation errors | Result |
| --------| -------- | -------- | -------- |
| 5| 1.0237825706969441 | [ -30.47502251 -4.79297531 -3.18617494 -3.55245159 -178.32849592] | |
| 10| 0.7274995205660019 | [-2.32915571e+07 -3.46602901e+02 -1.18478742e+02 -1.08917069e+03 -5.13077210e+08] | |
| 14| 5.5699897482027674e-11 | [-1.04879400e+07 -1.31826246e+02 -7.80325447e+01 -1.25908124e+03 -1.61189445e+08] | |
### 第四題
* Dataset資料分布圖
| m | 說明 | `Problem4_dataset.png` |
| -------- | -------- | -------- |
| 15 | 圖中<span style="color:blue">藍色虛線</span>代表 $y = sin(2πx)$ 方程式 ||
* Linear Regression fitting plot
> 圖中<span style="color:purple">紫色實線</span>代表模型產生的擬合
| the training error | 5-fold cross-validation errors | Result |
| -------- | -------- | -------- |
| 0.2465849105402421 | [-0.63311177 -0.7355077 -0.06815203 -0.68571631 -0.68740372] | |
* Polynomial Regression fitting plot
> 圖中<span style="color:blue">藍色虛線</span>代表 $y = sin(2πx)$ 方程式,<span style="color:purple">紫色實線</span>代表模型產生的擬合
|degree | the training error | 5-fold cross-validation errors | Result |
| --------| -------- | -------- | -------- |
| 5| 0.0014616666934130422 | [-0.00984511 -0.00963286 -0.00428898 -0.00234264 -0.23753631] | |
| 10| 0.0006617456926407959 | [-6.15112941e+03 -1.37956774e+00 -1.03498534e-02 -1.57689634e-01 -1.15482767e+04] ||
| 14| 0.30725359519219175 | [-3.71501121e+02 -1.46598200e+00 -5.48066285e-02 -1.09184283e+02 -3.77850067e+08] ||
### 第五題
* Dataset資料分布圖
| m | 說明 | `Problem5_dataset_m10.png` `Problem5_dataset_m80.png` `Problem5_dataset_m320.png` |
| -------- | -------- | -------- |
| 10 | 圖中<span style="color:blue">藍色虛線</span>代表 $y = sin(2πx)$ 方程式 ||
| 80 | 圖中<span style="color:blue">藍色虛線</span>代表 $y = sin(2πx)$ 方程式 ||
| 320 | 圖中<span style="color:blue">藍色虛線</span>代表 $y = sin(2πx)$ 方程式 ||
* Polynomial Regression fitting plot
> 圖中<span style="color:blue">藍色虛線</span>代表 $y = sin(2πx)$ 方程式,<span style="color:purple">紫色實線</span>代表模型產生的擬合
|m | the training error | 5-fold cross-validation errors | Result |
| --------| -------- | -------- | -------- |
| 10| 0.26579638461646415 | [-5.34474871e+00 -2.69572472e-02 -1.28324989e+01 -1.20571907e-01 -2.26045959e+02] ||
| 80| 0.09702557395514014 | [-7.80439730e+01 -9.83597401e-03 -2.80287668e-02 -2.60831038e-03 -1.55851669e+05] ||
| 320| 0.009371370542904935 | [-2.36947024e+03 -7.82045120e-03 -5.12510575e-03 -3.59297386e-03 -1.36939954e+04] ||
### 第六題
* Dataset資料分布圖
| m | 說明 | `Problem6_dataset.png` |
| -------- | -------- | -------- |
| 15 | 圖中<span style="color:blue">藍色虛線</span>代表 $y = sin(2πx)$ 方程式 |
|
* Polynomial Regression + weight-decay regularization fitting plot
> 圖中<span style="color:blue">藍色虛線</span>代表 $y = sin(2πx)$ 方程式,<span style="color:purple">紫色實線</span>代表模型產生的擬合
| $λ$ | the training error | 5-fold cross-validation errors | Result |
| --------| -------- | -------- | -------- |
| 0| 0.7261844030043304 | [-2.50383054e+04 -3.78808618e+00 -1.32271121e-02 -1.24534303e+01 -2.54983378e+07] ||
| 0.001/m|0.0015849940672020915 | [-7.93788882e-02 -4.08927160e-03 -1.68043575e-02 -1.90180453e-02 -1.34337946e+01] | |
| 1/m| 0.10696137036854274 | [-0.84285473 -0.53992693 -0.05073262 -0.3311832 -3.29782521] ||
| 1000/m|0.4509918241572265 | [-0.31590819 -0.8695116 -0.14364495 -0.91238358 -0.2338576 ] ||
## Conclusion
* 根據第三、四題的實驗結果,在使用線性迴歸時,若資料使用多項式產生,則效果不好;在使用多項式迴歸時,若資料是使用多項式產生,效果會比資料使用線性方程式產生時來的好。
* 根據第五題的實驗結果,可以發現使用越大的資料集,在使用多項式迴歸時效果更好。
* 根據第六題的實驗結果,調高 $λ$ 可減輕overfitting,因 $w_{LIN}$ 被控制的越短;可觀察到在0.001/m時效果最佳,$λ$ 大於此值則越趨向underfitting。
## Discussion
* 因為sklearn套件中的`cross_val_scoreestimator`需要實作estimator物件才能使用,花了滿多時間在了解官方文檔。
* 這次作業需要一些重複的實驗結果,花了一些時間將可重複用的函式物件化。