AML

[Thực Hành] Bài 4: Tiền xử lý dữ liệu - Pre-process data

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

Posted by KyoHB on December 11, 2020

Trong bài thực hành đầu tiên thuộc series AML, chúng ta sẽ làm quen với các bước cơ bản như import tập dữ liệu (dataset), tiền xử lý (pre-process) dữ liệu.

* Các bài thực hành đều sử dụng Python 3.

Import tập dữ liệu

Tập dữ liệu (dataset) được sử dụng trong bài thực hành này là tập dữ liệu (dataset) ở link sau:

Download Tập dữ liệu

File dữ liệu là file adult.data

1
import pandas as pd

Import tập dữ liệu (dataset) sử dụng thư viện pandas, mặc định các giá trị ‘?’ là các giá trị đang bị thiếu (Missing values)

1
2
3
cols = ['age', 'workclass', 'fnlwgt', 'education', 'education-num', 'marital-status', 'occupation', 'relationship', 'race', 'sex', 'capital-gain', 'capital-loss', 'hours-per-week', 'native-country', 'income']
ds = pd.read_csv('adult.data', names = cols, index_col=False, na_values=' ?')
ds
age workclass fnlwgt education education-num marital-status occupation relationship race sex capital-gain capital-loss hours-per-week native-country income
0 39 State-gov 77516 Bachelors 13 Never-married Adm-clerical Not-in-family White Male 2174 0 40 United-States <=50K
1 50 Self-emp-not-inc 83311 Bachelors 13 Married-civ-spouse Exec-managerial Husband White Male 0 0 13 United-States <=50K
2 38 Private 215646 HS-grad 9 Divorced Handlers-cleaners Not-in-family White Male 0 0 40 United-States <=50K
3 53 Private 234721 11th 7 Married-civ-spouse Handlers-cleaners Husband Black Male 0 0 40 United-States <=50K
4 28 Private 338409 Bachelors 13 Married-civ-spouse Prof-specialty Wife Black Female 0 0 40 Cuba <=50K
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
32556 27 Private 257302 Assoc-acdm 12 Married-civ-spouse Tech-support Wife White Female 0 0 38 United-States <=50K
32557 40 Private 154374 HS-grad 9 Married-civ-spouse Machine-op-inspct Husband White Male 0 0 40 United-States >50K
32558 58 Private 151910 HS-grad 9 Widowed Adm-clerical Unmarried White Female 0 0 40 United-States <=50K
32559 22 Private 201490 HS-grad 9 Never-married Adm-clerical Own-child White Male 0 0 20 United-States <=50K
32560 52 Self-emp-inc 287927 HS-grad 9 Married-civ-spouse Exec-managerial Wife White Female 15024 0 40 United-States >50K

32561 rows × 15 columns

Tập dữ liệu (dataset) này có 32,561 cá thể (instance) bao gồm 14 biến không phụ thuộc (independent variable) và biến phụ thuộc (dependent variable) là income (thu nhập) với 2 nhóm (class) đó là: <=50K and >50K

Giá trị trống (missing values)

1
import missingno as msno

Chúng ta sẽ trích xuất 14 biến không phụ thuộc (independent variable) để kiểm tra giá trị trống (Missing Values)

1
2
x = ds.iloc[:,0:14]
x
age workclass fnlwgt education education-num marital-status occupation relationship race sex capital-gain capital-loss hours-per-week native-country
0 39 State-gov 77516 Bachelors 13 Never-married Adm-clerical Not-in-family White Male 2174 0 40 United-States
1 50 Self-emp-not-inc 83311 Bachelors 13 Married-civ-spouse Exec-managerial Husband White Male 0 0 13 United-States
2 38 Private 215646 HS-grad 9 Divorced Handlers-cleaners Not-in-family White Male 0 0 40 United-States
3 53 Private 234721 11th 7 Married-civ-spouse Handlers-cleaners Husband Black Male 0 0 40 United-States
4 28 Private 338409 Bachelors 13 Married-civ-spouse Prof-specialty Wife Black Female 0 0 40 Cuba
... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
32556 27 Private 257302 Assoc-acdm 12 Married-civ-spouse Tech-support Wife White Female 0 0 38 United-States
32557 40 Private 154374 HS-grad 9 Married-civ-spouse Machine-op-inspct Husband White Male 0 0 40 United-States
32558 58 Private 151910 HS-grad 9 Widowed Adm-clerical Unmarried White Female 0 0 40 United-States
32559 22 Private 201490 HS-grad 9 Never-married Adm-clerical Own-child White Male 0 0 20 United-States
32560 52 Self-emp-inc 287927 HS-grad 9 Married-civ-spouse Exec-managerial Wife White Female 15024 0 40 United-States

