###### 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。 >這個種子就是一個控制器,控制每次的隨機,設定了引數後,隨機的結果都是一致的,可以避免不必要的變數存在。 >如下圖範例 == 無隨機數種子== ==>每次結果皆為亂數 ![](https://hackmd.io/_uploads/SknbT7IVh.png) ![](https://hackmd.io/_uploads/rJQsjm8Eh.png) == 有隨機數種子== ![](https://hackmd.io/_uploads/Sk833mI4h.png) ![](https://hackmd.io/_uploads/Sk6hhXU42.png) ==案例導入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() ``` ![](https://hackmd.io/_uploads/rkBtxV84n.png) ==預測模型的績效(常用)== * MSE * R平方 >MSE(Mean Squrared Error):MSE可以告訴我們資料集的點是如何接近回歸線,測量各點至回歸線的距離(這些距離稱為誤差)的平方和後,計算出其平均值。 >因為誤差,所以值越小代表模型越好。 ![](https://hackmd.io/_uploads/By5jzEUE2.png) >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。*== ![](https://hackmd.io/_uploads/S1cP8E84h.png) ==**結果探討,MSE & R-squred都是績效評估的指標**== * 有訓練過的MSE一定比沒訓練的值來的好(誤差比較小) * R^2^:訓練過的解釋能力一定比沒訓練過的來的好,數值越接近1.0 **概念:有做過參考書練習的學生,一般都會比未做過參考書的學生分數高** ![](https://hackmd.io/_uploads/ryUZlNIE2.png) ==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^較高的數值結果! ![](https://hackmd.io/_uploads/HyZNvBU42.png)