Machine Learning A-Z(2)

將 Data 分為 Training set 和 Test set

1
2
3
4
5
6
7
8
A.下載 Dataset
B.導入標準庫
C.導入 Dataset
D.缺失 Data
E.分類 Data
F.將 Data 分為 Training set 和 Test set
G.特徵縮放
H.Data 預處理模板

所謂機器學習,就是讓機器知道數據之間的關係

並用學習到的結果,對新的資訊來做預測

一般來說,當你拿到一組 dataset 之後

會把 dataset 分為 Training set 和 Test set

或是 Training set 和 Test set 和 validation set

不過一般會忽略 validation set

2017_12_03_1.png

舉例來說你可能會拿到 100 筆 dataset 資料

那我們會把 100 筆中隨機拿 80 筆資料出來當 Training set

機器透過 Training set 會自己產生一個”模型”出來

最後再將剩下的 20 筆資料丟進此”模型”

來驗證此模型是否有好的預測能力

以下是 python 作法,目前我們已經有 2 個 dataset

分別是 X 和 y,所以將此 2 個 dataset 分別建立 Training set 和 Test set

所以最後會有 4 組資料

1
2
3
X -> X Training & X Test

y -> y Training & y Test

其中 X 屬於字變量,y 屬於應變量(結果)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from sklearn.model_selection import train_test_split
X_train,X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)

/*
train_test_split 第一個參數是 array
要傳入想要分割為 Training set 和 Test set 的 dataset
此處當然是傳入 X 和 y

test_size 參數表示你想要將 dataset 中,多少比例變為 Test set
剛剛說過如果 100 筆資料,你想要 20 筆變成 Test set
那 test_size 就輸入 0.20,所以此參數是個比例的意思,藉由 0.0 - 1.0 之間
通常不會將 Test set 分配超過 0.50 ,這樣會導致 Training set 太少

train_size 參數就可以省略不寫,因為你設定好 Test set 比率後
就知道 Training set 比率是多少,由此可知為 0.80

random_state 設定如何從 dataset 中取資料分配到 Training set 和 Test set
如果 = 0 表示固定
*/

結果如下

2017_12_03_2.png

所以機器會開始學習 X_train 和 y_train 之間的關係

我們稱這個過程為擬合,而機器最後學習完產生的模型就稱為擬合模型

之後就會用 X_test 丟進此模型來看結果是否和 y_test 差不多

但此過程會遇到一些問題

1.過度擬合(overfitting)

所謂 overfitting 就是說,這個訓練好的模型

只有將 Training set 的資料丟進去才會出現好的預測結果

但如果將 Test set 資料丟進去,預測結果卻很爛

此狀況就為 overfitting

也就是機器學習太多 Training set 的資訊

導致機器只會處理 Training set 裡面的資料

以下是 R 的操作

1
2
# 安裝 lib
install.packages('caTools')

使用 caTools

2017_12_03_3.png

另一種方法,建議使用這種

1
library(caTools)

以下是完整程式

1
2
3
4
5
library(caTools)
set.seed(123)
split = sample.split(dataset$Purchased, SplitRatio = 0.8)
training_set = subset(dataset, split == TRUE )
test_set = subset(dataset, split == FALSE )

G.特徵縮放

先看原本的 dataset

Age 範圍在 27-50

Salary 範圍在 50000-90000

這 2 個變量不是在同一個數量級上

1
2
3
4
5
6
7
8
9
10
11
   Country      Age   Salary Purchased
1 1 44.00000 72000.00 0
2 2 27.00000 48000.00 1
3 3 30.00000 54000.00 0
4 2 38.00000 61000.00 0
5 3 40.00000 63777.78 1
6 1 35.00000 58000.00 1
7 2 38.77778 52000.00 0
8 1 48.00000 79000.00 1
9 3 50.00000 83000.00 0
10 1 37.00000 67000.00 1

歐式距離

2D 坐標系上 2 點的距離

例如 P1(x1,y1),P2(x2,y2)

歐式距離(畢氏定理) = √((x2 - x1)^2 + (y2 - y1)^2)

舉例來說,上述 dataset 取兩點

1
2
3
4
5
6
7
   Country      Age   Salary Purchased
2 2 27.00000 48000.00 1 P1
9 3 50.00000 83000.00 0 P2


x = (50 - 27)^2 = 529
y = (83000 - 48000)^2 = 1225000000

由此可看到,兩數的級距過大,導致 x 可有可無

主要會被 y 所影響,在學習中導致效果不好

所以會想將 2 數據變到同一個級距

也就是特徵縮放,這是第一點需要特徵縮放的意義

第二點是在某些情況如果先使用特徵縮放,收斂會比較快(決策樹)

特徵縮放有 2 種方法

1
2
1.Standardisation 標準化
2.Normalisation 正規化 (0-1 之間)

python 作法