32561 rows × 14 columns

Sử dụng thư viện missingno để thống kê số lượng giá trị của các biến không phụ thuộc (independent variable)

1
msno.bar(x)

1
x.isna().sum()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
age                  0
workclass         1836
fnlwgt               0
education            0
education-num        0
marital-status       0
occupation        1843
relationship         0
race                 0
sex                  0
capital-gain         0
capital-loss         0
hours-per-week       0
native-country     583
dtype: int64

Có thể thấy các biến không phụ thuộc (independent variable): workclass, occupation, native-country đang có các giá trị trống (missing value). Xét thấy số lượng các cá thể (instance) này là rất ít so với tổng số cá thể (instance) của tập dữ liệu (dataset) nên chúng ta có thể loại bỏ hẳn chúng. Trong trường hợp xui nhất - các cá thể (instance) này khác nhau chúng ta sẽ loại bỏ 4262 cá thể (instance), chúng ta vẫn còn 28299 cá thể (instance) một con số vẫn đủ lớn.

1
2
3
ds = ds.dropna()

ds
age workclass fnlwgt education education-num marital-status occupation relationship race sex capital-gain capital-loss hours-per-week native-country income
0 39 State-gov 77516 Bachelors 13 Never-married Adm-clerical Not-in-family White Male 2174 0 40 United-States <=50K
1 50 Self-emp-not-inc 83311 Bachelors 13 Married-civ-spouse Exec-managerial Husband White Male 0 0 13 United-States <=50K
2 38 Private 215646 HS-grad 9 Divorced Handlers-cleaners Not-in-family White Male 0 0 40 United-States <=50K
3 53 Private 234721 11th 7 Married-civ-spouse Handlers-cleaners Husband Black Male 0 0 40 United-States <=50K
4 28 Private 338409 Bachelors 13 Married-civ-spouse Prof-specialty Wife Black Female 0 0 40 Cuba <=50K
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
32556 27 Private 257302 Assoc-acdm 12 Married-civ-spouse Tech-support Wife White Female 0 0 38 United-States <=50K
32557 40 Private 154374 HS-grad 9 Married-civ-spouse Machine-op-inspct Husband White Male 0 0 40 United-States >50K
32558 58 Private 151910 HS-grad 9 Widowed Adm-clerical Unmarried White Female 0 0 40 United-States <=50K
32559 22 Private 201490 HS-grad 9 Never-married Adm-clerical Own-child White Male 0 0 20 United-States <=50K
32560 52 Self-emp-inc 287927 HS-grad 9 Married-civ-spouse Exec-managerial Wife White Female 15024 0 40 United-States >50K

30162 rows × 15 columns

Như vậy sau quá trính loại bỏ các cá thể (instance) có giá trị trống (missing value) chúng ta vẫn còn 30162 cá thể (instance). Điều này chứng tỏ có các cá thể (instance) cùng lúc có nhiều giá trị trống (missing value). Chúng ta hãy kiểm tra lại lần nữa các giá trị trống còn không khi đã loại bỏ nhé

1
2
x = ds.iloc[:,0:14]
x.isna().sum()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
age               0
workclass         0
fnlwgt            0
education         0
education-num     0
marital-status    0
occupation        0
relationship      0
race              0
sex               0
capital-gain      0
capital-loss      0
hours-per-week    0
native-country    0
dtype: int64

Phân phối của biến phụ thuộc (dependent variable)

Đầu tiên chúng ta cần trích xuất biến phụ thuộc (dependent variable) và gán cho các nhãn ‘<=50K’ là 0 và ‘>50K’ là 1.

1
y = ds.income.apply(lambda x: 0 if str(x).strip() == '<=50K' else 1 )

Xem phân phối của hai nhóm bằng câu lệnh sau

1
y.value_counts()
1
2
3
0    22654
1     7508
Name: income, dtype: int64

Vẽ biểu đồ cột (bar plot) để nhìn trực quan hơn

