AML

[Thực hành] Bài 16 Mạng thần kinh nhân tạo - Artificial Neural Network

Loạt bài học thuộc series AML

Posted by KyoHB on May 28, 2021

Trong bài số 16 này chúng ta sẽ cùng tìm hiểu các bước để xây dựng một model ANN hoàn chỉnh thông qua thư viện Keras nhé.

Import tập dữ liệu

Giống như các bài thực hành trước, tập dữ liệu (dataset) về người trưởng thành sẽ được sử dụng để huấn luyện (training) model ANN. Sau khi quá trình training kết thúc chúng ta sẽ thực hiện so sánh các điểm khác biệt trong hiệu năng (performance) với các model đã được huấn luyện (training) trước đó nhé !

1
import pandas as pd
1
2
df = pd.read_csv('/content/new_adult_data.csv')
df
0 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 36 37 38 39 ... 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000503 0.999607 0.000168 0.028035 0.0 0.000516 0.0
1 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000600 1.000000 0.000156 0.000000 0.0 0.000156 0.0
2 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000176 1.000000 0.000042 0.000000 0.0 0.000185 0.0
3 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000226 1.000000 0.000030 0.000000 0.0 0.000170 0.0
4 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.000083 1.000000 0.000038 0.000000 0.0 0.000118 0.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
45303 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000272 1.000000 0.000083 0.000000 0.0 0.000256 1.0
45304 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000240 1.000000 0.000063 0.000000 0.0 0.000226 1.0
45305 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000794 0.999999 0.000178 0.000000 0.0 0.000690 1.0
45306 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000191 1.000000 0.000065 0.000000 0.0 0.000198 1.0
45307 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000231 1.000000 0.000057 0.000000 0.0 0.000266 1.0

45308 rows × 105 columns

Phân chia tập dữ liệu

Tách biến không phụ thuộc (independent variable) và biến phụ thuộc (dependent variable) từ tập dữ liệu (dataset)

1
2
x = df.iloc[:,0:104]
y = df.iloc[:,104]

Tiếp theo chúng ta sẽ phân chia tập dữ liệu (dataset) thành hai tập nhỏ hơn: tập dữ liệu huấn luyện (training set) và tập dữ liệu xác nhận (validation set) với tỷ lệ 80% và 20%.

  • random_state nhằm đảm bảo việc phân chia dữ liệu là như nhau trong mọi lần chạy.
1
from sklearn.model_selection import train_test_split
1
X_train, X_valid, Y_train, Y_valid = train_test_split(x, y, test_size = 0.2, random_state = 101)

Giờ chúng ta sẽ tiến hành xây dựng model ANN, việc đầu tiên cần làm đầu tiên đó là lựa chọn kiến trúc !!! Model ANN của chúng ta sẽ có số nơron ở lớp đầu vào (input layer) là 104, tương ứng theo số biến không phụ thuộc (independent variable), trong khi đó ở lớp đầu ra (output layer) số nơron sẽ là 2 do chúng ta có 2 nhóm (class) cần phân loại. Số nơron và số lớp ở lớp ẩn (hidden layer) thì chúng ta có thể tùy ý chọn. Về lý thuyết mạng (network) càng có độ phức tạp cao (nhiều nơron, nhiều lớp ẩn) sẽ càng có độ chính xác cao hơn. Tuy nhiên cũng có thể độ chính xác (accuracy) cao này do model quá vừa vặn (overfit) với tập huấn luyện (training set) mà thiếu đi tính tổng quát (generalize). Để có thể tìm ra một model ANN tốt nhất, chúng ta sẽ huấn luyện (training) 2 model ANN với lớp ẩn (hidden layer) khác nhau để so sánh và đưa ra lựa chọn cuối cùng.

Huấn luyện ANN model

1
2
# import keras
from tensorflow import keras

Kiến trúc thứ nhất

