###### tags: `Machine Learning`,`Rregression`,`train_test_split`,`MSE`,`R**2`
# Machine Learning 基礎篇train_test_split(訓練和測試資料集)
在機器學習中,我們通常將原始數據按照比例分割為==測試集==和==訓練集==,從 sklearn套件使用train_test_split 函數來將數據分成兩個類別
| 資料比例 | train dataset | test dataset |
| ----- | --- | --- |
| 4:1| 80% | 20% |
| 3:1| 67% | 33% |
**from sklearn.model_selection import train_test_split**
XTrain, XTest, yTrain ,yTest = train_test_split(X, y, test_size=0.33, random_state=5)
**train_test_split**(*arrays **options)
>返回的危亂序的結果(random)
>X:資料集的特徵值array
>y:資料集的目標值array
>test_size:測試集的大小,一般為float類型,常用百分比表示
>random_state:隨機數種子(seed),不同seed會造成不同的隨機採樣結果,相同seed採樣結果相同
>return:訓練集特徵值(X_train)、測試集特徵值(X_test)、訓練集目標值(y_train)、訓練集目標值(y_test)
==隨機數種子 random_state==
>因為scikit-learn中很多算法含有隨機的因素,為了進行可重複的訓練,我們需要固定一個random_state。
>這個種子就是一個控制器,控制每次的隨機,設定了引數後,隨機的結果都是一致的,可以避免不必要的變數存在。
>如下圖範例
== 無隨機數種子==
==>每次結果皆為亂數


== 有隨機數種子==


==案例導入boston房屋資料集==
```python=
import pandas as pd
import numpy as np
from sklearn import datasets
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split as tts
import matplotlib.pyplot as plt
boston = datasets.load_boston()
X = pd.DataFrame(boston.data, columns=boston.feature_names)
target = pd.DataFrame(boston.target ,columns=["MEDV"])
y = target["MEDV"]
#帶入train_test_split =>會帶出四個值(XTrain, XTest, yTrain ,yTest)記得要使用有意義的名稱去代表
#順序不能亂掉,勿取名為A,B,C,D之類的變數名稱
XTrain, XTest, yTrain ,yTest = tts(X, y, test_size=0.33, random_state=5)
lm = LinearRegression()
lm.fit(XTrain, yTrain) #fit代表開始訓練資料集
#假設有100張照片,1/3拿去做測試,2/3拿去做訓練資料集
#代表有看過的題目(2/3),再拿去做預測
pred_train = lm.predict(XTrain)#這是為了跟下面這組對照用,事實上沒必要寫
#因為用訓練過的資料集再去預測,會失真,一般train出來績效會很好
#代表拿沒看過的題目(1/3),去做預測
pred_test = lm.predict(XTest)#一般都只寫這一組
#用沒Train過的資料拿來做預估,才能有效看出模型的能力
#預測模型的績效
MSE_train = np.mean((yTrain-pred_train)**2) #np.mean取平均值
MSE_test = np.mean((yTest-pred_test)**2)#實際值-值預估
#訓練的MSE一定比沒訓練的值來的好(誤差比較小)
print("訓練資料MSE:", MSE_train)
print("測試資料的MSE:", MSE_test)
#MSE & R squre都是績效評估的指標
print("訓練資料的R-squared:",lm.score(XTrain, yTrain))
print("測試資料的R-squared:",lm.score(XTest, yTest))
#訓練過的解釋能力一定比沒訓練過的來的好
plt.scatter(yTest, pred_test)
plt.xlabel("Price")
plt.ylabel("Predicted Price")
plt.title("Price vs Predicted Price")#下圖可以判斷預估與實際值是否貼近
plt.show()
```

==預測模型的績效(常用)==
* MSE
* R平方
>MSE(Mean Squrared Error):MSE可以告訴我們資料集的點是如何接近回歸線,測量各點至回歸線的距離(這些距離稱為誤差)的平方和後,計算出其平均值。
>因為誤差,所以值越小代表模型越好。

>R平方(R^2^)
>R-squared:也稱決定係數(Coefficient of Determination),可以告訴我們資料集是如何符合回歸線。
>R^2^的定義,代表回歸模式的變異值與所有yi變異量之比例,R^2^越大,代表此回歸模式能夠解釋全體yi變異量的比例越大。R^2^結果越接近1.0,則代表此模型越有解釋能力。
>R^2^的值是0~1,其值越大,模型越好。
>==*可直接套用Scikit-learn的score()函數直接計算R-squared。*==

==**結果探討,MSE & R-squred都是績效評估的指標**==
* 有訓練過的MSE一定比沒訓練的值來的好(誤差比較小)
* R^2^:訓練過的解釋能力一定比沒訓練過的來的好,數值越接近1.0
**概念:有做過參考書練習的學生,一般都會比未做過參考書的學生分數高**

==sample 2 糖尿病資料集練習==
```python=
import pandas as pd
from sklearn import datasets
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split as tts
import numpy as np
diabetes = datasets.load_diabetes()
X = pd.DataFrame(diabetes.data, columns=diabetes.feature_names)
target = pd.DataFrame(diabetes.target ,columns=["Target"])
y = target["Target"]
#不分割資料集
#XTrain, XTest, yTrain ,yTest = tts(X, y)
lm = LinearRegression()
lm.fit(X, y)
pred_test = lm.predict(X)
MES_test = np.mean((y-pred_test)**2)
print("不分割_MSE: ",MES_test)
print("不分割_R-squared: ",lm.score(X, y))
#分割資料集(3:1),亂數種子:100,求MSE & R-squared
X1_Train, X1_Test, y1_Train ,y1_Test = tts(X, y, test_size=0.25, random_state=100)
lm_1 = LinearRegression()
lm_1.fit(X1_Train, y1_Train)
pred_test1 = lm_1.predict(X1_Test)
MES_test1 = np.mean((y1_Test-pred_test1)**2)
print("*************************************")
print("分割3:1_MSE: ",MES_test1)
print("分割3:1_R-squared: ",lm.score(X1_Test, y1_Test))
#分割資料集(4:1),亂數種子:100,求MSE & R-squared
X2_Train, X2_Test, y2_Train ,y2_Test = tts(X, y, test_size=0.2, random_state=100)
lm_2 = LinearRegression()
lm_2.fit(X2_Train, y2_Train)
pred_test2 = lm_2.predict(X2_Test)
MES_test2 = np.mean((y2_Test-pred_test2)**2)
print("*************************************")
print("分割4:1_MSE: ",MES_test2)
print("分割4:1_R-squared: ",lm.score(X2_Test, y2_Test))
```
**結論**
以資料集分割3:1的模式可得到R^2^較高的數值結果!