1
y.value_counts().plot(kind='bar')
1
<matplotlib.axes._subplots.AxesSubplot at 0x7f4a94176748>

Có thể thấy tập dữ liệu (dataset) đang gặp vấn đề mất cân bằng (imbalance), chúng ta sẽ sử dụng Synthetic Minority Oversampling Technique (SMOTE) để oversampling các cá thể ở nhóm thiểu số (minority class) - nhóm 1.

1
from imblearn.over_sampling import SMOTENC 

Chúng ta sẽ sử dụng thư viện imblearn, để sử dụng SMOTE ở thư viện này chúng ta cần liệt kê các biến phân loại (categorical variable), đây là các biến có giá trị là loại (category) của cá thể (instance). Trong tập dữ liệu (dataset) của chúng ta đó là biến: workclass, education, marital-status, occupation, relationship, race, sex, native-country.

SMOTE hoạt động theo 3 bước sau (tương ứng với 3 hình a,b,c):

  1. Lựa chọn một cá thể (instance) bất kỳ thuộc nhóm thiểu số (minority class) ở đây chính là các điểm màu xanh trong hình

  2. Điểm màu đen chính là cá thể (instance) thuộc nhóm thiểu số (minority class) được lựa chọn, từ đó chọn ra k hàng xóm thuộc nhóm thiểu số (minority class) gần nhất (k-nearest neighbor), k ở trong hình là 3 tương ứng với 3 điểm màu vàng.

  3. Một trong k hàng xóm sẽ được lựa chọn và đó là điểm màu nâu trong hình c, dữ liệu giả - điểm màu đỏ được tạo ra trên đường kết nối từ điểm màu đen đến điểm màu nâu.

Việc tìm kiếm các các điểm hàng xóm, hay tạo nên dữ liệu giả, đều dựa trên khoảng cách Euclidean, việc tính khoảng cách Euclidean đối với các biến có kiểu dữ liệu là số (numeric variable) là rất trực quan, tuy nhiên đối với các biến có kiểu dữ liệu phân loại (categorical variable) sẽ có phải có phương pháp tính khác nên đó là lý do chúng ta cần phải liệt kê các biến (variable) đó.

image.png

1
2
oversample = SMOTENC(random_state=123, categorical_features=[1,3,5,6,7,8,9,13])
x_over, y_over = oversample.fit_sample(x,y)

Kiểm tra lại phân phối của biến phụ thuộc (dependent variable) sau khi áp dụng SMOTE

1
2
y_over = pd.DataFrame(y_over)
y_over.value_counts().plot(kind='bar')

png

Chuyển đổi các biến phân loại (categorical variable)

Cùng nhìn lại các biến không phụ thuộc (independent variable), sau khi áp dụng SMOTE

1
2
x_over =  pd.DataFrame(x_over)
x_over
0 1 2 3 4 5 6 7 8 9 10 11 12 13
0 39 State-gov 77516 Bachelors 13 Never-married Adm-clerical Not-in-family White Male 2174 0 40 United-States
1 50 Self-emp-not-inc 83311 Bachelors 13 Married-civ-spouse Exec-managerial Husband White Male 0 0 13 United-States
2 38 Private 215646 HS-grad 9 Divorced Handlers-cleaners Not-in-family White Male 0 0 40 United-States
3 53 Private 234721 11th 7 Married-civ-spouse Handlers-cleaners Husband Black Male 0 0 40 United-States
4 28 Private 338409 Bachelors 13 Married-civ-spouse Prof-specialty Wife Black Female 0 0 40 Cuba
... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
45303 47.8688 Private 175957 Prof-school 14.5656 Married-civ-spouse Exec-managerial Husband White Male 0 0 45 United-States
45304 37.8997 Private 157769 Some-college 10 Married-civ-spouse Exec-managerial Husband White Male 0 0 35.6342 United-States
45305 45.7023 Private 57544 Assoc-voc 10.2257 Married-civ-spouse Sales Husband White Male 0 0 39.7179 United-States
45306 38.394 Private 200983 Bachelors 13 Married-civ-spouse Exec-managerial Husband White Male 0 0 39.8503 United-States
45307 40.5609 Private 175722 Some-college 10 Married-civ-spouse Exec-managerial Husband White Male 0 0 46.6827 United-States

45308 rows × 14 columns