1
2
3
4
5
6
7
8
# Khởi tạo ANN model
ann_model_1 = keras.models.Sequential()
# Lớp ẩn (hidden layer) đầu tiên với 1024 nơron, với đầu vào là 104 tương ứng theo số biến không phụ thuộc (independent variable)
ann_model_1.add(keras.layers.Dense(1024, input_dim=104, activation='relu'))
# Lớp ẩn (hidden layer) thứ 2 cũng với 1024 nơron
ann_model_1.add(keras.layers.Dense(1024, activation='relu'))
# Lớp đầu ra (output layer), ở đây hàm kích hoạt softmax do đây là bài toán phân loại (classification)
ann_model_1.add(keras.layers.Dense(2, activation='softmax'))
1
2
# Tóm tắt kiến trúc ANN đầu tiên, với các thông tin về tên lớp (layer), loại lớp, chiều (shape) của lớp và số thông số (parameter) cần phải tính toán
ann_model_1.summary()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 1024)              107520    
_________________________________________________________________
dense_1 (Dense)              (None, 1024)              1049600   
_________________________________________________________________
dense_2 (Dense)              (None, 2)                 2050      
=================================================================
Total params: 1,159,170
Trainable params: 1,159,170
Non-trainable params: 0
_________________________________________________________________
1
2
# Trực quan hơn chúng ta có thể dùng cách này để vẽ kiến trúc ANN model ra
keras.utils.plot_model(ann_model_1, "ann_model_1_architecture.png", show_shapes=True)

png

Trước khi tiến hành huấn luyện (training) chúng ta cần biên dịch kiến trúc ANN model trên. Trong quá trình này chúng ta sẽ định nghĩa hàm mất mát (loss function), thuật toán tối ưu (optimizer), và phương thức để so sánh hiệu năng của model.

1
2
3
4
# Biên dịch kiến trúc ANN model
ann_model_1.compile(loss='sparse_categorical_crossentropy',
                    optimizer='adam',
                    metrics=["accuracy"])
1
2
# Thêm tính năng dừng sớm để tránh việc quá vừa vặn (overfit)
early_stopping_cb = keras.callbacks.EarlyStopping(patience=5, restore_best_weights=True)
1
2
3
4
5
6
# Huấn luyện ANN model
history_model_ann_1 = ann_model_1.fit(X_train, 
                                      Y_train.values.astype(int), 
                                      epochs=30, 
                                      validation_data=(X_valid, Y_valid), 
                                      callbacks=early_stopping_cb)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Epoch 1/30
1133/1133 [==============================] - 28s 25ms/step - loss: 0.2760 - accuracy: 0.8766 - val_loss: 0.3981 - val_accuracy: 0.8578
Epoch 2/30
1133/1133 [==============================] - 26s 23ms/step - loss: 0.2753 - accuracy: 0.8787 - val_loss: 0.3954 - val_accuracy: 0.8615
Epoch 3/30
1133/1133 [==============================] - 27s 24ms/step - loss: 0.2728 - accuracy: 0.8801 - val_loss: 0.4430 - val_accuracy: 0.8615
Epoch 4/30
1133/1133 [==============================] - 26s 23ms/step - loss: 0.2708 - accuracy: 0.8800 - val_loss: 0.4161 - val_accuracy: 0.8561
Epoch 5/30
1133/1133 [==============================] - 26s 23ms/step - loss: 0.2701 - accuracy: 0.8793 - val_loss: 0.4163 - val_accuracy: 0.8573
Epoch 6/30
1133/1133 [==============================] - 26s 23ms/step - loss: 0.2686 - accuracy: 0.8801 - val_loss: 0.4189 - val_accuracy: 0.8581
Epoch 7/30
1133/1133 [==============================] - 28s 24ms/step - loss: 0.2671 - accuracy: 0.8803 - val_loss: 0.4470 - val_accuracy: 0.8575
1
2
3
4
5
6
7
# Vẽ biểu đồ quá trình huấn luyện
import pandas as pd
import matplotlib.pyplot as plt

pd.DataFrame(history_model_ann_1.history).plot(figsize=(8,5))
plt.grid(True)
plt.show()

png