1
2
3
4
5
6
7
8
9
# X_train
array([[ 0. , 1. , 0. , 40. , 63777.778],
[ 1. , 0. , 0. , 37. , 67000. ],
[ 0. , 0. , 1. , 27. , 48000. ],
[ 0. , 0. , 1. , 38.778, 52000. ],
[ 1. , 0. , 0. , 48. , 79000. ],
[ 0. , 0. , 1. , 38. , 61000. ],
[ 1. , 0. , 0. , 44. , 72000. ],
[ 1. , 0. , 0. , 35. , 58000. ]])

注意虛擬變量雖然是 0/1,可以不用做特徵縮放

不過有時候對虛擬變量做特徵縮放,會提高效能,所以此處還是對所有數值都做特徵縮放

1
2
3
4
from sklearn.preprocessing import StandardScaler
sc_X = StandardScaler()
X_train = sc_X.fit_transform(X_train)
X_test = sc_X.transform(X_test)

做完如下圖

2017_12_06_1.png

R 的作法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
training_set = scale(training_set)
test_set = scale(test_set)

會出現錯誤
> training_set = scale(training_set)
Error in colMeans(x, na.rm = TRUE) : 'x' must be numeric
> test_set = scale(test_set)
Error in colMeans(x, na.rm = TRUE) : 'x' must be numeric

這表示 training_set & test_set 其中有些不是數字 (numeric)
> training_set
Country Age Salary Purchased
1 1 44.00000 72000.00 0
2 2 27.00000 48000.00 1
3 3 30.00000 54000.00 0
4 2 38.00000 61000.00 0
5 3 40.00000 63777.78 1
7 2 38.77778 52000.00 0
8 1 48.00000 79000.00 1
10 1 37.00000 67000.00 1

Country 和 Purchased 雖然看上去是數字
但實際上是"分類因子"

所以只對年齡和薪水做特徵縮放

1
2
training_set[,2:3] = scale(training_set[,2:3])
test_set[,2:3] = scale(test_set[,2:3])

H.Data 預處理模板

python 目前程式碼如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Data Preprocessing Template

# Importing the libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# Importing the dataset
dataset = pd.read_csv('Data.csv')
X = dataset.iloc[:, :-1].values
y = dataset.iloc[:, 3].values

# Taking care of missing data
from sklearn.preprocessing import Imputer
imputer = Imputer(missing_values='NaN',strategy='mean',axis=0).fit(X[:,1:3])
X[:,1:3] = imputer.transform(X[:,1:3])

# Encodig catagorical data
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
labelencoder_X = LabelEncoder()
X[:,0] = labelencoder_X.fit_transform(X[:,0])
onehotencoder = OneHotEncoder(categorical_features=[0])
X = onehotencoder.fit_transform(X).toarray()
labelencoder_y = LabelEncoder()
y = labelencoder_y.fit_transform(y)

# Splitting the dataset into the Training set and Test set
from sklearn.model_selection import train_test_split
X_train,X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)

# Feature Scaling
from sklearn.preprocessing import StandardScaler
sc_X = StandardScaler()
X_train = sc_X.fit_transform(X_train)
X_test = sc_X.transform(X_test)

刪除目前比較少用到的程式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Data Preprocessing Template

# Importing the libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# Importing the dataset
dataset = pd.read_csv('Data.csv')
X = dataset.iloc[:, :-1].values
y = dataset.iloc[:, 3].values

# Splitting the dataset into the Training set and Test set
from sklearn.model_selection import train_test_split
X_train,X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0)

# Feature Scaling
"""
from sklearn.preprocessing import StandardScaler
sc_X = StandardScaler()
X_train = sc_X.fit_transform(X_train)
X_test = sc_X.transform(X_test)
"""

R 目前程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Data Preprocessing Template

# Importing the dataset
dataset = read.csv('Data.csv')

# Taking care of missing data
dataset$Age[is.na(dataset$Age)] = mean(dataset$Age, na.rm = T)
dataset$Salary[is.na(dataset$Salary)] = mean(dataset$Salary, na.rm = T)

# Enconding categorical data
dataset$Country = factor(dataset$Country,
levels = c('France', 'Spain', 'Germany'),
labels = c(1,2,3))

dataset$Purchased = factor(dataset$Purchased,
levels = c('No','Yes'),
labels = c(0,1))


# Splitting the dataset into the Training set and Test set
#install.packages('caTools')
library(caTools)
set.seed(123)
split = sample.split(dataset$Purchased, SplitRatio = 0.8)
training_set = subset(dataset, split == TRUE )
test_set = subset(dataset, split == FALSE )

# Feature Scaling
training_set[,2:3] = scale(training_set[,2:3])
test_set[,2:3] = scale(test_set[,2:3])

刪除不需要的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Data Preprocessing Template

# Importing the dataset
dataset = read.csv('Data.csv')
#dataset = dataset[,2:3]

# Splitting the dataset into the Training set and Test set
#install.packages('caTools')
library(caTools)
set.seed(123)
split = sample.split(dataset$Purchased, SplitRatio = 0.8)
training_set = subset(dataset, split == TRUE )
test_set = subset(dataset, split == FALSE )

# Feature Scaling
# training_set[,2:3] = scale(training_set[,2:3])
# test_set[,2:3] = scale(test_set[,2:3])