1
2
3
4
5
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import LabelEncoder
from sklearn.compose import ColumnTransformer
import numpy as np
from sklearn.preprocessing import Normalizer

Như vậy tập dữ liệu (dataset) của chúng ta đã lên thành 45,308 cá thể (instance). Đầu tiên chúng ta sẽ sử dụng Label Encoder để chuyển đổi các nhóm của các biến dạng phân loại (categorical variable) từ dạng chữ sang thành dạng số. Ví dụ như biến workclass chúng ta có nhóm State-gov, Self-emp-not-inc, Private,… Label Encoder sẽ quy đổi tương đương các nhóm này sang dạng số 1 ,2, 3, 4,…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
le_1 = LabelEncoder()
x_over[1] = le_1.fit_transform(x_over[1])
le_3 = LabelEncoder()
x_over[3] = le_3.fit_transform(x_over[3])
le_5 = LabelEncoder()
x_over[5] = le_5.fit_transform(x_over[5])
le_6 = LabelEncoder()
x_over[6] = le_6.fit_transform(x_over[6])
le_7 = LabelEncoder()
x_over[7] = le_7.fit_transform(x_over[7])
le_8 = LabelEncoder()
x_over[8] = le_8.fit_transform(x_over[8])
le_9 = LabelEncoder()
x_over[9] = le_9.fit_transform(x_over[9])
le_13 = LabelEncoder()
x_over[13] = le_13.fit_transform(x_over[13])
x_over
0 1 2 3 4 5 6 7 8 9 10 11 12 13
0 39 5 77516 9 13 4 0 1 4 1 2174 0 40 38
1 50 4 83311 9 13 2 3 0 4 1 0 0 13 38
2 38 2 215646 11 9 0 5 1 4 1 0 0 40 38
3 53 2 234721 1 7 2 5 0 2 1 0 0 40 38
4 28 2 338409 9 13 2 9 5 2 0 0 0 40 4
... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
45303 47.8688 2 175957 14 14.5656 2 3 0 4 1 0 0 45 38
45304 37.8997 2 157769 15 10 2 3 0 4 1 0 0 35.6342 38
45305 45.7023 2 57544 8 10.2257 2 11 0 4 1 0 0 39.7179 38
45306 38.394 2 200983 9 13 2 3 0 4 1 0 0 39.8503 38
45307 40.5609 2 175722 15 10 2 3 0 4 1 0 0 46.6827 38

45308 rows × 14 columns

Bước tiếp chúng ta sẽ thực hiện One Hot Encoder với các biến kiểu phân loại (categorical variable) và Normalizer với các biến kiểu số (numeric variable).

Với one hot encoder, chúng ta sẽ tách các nhóm của biến kiểu phân loại (categorical variable) ra thành các cột riêng rẽ, mỗi cột tương ứng với một loại (category), khi đó giá trị của các cột này chỉ là 0 và 1, giá trị 1 sẽ biểu thị cá thế (instance) thuộc loại đó. Đây là một trick giúp cho tập dữ liệu (dataset) của chúng ta có thể dùng trong các ML model yêu cầu dữ liệu phải là kiểu số (numeric).

image.png

Normalizer sẽ tiêu chuẩn hóa các biến dạng số (numeric variable) thay vì để tỉ lệ (scale) của các biến dạng số lệch nhau như nguyên bản ví dụ như age chỉ khoảng hàng chục nhưng fnlwgt lại lên đáng hàng nghìn. Sự khác nhau về tỉ lệ này vô hình chung làm khó ML model trong quá trình ‘học’, chúng ta sẽ chuyển đổi chúng về cùng một tiêu chuẩn đó là các giá trị sẽ trải từ 0 cho đến 1, giúp cho việc ‘học’ của ML model thuận lợi hơn.

1
2
columnTransfer_x = ColumnTransformer([('encoder', OneHotEncoder(sparse=False),[1,3,5,6,7,8,9,13]), ('norm', Normalizer(), [0,2,4,10,11,12])], remainder='passthrough')
x_onehot = np.array(columnTransfer_x.fit_transform(x_over))

Giá trị của các biến không phụ thuộc (independent variable) sau quá trình chuyển đổi sẽ như sau:

1
x_onehot
1
2
3
4
5
6
7
8
9
10
11
12
13
array([[0.00000000e+00, 0.00000000e+00, 0.00000000e+00, ...,
        2.80347917e-02, 0.00000000e+00, 5.15819534e-04],
       [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, ...,
        0.00000000e+00, 0.00000000e+00, 1.56041787e-04],
       [0.00000000e+00, 0.00000000e+00, 1.00000000e+00, ...,
        0.00000000e+00, 0.00000000e+00, 1.85489175e-04],
       ...,
       [0.00000000e+00, 0.00000000e+00, 1.00000000e+00, ...,
        0.00000000e+00, 0.00000000e+00, 6.90217486e-04],
       [0.00000000e+00, 0.00000000e+00, 1.00000000e+00, ...,
        0.00000000e+00, 0.00000000e+00, 1.98276798e-04],
       [0.00000000e+00, 0.00000000e+00, 1.00000000e+00, ...,
        0.00000000e+00, 0.00000000e+00, 2.65662543e-04]])

Lưu tập dữ liệu đã xử lý

Như vậy đến đây sau các quá trình tiền xử lý (pre-process) chúng ta đã có một tập dữ liệu (dataset) hoàn chỉnh, sạch sẽ để huấn luyện các ML model. Giờ chúng ta sẽ lưu tập dữ liệu (dataset) đã xử lý lại nhé !

1
2
3
4
5
6
7
# Ghép x và y vào thành một tập dữ liệu (dataset) hoàn chỉnh

new_dataset = np.concatenate((x_onehot, y_over), axis=1)

df_new = pd.DataFrame(new_dataset)

df_new
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

1
df_new.to_csv('new_adult_data.csv', index=False)

Sau bước này chúng ta sẽ có một file dữ liệu csv để có thể sử dụng trong việc xây dựng ML model.

Tiền xử lý tập dữ liệu kiểm thử

Nếu các bạn để ý trong kho dữ liệu của chúng ta còn một tập dữ liệu (dataset) đó là adult.test nhằm phục vụ phục mục đích kiểm thử dữ liệu, chúng ta sẽ import và xử lý nốt file này nhé !

1
2
3
df_test = pd.read_csv('adult.test', names=cols, index_col=None, skiprows= 1, na_values=' ?')

df_test
age workclass fnlwgt education education-num marital-status occupation relationship race sex capital-gain capital-loss hours-per-week native-country income
0 25 Private 226802 11th 7 Never-married Machine-op-inspct Own-child Black Male 0 0 40 United-States <=50K.
1 38 Private 89814 HS-grad 9 Married-civ-spouse Farming-fishing Husband White Male 0 0 50 United-States <=50K.
2 28 Local-gov 336951 Assoc-acdm 12 Married-civ-spouse Protective-serv Husband White Male 0 0 40 United-States >50K.
3 44 Private 160323 Some-college 10 Married-civ-spouse Machine-op-inspct Husband Black Male 7688 0 40 United-States >50K.
4 18 NaN 103497 Some-college 10 Never-married NaN Own-child White Female 0 0 30 United-States <=50K.
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
16276 39 Private 215419 Bachelors 13 Divorced Prof-specialty Not-in-family White Female 0 0 36 United-States <=50K.
16277 64 NaN 321403 HS-grad 9 Widowed NaN Other-relative Black Male 0 0 40 United-States <=50K.
16278 38 Private 374983 Bachelors 13 Married-civ-spouse Prof-specialty Husband White Male 0 0 50 United-States <=50K.
16279 44 Private 83891 Bachelors 13 Divorced Adm-clerical Own-child Asian-Pac-Islander Male 5455 0 40 United-States <=50K.
16280 35 Self-emp-inc 182148 Bachelors 13 Married-civ-spouse Exec-managerial Husband White Male 0 0 60 United-States >50K.

16281 rows × 15 columns

Như vậy tập dữ liệu (dataset) kiểm thử của chúng ta có 16,821 cá thể (instance), bước tiếp theo chúng ta sẽ kiểm tra các giá trị trống (missing value) ở tập dữ liệu (dataset) này nhé.

1
2
3
x_test = df_test.iloc[:,0:14]

x_test.isna().sum()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
age                 0
workclass         963
fnlwgt              0
education           0
education-num       0
marital-status      0
occupation        966
relationship        0
race                0
sex                 0
capital-gain        0
capital-loss        0
hours-per-week      0
native-country    274
dtype: int64