Qua biểu đồ ở trên chúng ta có thể thấy model đạt trạng thái tốt nhất ở epoch 2, sau epoch này model dần trở nên quá vừa vặn (overfit) với tập huấn luyện (training set). Điều này có thể nhìn thấy qua sai số (loss) ở tập xác nhận (validation set) có xu hướng đi lên lên sau epoch 2, từ đó đến khoảng cách giữa sai số (loss) ở tập xác nhận (validation set) và tập huấn luyện (training set) ngày càng lớn. Việc sử dụng tính năng dừng sớm (Early stopping callback) giúp chúng ta tránh mất quá nhiều thời gian cho việc training khi model dần trở nên quá vừa vặn (overfit). Tính năng này sẽ thực hiện kiểm soát sự tăng, giảm, không thay đổi sai số (loss) trên tập xác nhận (validation set), nếu như sai số (loss) này không thay đổi, hay tăng quá số epoch kiên nhẫn, Keras sẽ dừng sớm việc huấn luyện (training). Cùng với đó hồi phục lại trạng thái tốt nhất của model đã đạt được trước đó. Sau quá trình huấn luyện (training) chúng ta có thể lưu ANN model này lại để có thể sử dụng trong tương lai.

1
2
# Lưu model
ann_model_1.save('ann_model_1.h5')

Kiến trúc thứ 2

Tiếp theo chúng ta sẽ tăng độ sâu cho kiến trúc ANN trên bằng cách tăng số lượng lớp và số nơron ở lớp ẩn (hidden layer).

1
2
3
4
5
6
7
8
9
10
# Khởi tạo ANN model
ann_model_2 = keras.models.Sequential()
# Lớp ẩn (hidden layer) đầu tiên với 2048 nơron, với đầu vào là 104 tương ứng theo số biến không phụ thuộc (independent variable)
ann_model_2.add(keras.layers.Dense(2028, input_dim=104, activation='relu'))
# Lớp ẩn (hidden layer) thứ 2 cũng với 2048 nơron
ann_model_2.add(keras.layers.Dense(2048, activation='relu'))
# Lớp ẩn (hidden layer) thứ 3 cũng với 2048 nơron
ann_model_2.add(keras.layers.Dense(2048, activation='relu'))
# Lớp đầu ra (output layer), hàm kích hoạt softmax do đây là bài toán phân loại (classification)
ann_model_2.add(keras.layers.Dense(2, activation='softmax'))
1
2
3
4
# Biên dịch kiến trúc ANN model
ann_model_2.compile(loss='sparse_categorical_crossentropy',
                    optimizer='adam',
                    metrics=["accuracy"])
1
2
# Thêm tính năng dừng sớm để tránh việc quá vừa vặn overfit
early_stopping_cb = keras.callbacks.EarlyStopping(patience=5, restore_best_weights=True)
1
2
3
4
5
6
# Huấn luyện ANN model
history_model_ann_2 = ann_model_2.fit(X_train, 
                                      Y_train.values.astype(int), 
                                      epochs=30, 
                                      validation_data=(X_valid, Y_valid),
                                      callbacks=early_stopping_cb)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Epoch 1/30
1133/1133 [==============================] - 109s 96ms/step - loss: 0.3473 - accuracy: 0.8485 - val_loss: 0.3438 - val_accuracy: 0.8548
Epoch 2/30
1133/1133 [==============================] - 111s 98ms/step - loss: 0.3266 - accuracy: 0.8579 - val_loss: 0.3521 - val_accuracy: 0.8497
Epoch 3/30
1133/1133 [==============================] - 105s 93ms/step - loss: 0.3190 - accuracy: 0.8595 - val_loss: 0.3207 - val_accuracy: 0.8601
Epoch 4/30
1133/1133 [==============================] - 106s 94ms/step - loss: 0.3139 - accuracy: 0.8629 - val_loss: 0.3419 - val_accuracy: 0.8616
Epoch 5/30
1133/1133 [==============================] - 104s 91ms/step - loss: 0.3097 - accuracy: 0.8635 - val_loss: 0.3283 - val_accuracy: 0.8601
Epoch 6/30
1133/1133 [==============================] - 103s 91ms/step - loss: 0.3067 - accuracy: 0.8659 - val_loss: 0.3280 - val_accuracy: 0.8581
Epoch 7/30
1133/1133 [==============================] - 100s 88ms/step - loss: 0.3020 - accuracy: 0.8680 - val_loss: 0.3248 - val_accuracy: 0.8646
Epoch 8/30
1133/1133 [==============================] - 95s 84ms/step - loss: 0.2976 - accuracy: 0.8701 - val_loss: 0.3308 - val_accuracy: 0.8637
1
2
3
4
5
6
7
# Vẽ biểu đồ quá trình huấn luyện
import pandas as pd
import matplotlib.pyplot as plt

