Bài thứ 18 trong chuỗi các bài viết về chủ đề Data Preparation cho các mô hình ML và là bài thứ 5 về về Data Transforms. Trong bài này, chúng ta sẽ tìm hiểu cách thức để sinh ra thêm features mới cho bộ dữ liệu huấn luyện ML model. Chúng ta cũng sẽ thực hành trên bộ dữ liệu thực tế.
Thông thường, các features của một mô hình dự đoán tương tác theo những cách mà ta không biết trước và thường là phi tuyến tính. Những tương tác này có thể được xác định và mô hình hóa bằng một thuật toán ML. Một cách tiếp cận khác là thiết kế các features mới thể hiện những tương tác này và xem liệu chúng có cải thiện hiệu suất mô hình hay không? Features mới có thể được tạo ra bằng cách thực hiện lũy thừa các giá trị đang có của features. Trong một số trường hợp, việc làm này có thể giúp thể hiện tốt hơn các mối quan hệ quan trọng giữa các features và target.
Polynomal features là các features mới được tạo ra bằng cách lấy lũy thừa từ các features đã tồn tại. VD, Polynomial feature sinh ra từ feature $X$ là $X^2$, …
Bậc (degree) của Polynomial feature quy định số lượng features mới được tạo ra. VD, bậc 3 thì sẽ có 3 features mới được tạo ra từ một feature ban đầu.
Interaction features là các features mới được sinh ra bằng cách kết hợp 2 features đã tồn tại qua một phép toán. VD, nhân feature $X$ với feature $Y$ ta được Interaction feature $Z$.
Polynomial/Interaction Feature Transform được implemented trong thư viện scikit-learn thông qua class PolynomialFeatures(). Các features có thể được tạo ra từ class này là:
VD, với 2 features ban đầu là 2 và 3, bậc là 2 thì các features có thể được tạo ra là:
Các tham số quan trọng của class PolynomialFeatures() là:
VD sử dụng class PolynomialFeatures() trong scikit-learn:
# demonstrate the types of features created
from numpy import asarray
from sklearn.preprocessing import PolynomialFeatures
# define the dataset
data = asarray([[2,3],[2,3],[2,3]])
print(data)
# perform a polynomial features transform of the dataset
trans = PolynomialFeatures(degree=2)
data = trans.fit_transform(data)
print(data)
Kết quả thực hiện:
[[2 3]
[2 3]
[2 3]]
[[1. 2. 3. 4. 6. 9.]
[1. 2. 3. 4. 6. 9.]
[1. 2. 3. 4. 6. 9.]]
# visualize a polynomial features transform of the sonar dataset
from pandas import read_csv
from pandas import DataFrame
from sklearn.preprocessing import PolynomialFeatures
# load dataset
dataset = read_csv('sonar.csv', header=None)
# retrieve just the numeric input values
data = dataset.values[:, :-1]
# perform a polynomial features transform of the dataset
trans = PolynomialFeatures(degree=3)
data = trans.fit_transform(data)
# convert the array back to a dataframe
dataset = DataFrame(data)
# summarize
print(dataset.shape)
Kết quả thực hiện:
(208, 39711)
Ta thấy số lượng features tăng từ 60 lên 39711.
# evaluate knn on the sonar dataset with polynomial features transform
from numpy import mean
from numpy import std
from pandas import read_csv
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline
# load dataset
dataset = read_csv('sonar.csv', header=None)
data = dataset.values
# separate into input and output columns
X, y = data[:, :-1], data[:, -1]
# ensure inputs are floats and output is an integer label
X = X.astype('float32')
y = LabelEncoder().fit_transform(y.astype('str'))
# define the pipeline
trans = PolynomialFeatures(degree=3)
model = KNeighborsClassifier()
pipeline = Pipeline(steps=[('t', trans), ('m', model)])
# evaluate the pipeline
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
n_scores = cross_val_score(pipeline, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
# report pipeline performance
print('Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores)))
Kết quả thực hiện:
Accuracy: 0.800 (0.077)
Độ chính xác tăng lên 1 chút so với khi không thực hiện bất kỳ phép biến đổi nào, 79.7%.
Ta chỉ chọn giá trị của degree từ 0 đến 4, vì càng nhiều features sinh ra, khả năng xảy ra Overfitting càng cao.
# explore the effect of degree on accuracy for the polynomial features transform
from numpy import mean
from numpy import std
from pandas import read_csv
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import LabelEncoder
from sklearn.pipeline import Pipeline
from matplotlib import pyplot
# get the dataset
def get_dataset(filename):
# load dataset
dataset = read_csv(filename, header=None)
data = dataset.values
# separate into input and output columns
X, y = data[:, :-1], data[:, -1]
# ensure inputs are floats and output is an integer label
X = X.astype('float32')
y = LabelEncoder().fit_transform(y.astype('str'))
return X, y
# get a list of models to evaluate
def get_models():
models = dict()
for d in range(1,5):
# define the pipeline
trans = PolynomialFeatures(degree=d)
model = KNeighborsClassifier()
models[str(d)] = Pipeline(steps=[('t', trans), ('m', model)])
return models
# evaluate a given model using cross-validation
def evaluate_model(model, X, y):
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
return scores
# define dataset
X, y = get_dataset('sonar.csv')
# get the models to evaluate
models = get_models()
# evaluate the models and store results
results, names = list(), list()
for name, model in models.items():
scores = evaluate_model(model, X, y)
results.append(scores)
names.append(name)
print('>%s %.3f (%.3f)' % (name, mean(scores), std(scores)))
# plot model performance for comparison
pyplot.boxplot(results, labels=names, showmeans=True)
pyplot.show()
Kết quả thực hiện:
>1 0.797 (0.073)
>2 0.793 (0.085)
>3 0.800 (0.077)
>4 0.795 (0.079)
Ta thấy chỉ có degree=3 thì độ chính xác mới cao hơn so với khi không thực hiện bất kỳ phép biến đổi nào, 79.7%.
Bài thứ 5 về chủ đề Data Transforms, mình đã giới thiệu về kỹ thuật sinh thêm features mới là Polynominal/Interaction. Toàn bộ code của bài này, các bạn có thể tham khảo tại đây.
Bài tiếp theo chúng ta sẽ tìm hiểu cách thức thực hiện Data Transforms đối với dữ liệu cả 2 loại features là categorical và numerical. Mời các bạn đón đọc.
[1] Jason Brownlee, “Data Preparation for Machine Learning”, Book: https://machinelearningmastery.com/data-preparation-for-machine-learning/.