Như vậy là ở tập dữ liệu (dataset) kiểm thử này cũng có dữ liệu trống (missing value) chúng ta hãy loại bỏ nó nhé.

1
2
3
4
5
df_test = df_test.dropna()

x_test = df_test.iloc[:,0:14]

x_test.isna().sum()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
age               0
workclass         0
fnlwgt            0
education         0
education-num     0
marital-status    0
occupation        0
relationship      0
race              0
sex               0
capital-gain      0
capital-loss      0
hours-per-week    0
native-country    0
dtype: int64

Tiếp theo chúng ta sẽ chuyển đổi biến phụ thuộc (dependent variable) sang thành label 0 và 1 như ở trên.

1
2
3
y_test = df_test.income.apply(lambda x: 0 if str(x).strip() == '<=50K.' else 1 )

y_test
1
2
3
4
5
6
7
8
9
10
11
12
0        0
1        0
2        1
3        1
5        0
        ..
16275    0
16276    0
16278    0
16279    0
16280    1
Name: income, Length: 15060, dtype: int64

Vì mục địch của tập dữ liệu này là để kiểm thử ML model, nên chúng ta sẽ không thực hiện SMOTE mà giữ nguyên giá trị của chúng, chỉ thực hiện Label Encoder và One Hot Encoding các biến không phụ thuộc (independent variable).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
x_test['workclass'] = le_1.transform(x_test['workclass'])

x_test['education'] = le_3.transform(x_test['education'])

x_test['marital-status'] = le_5.transform(x_test['marital-status'])

x_test['occupation'] = le_6.transform(x_test['occupation'])

x_test['relationship'] = le_7.transform(x_test['relationship'])

x_test['race'] = le_8.transform(x_test['race'])

x_test['sex'] = le_9.transform(x_test['sex'])

x_test['native-country'] = le_13.transform(x_test['native-country'])

x_test
age workclass fnlwgt education education-num marital-status occupation relationship race sex capital-gain capital-loss hours-per-week native-country
0 25 2 226802 1 7 4 6 3 2 1 0 0 40 38
1 38 2 89814 11 9 2 4 0 4 1 0 0 50 38
2 28 1 336951 7 12 2 10 0 4 1 0 0 40 38
3 44 2 160323 15 10 2 6 0 2 1 7688 0 40 38
5 34 2 198693 0 6 4 7 1 4 1 0 0 30 38
... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
16275 33 2 245211 9 13 4 9 3 4 1 0 0 40 38
16276 39 2 215419 9 13 0 9 1 4 0 0 0 36 38
16278 38 2 374983 9 13 2 9 0 4 1 0 0 50 38
16279 44 2 83891 9 13 0 0 3 1 1 5455 0 40 38
16280 35 3 182148 9 13 2 3 0 4 1 0 0 60 38

15060 rows × 14 columns

1
2
3
x_test_onehot = np.array(columnTransfer_x.transform(x_test))

x_test_onehot
1
2
3
4
5
6
7
8
9
10
11
12
13
array([[0.00000000e+00, 0.00000000e+00, 1.00000000e+00, ...,
        0.00000000e+00, 0.00000000e+00, 1.76365284e-04],
       [0.00000000e+00, 0.00000000e+00, 1.00000000e+00, ...,
        0.00000000e+00, 0.00000000e+00, 5.56705943e-04],
       [0.00000000e+00, 1.00000000e+00, 0.00000000e+00, ...,
        0.00000000e+00, 0.00000000e+00, 1.18711621e-04],
       ...,
       [0.00000000e+00, 0.00000000e+00, 1.00000000e+00, ...,
        0.00000000e+00, 0.00000000e+00, 1.33339376e-04],
       [0.00000000e+00, 0.00000000e+00, 1.00000000e+00, ...,
        6.48878010e-02, 0.00000000e+00, 4.75804224e-04],
       [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, ...,
        0.00000000e+00, 0.00000000e+00, 3.29402439e-04]])

Bước cuối chúng ta sẽ lưu lại tập dữ liệu (dataset) kiểm thử này để sử dụng trong những bài tới !

1
2
3
4
5
new_test_dataset = np.concatenate((x_test_onehot, np.expand_dims(y_test, axis=1)), axis=1)

df_test_new = pd.DataFrame(new_test_dataset)

df_test_new
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
df_test_new.to_csv('new_adult_test.csv', index=False)