pd.DataFrame(history_model_ann_2.history).plot(figsize=(8,5))
plt.grid(True)
plt.show()

png

Qua biểu đồ trên, chúng ta có thể thấy model ANN thứ 2 đạt trạng thái tốt nhất ở epoch số 3. Trên tập xác nhận (validation set) sai số (loss) của model thứ 2 nhỏ hơn so với model thứ 1 (0.3207 và 0.3954), dù độ chính xác (accuracy) là tương đối bằng nhau. Chúng ta có thể kỳ vọng model thứ 2 này sẽ cho độ chính xác tốt hơn trên tập kiểm thử (test set). Giống như model thứ 1, chúng ta sẽ lưu lại model này để có thể tiếp tục sử dụng trong tương lai nhé.

1
2
# Lưu model
ann_model_2.save('ann_model_2.h5')

Kiểm tra các ANN model đã huấn luyện

1
2
3
# Import dữ liệu từ tập kiểm thử (test set)
df_test = pd.read_csv('/content/new_adult_test.csv')
df_test
0 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 36 37 38 39 ... 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000110 1.000000 0.000031 0.000000 0.0 0.000176 0.0
1 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000423 1.000000 0.000100 0.000000 0.0 0.000557 0.0
2 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000083 1.000000 0.000036 0.000000 0.0 0.000119 1.0
3 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000274 0.998852 0.000062 0.047898 0.0 0.000249 1.0
4 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000171 1.000000 0.000030 0.000000 0.0 0.000151 0.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
15055 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000135 1.000000 0.000053 0.000000 0.0 0.000163 0.0
15056 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000181 1.000000 0.000060 0.000000 0.0 0.000167 0.0
15057 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000101 1.000000 0.000035 0.000000 0.0 0.000133 0.0
15058 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000523 0.997892 0.000155 0.064888 0.0 0.000476 0.0
15059 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.000192 1.000000 0.000071 0.000000 0.0 0.000329 1.0

15060 rows × 105 columns

1
2
3
4
# Tách biến không phụ thuộc (indepedent variable)
x_test = df_test.iloc[:, 0:104]
# Tách biến phụ thuộc (depedent variable)
y_test = df_test.iloc[:,104]

ANN model thứ 1

1
2
# Load model đã lưu
ann_model_1 = keras.models.load_model('/content/ann_model_1.h5')
1
2
# Dự đoán trên tập kiểm thử (test set)
y_pred_model_1 = ann_model_1.predict(x_test)

Do kiến trúc của cả 2 model ANN của chúng ta có 2 nơron ở lớp đầu ra (output layer), các nơron này đều sử dụng hàm kích hoạt (activation function) là softmax do đó kết quả chúng ta thu được sẽ là xác xuất (probability) của cá thể (instance) sẽ thuộc nhóm (class) nào. Chúng ta sẽ lấy nhóm có xác xuất (probability) cao hơn làm kết quả cuối cùng.

1
2
# Kết quả dự đoán thô từ model
y_pred_model_1
1
2
3
4
5
6
7
array([[1.0000000e+00, 1.0863846e-11],
       [5.1192468e-01, 4.8807526e-01],
       [4.1566136e-01, 5.8433861e-01],
       ...,
       [7.4035093e-02, 9.2596495e-01],
       [9.0415090e-01, 9.5849141e-02],
       [1.7712155e-01, 8.2287842e-01]], dtype=float32)
1
2
3
4
import numpy as 
# Lấy nhóm nào có xác xuất (probability) cao hơn
y_pred_model_1 = np.argmax(y_pred_model_1, axis=1)
y_pred_model_1
1
array([0, 0, 1, ..., 1, 0, 1])
1
2
3
4
5
6
7
8
9
10
11
12
13
import seaborn as sns
import matplotlib.pyplot as plt

def draw_cf_matrix(label, pred):
  cf_matrix = confusion_matrix(label, pred)
  ax = plt.subplot()
  sns.heatmap(cf_matrix, annot=True, ax = ax, fmt='g', cmap='Greens')
  ax.set_xlabel('Predicted labels')
  ax.set_ylabel('True labels')
  ax.set_title('Confusion Matrix')
  ax.xaxis.set_ticklabels([0, 1])
  ax.yaxis.set_ticklabels([0, 1])
  cf_matrix
1
2
# Vẽ ma trận nhầm lẫn
draw_cf_matrix(y_test, y_pred_model_1)

png

1
2
3
# In báo cáo phân loại
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report
print(classification_report(y_test, y_pred_model_1))
1
2
3
4
5
6
7
8
              precision    recall  f1-score   support

         0.0       0.91      0.83      0.86     11360
         1.0       0.58      0.74      0.65      3700

    accuracy                           0.80     15060
   macro avg       0.74      0.78      0.76     15060
weighted avg       0.83      0.80      0.81     15060

ANN model thứ 2

1
2
# Load model đã lưu
ann_model_2 = keras.models.load_model('/content/ann_model_2.h5')
1
2
# Dự đoán trên tập kiểm thử (test set)
y_pred_model_2 = ann_model_2.predict(x_test)
1
2
3
import numpy as np
# Lấy nhóm nào có xác xuất (probability) cao hơn
y_pred_model_2 = np.argmax(y_pred_model_2, axis=1)
1
2
# Vẽ ma trận nhầm lẫn
draw_cf_matrix(y_test, y_pred_model_2)

png

1
2
3
# In báo cáo phân loại
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report
print(classification_report(y_test, y_pred_model_2))
1
2
3
4
5
6
7
8
              precision    recall  f1-score   support

         0.0       0.89      0.85      0.87     11360
         1.0       0.60      0.68      0.64      3700

    accuracy                           0.81     15060
   macro avg       0.75      0.77      0.75     15060
weighted avg       0.82      0.81      0.81     15060

Kết luận

Qua việc kiểm tra kết quả giữa 2 model, về căn bản model thứ 2 cho độ chính xác (accuracy) nhỉnh hơn một chút so với model thứ 1 (0.81 và 0.8). Model thứ 2 cho độ chuẩn xác (precision) ở nhóm (class) 1 tốt hơn so với model thứ 1, thể hiện ở số cá thể (instance) thuộc nhóm (class) 0 dự đoán nhầm sang nhóm (class) 1 là ít hơn so với model thứ 1 (1700 và 1972). Tuy nhiên số cá thể (instance) thuộc nhóm (class) 1 bị dự đoán sai sang nhóm (class) 0 ở model thứ 2 là nhiều hơn, dẫn đến độ chuẩn xác (precision) ở nhóm (class) 0 giảm xuống.

So sánh với các model đã huấn luyện

Chúng ta sẽ so sánh hiệu năng (performance) của ANN model thứ 2 với các kết quả phân loại của Logistic Regression model, Naive Bayes model, Decision tree model, SVM model đã được huấn luyện (training) ở các bài thực hành số 8, 10, 12, 14:

  Accuracy Recall Precision F1-Score
Logistic Regression 80% 76% 57% 0.65
Naive Bayes 77.15% 77% 52% 0.62
Decision tree 79.98% 69% 58% 0.63
SVM 80% 76% 56% 0.64
ANN 81% 68% 60% 0.65

Qua một loạt các huấn luyện (training) trên các model ML khác nhau, ANN model, model học giám sát (supervised learning) cuối cùng chúng ta tìm hiểu trong loạt bài AML cho kết quả tốt nhất về phương diện độ chính xác (accuracy), độ chuẩn xác (precision) và F1-Score. Điều này cho thấy sức mạnh của ANN model trong việc giải quyết các bài toán phân loại (classification) và đây cũng chính là tiền đề để học sâu (deep learning) ra đời. Sau bài học này các bạn hãy ghi nhớ quy trình xây dựng và huấn luyện (training) một model ANN nhé:

  1. Xây dựng kiến trúc model ANN
  2. Biên dịch model ANN đã xây dựng
  3. Huấn luyện model ANN với tập huấn luyện (training set) và xác nhận trên tập xác nhận (validation set)
  4. Kiểm tra model trên tập huấn luyện (test set)