Machine Learning Resources

Machine learning overview

Machine learning mastery

Machine learning is fun

Inky Machine Learning

Machine Learning: An In-Depth Guide

Stories and experiences

Machine Learning Algorithms

Beginner Books

Practical Books

Kaggle knowledge competitions

Video Series

MOOC

Resources

Games

Becoming an Open Source Contributor

Podcasts

Communities

Conferences

  • Neural Information Processing Systems (NIPS)
  • International Conference on Learning Representations (ICLR)
  • Association for the Advancement of Artificial Intelligence (AAAI)
  • IEEE Conference on Computational Intelligence and Games (CIG)
  • IEEE International Conference on Machine Learning and Applications (ICMLA)
  • International Conference on Machine Learning (ICML)
  • International Joint Conferences on Artificial Intelligence (IJCAI)
  • Association for Computational Linguistics (ACL)

Interview Questions

Supervised Learning (Thực hành – Phần 2)

Trong phần 1, tôi đã giới thiệu tổng quan về phương pháp học có giám sát và thực hành với mô hình k-Nearest Neighbors, trong phần này chúng ta sẽ đi tiếp với các mô hình Linear, Naive BayesDecision Tree.

1. Mô hình Linear

Là mô hình phổ biến nhất, cổ xưa nhất trong học thuật cũng như thực hành trong vài thập kỷ trở lại đây. Biểu diễn mô hình bởi công thức như sau:

ŷ = w[0] * x[0] + w[1] * x[1] + ... + w[p] * x[p] + b

Trong đó:

ŷ: Giá trị dự đoán (predictor)

x[]: Các biến số đầu vào, quy định các tính năng (features). Với single feature thì ta có mô hình: ŷ = w[0] * x[0] + b

w[]: Các hệ số, khi vẽ thành biểu đồ thì ta thấy hệ số này quy định độ dốc của đường tuyến tính

b: Giá trị bù thêm (intercept offset)

Mục tiêu của mô hình Linear là học để tìm ra giá trị các hệ số w[] và b. Ví dụ về single feature linear dưới đây:

Input:

mglearn.plots.plot_linear_regression_wave()

Output:

w[0]: 0.393906 b: -0.031804

Biểu đồ như sau:

So sánh với mô hình kNN thì có vẻ single feature linear khá đơn giản, thuần túy, không khớp với training data, còn bỏ sót khá nhiều data point. Tuy nhiên khi số features tăng lên thì sức mạnh, độ chính xác của mô hình tuyến tính Linear sẽ được thể hiện rõ nét. Cũng tương tự như mô hình kNN, chúng ta có Linear Regression và Linear Classification.

a. Linear Regression

Có khá nhiều mô hình hồi quy tuyến tính, các mô hình khác nhau ở chỗ các trọng số w và b được dạy học như thế nào và làm thế nào để kiểm soát độ phức tạp của mô hình. Chúng ta sẽ chỉ đi các mô hình phổ biến.

Linear Regression OLS:

Mô hình cổ điển, tìm các trọng số w và b bằng cách tối thiểu hóa hàm mất mát (loss function) – mean squared error của hiệu số giữa giá trị predictor ŷ và giá trị thực tế trong training set.

Dưới đây là đoạn code demo viết trên python:

Input:

import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
X, y = mglearn.datasets.make_wave(n_samples=60)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
lr = LinearRegression().fit(X_train, y_train)
mglearn.plots.plot_linear_regression_wave()
print("X.shape {}".format(X.shape))
print("lr.coef_: {}".format(lr.coef_))
print("lr.intercept_: {}".format(lr.intercept_))
print("Training set score: {:.2f}".format(lr.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lr.score(X_test, y_test)))print("Test set score: {:.2f}".format(lr.score(X_test, y_test)))print("Test set score: {:.2f}".format(lr.score(X_test, y_test)))

Output:

w[0]: 0.393906

b: -0.031804

X.shape (60, 1)

lr.coef_: [0.39390555]

lr.intercept_: -0.031804343026759746

Training set score: 0.67

Test set score: 0.66

Chú ý: coef_ chính là giá trị w, intercept chính là giá trị b.

Kết quả training và test đều xấp xỉ 0.67 là rất thấp, chứng tỏ mô hình single feature này bị underfitting. Tiếp theo chúng ta thử với lượng dữ liệu lớn hơn.

Input:

import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
X, y = mglearn.datasets.load_extended_boston()
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
lr = LinearRegression().fit(X_train, y_train)
print("X.shape {}".format(X.shape))
print("lr.coef_: {}".format(lr.coef_))
print("lr.intercept_: {}".format(lr.intercept_))
print("Training set score: {:.2f}".format(lr.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lr.score(X_test, y_test)))

Output:

w[0]: 0.393906

b: -0.031804

X.shape (506, 104)

lr.coef_: [-5.11126504e+02 4.02559787e+00 -9.45778613e+01 1.34720251e+01 3.48176257e+01 6.03611391e+01 3.49707471e+01 2.94114542e+00 3.14525465e+00 8.20792132e+01 1.24254396e+01 3.86676075e+01 -9.38409521e-01 1.32936334e+01 7.60317098e+02 1.42274855e+03 2.29220565e+02 -7.79405429e+01 8.79429261e+01 1.39813973e+01 1.02565346e+02 7.52178879e+02 -1.82071934e+03 5.34143172e+02 -2.41122305e+01 1.11848898e+02 -4.38177813e+00 -1.23079894e+01 -3.63360790e+00 -5.64878037e+01 4.60395879e-01 8.18005986e+00 -2.06294404e+01 -3.49659791e+01 4.31717988e+01 -2.92220843e+00 1.45250942e+01 -3.24346333e+01 3.66984591e+01 -2.75859278e+00 6.27805740e+00 4.98379104e+01 6.55060318e+00 3.91047481e+01 -1.14826290e+01 -8.00990322e-01 -3.68662287e+00 3.36483260e+01 -1.49103502e+01 1.34720251e+01 -1.80244019e+01 -2.90956806e+01 -2.78115796e+00 -1.10315060e+01 1.15584830e+00 -8.37313259e-01 -7.89905136e+00 6.27950290e+00 -1.09538327e+01 -2.48389637e+01 -1.16316264e+01 -3.00228631e+00 6.83518378e+01 -1.76428626e+01 6.10371772e+01 -6.12936496e+01 -1.14748321e+01 2.09075528e+01 3.32421356e+01 -4.11743268e+01 -2.19312422e+01 -2.08881337e+01 -5.05858326e+01 -2.14714962e+01 -1.11593182e+01 -6.16458839e-01 -1.12569338e+00 -1.40290786e-01 3.17622544e+01 -2.57159897e+01 5.51837314e-01 -1.33768644e+01 -3.25170630e+01 5.20806824e+01 1.08614313e-01 -3.62670514e+01 -2.68217433e+01 -3.42720513e+01 1.41341012e+01 -6.56371258e+01 8.64151127e+01 -3.08281756e+01 3.61562583e+01 -2.56736318e+01 -1.69118913e+01 3.35683331e+01 -7.48792540e+01 -2.02885460e+01 3.35543349e+00 1.07705825e+01 3.50306579e+00 -5.10021527e+00 2.46929457e+00 2.55749022e+01] lr.intercept_: -34.707522103873316

Training set score: 0.94

Test set score: 0.78

Chúng ta thấy có sự khác nhau giữa training score và test score, dấu hiệu của overfitting khi mô hình quá phức tạp, có quá nhiều hệ số. Một trong những giải pháp thay thế Linear Regression truyền thống là Ridge Regression.

Ridge Regression

Ridge Regression về cơ bản cũng giống với Linear Regression truyền thống, vẫn sử dụng đến hàm mean square error nhưng có điểm khác là công thức tìm giá trị hệ số w thì bổ sung thêm ràng buộc để sao cho các hệ số w nhỏ nhất có thể đến mức gần bằng 0, nghĩa là các feature (x) ít có ảnh hưởng tới giá trị đầu ra. Ràng buộc này sử dụng công thức chuẩn hóa L2.

Input:

import matplotlib.pyplot as plt
from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split
X, y = mglearn.datasets.load_extended_boston()
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
lr = Ridge().fit(X_train, y_train)
print("X.shape {}".format(X.shape))
print("lr.coef_: {}".format(lr.coef_))
print("lr.intercept_: {}".format(lr.intercept_))
print("Training set score: {:.2f}".format(lr.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lr.score(X_test, y_test)))

Output:

X.shape (506, 104)

lr.coef_: [-1.66018119e+00 -1.41929759e+00 -5.37684614e-01 7.96954640e-01 7.74009379e-01 9.00801690e+00 -8.92776134e-02 -4.91574523e+00 4.70214703e+00 -5.75434742e-01 -1.03433773e+00 1.77375286e+00 -4.16912180e+00 -2.13431099e-01 3.34424596e-03 -1.04210767e+00 1.56638846e+00 -1.20451306e+00 -1.42821926e+00 -1.61322770e+00 -2.42136076e-01 -1.94292142e+00 -1.67700882e+00 -1.48142670e+00 -1.04731871e+00 -1.11313713e+00 1.49485608e+00 -1.32119098e+00 2.31624450e+00 5.36928772e-01 3.45017547e+00 -1.23455386e+00 -2.35995304e-01 -4.33677055e-01 5.38893908e-01 1.73276291e+00 -1.12104286e+00 -1.80935022e+00 2.88495662e+00 1.82746265e+00 6.32937278e-01 -3.47131888e+00 1.89615705e+00 -3.09731568e+00 1.29031258e+00 3.20064563e+00 -2.05596659e+00 8.12855686e-01 -3.32761682e+00 7.96954640e-01 -5.86013095e+00 -3.57189492e+00 1.58982272e+00 -1.86216410e+00 3.61069409e+00 3.83871054e+00 2.09210783e-01 1.45641163e+00 -3.71898439e+00 -2.43728264e+00 -2.82695659e+00 -1.89357431e+00 -1.00515836e+00 -1.36445946e+00 -1.05970963e+00 -2.79742388e+00 -5.76463641e-01 -8.21276002e-01 1.80618447e+01 -7.76371306e-01 2.51323314e+00 -8.74200296e+00 -9.28927450e+00 -6.35833636e+00 9.81331630e+00 -8.34429422e+00 2.04363934e+00 -2.70371191e+00 3.56231644e+00 4.88560092e-01 -3.63645437e+00 -9.62975567e-01 -5.15644035e+00 9.99195084e-01 -1.06904595e+00 -3.30865649e+00 2.01128756e-01 -4.78203750e+00 -1.26479048e-01 8.78662293e-03 5.62854157e-01 2.54344334e+00 2.60329865e+00 -8.37207151e+00 9.28661900e-01 2.01937829e+00 -7.97643825e-01 -7.26085189e+00 1.76650958e+00 -1.81787063e+00 -6.69991765e-01 2.79044443e-01 -4.99596454e+00 1.12372028e+01] lr.intercept_: 19.772508539375153

Training set score: 0.87

Test set score: 0.81

Ridge Regression cho training score thấp hơn Linear Regression truyền thống nhưng điểm test thực tế lại cao hơn. Bởi vì Ridge đã loại bớt được số lượng các hệ số w, giảm bớt độ phức tạp của mô hình, qua đó tránh được tình trạng overfitting, đạt được genelization với dữ liệu test.

Chúng ta nhận thấy có 01 mối quan hệ nghịch giữa việc giảm số lượng các hệ số w và điểm training score, càng tìm cách để giảm số lượng hệ số w để mô hình đơn giản hơn thì điểm training score càng tồi và ngược lại.  Do đó, trong mô hình Ridge có thêm một hệ số alpha để điều chỉnh. Tăng alpha sẽ làm giảm số lượng các hệ số w (hầu hết các hệ số w quy về giá trị 0) thì điểm training score càng thấp. Ví dụ:

Input: alpha = 10

ridge10 = Ridge(alpha=10).fit(X_train, y_train)
print("Training set score: {:.2f}".format(ridge10.score(X_train, y_train)))
print("Test set score: {:.2f}".format(ridge10.score(X_test, y_test)))

Output: alpha = 10

Training set score: 0.77

Test set score: 0.73

Input: alpha = 0.1

ridge10 = Ridge(alpha=0.1).fit(X_train, y_train)
print("Training set score: {:.2f}".format(ridge10.score(X_train, y_train)))
print("Test set score: {:.2f}".format(ridge10.score(X_test, y_test)))

Ouput: alpha = 0.1

Training set score: 0.92

Test set score: 0.82

Hình vẽ sau biểu diễn mối quan hệ giữa việc điều chỉnh hệ số alpha và số lượng các trọng số w.

Input:

plt.plot(lr.coef_, 's', label="Ridge alpha=1")
plt.plot(ridge10.coef_, '^', label="Ridge alpha=10")
plt.plot(ridge01.coef_, 'v', label="Ridge alpha=0.1")
plt.plot(lr.coef_, 'o', label="LinearRegression")
plt.xlabel("Coefficient index")
plt.ylabel("Coefficient magnitude")
plt.hlines(0, 0, len(lr.coef_))
plt.ylim(-25, 25)
plt.legend()

Output:

Một điểm cần chú ý nữa là số lượng training data càng nhiều thì độ chính xác của các mô hình sẽ càng cao. Hình vẽ sau so sánh kết quả giữa Ridge và Linear sau khi tăng số lượng training và testing data:

Input:

mglearn.plots.plot_ridge_n_samples()

Output:

Hình vẽ này cho thấy training score của Ridge là thấp hơn so với Linear bởi vì Ridge sử dụng chuẩn hóa nhưng testing score của Ridge lại cao hơn Linear, không xảy ra hiện tượng Overfitting như Linear. Với dữ liệu nhỏ hơn 400 thì mô hình Linear gần như là rất tồi. Tuy nhiên khi lượng dữ liệu ngày càng nhiều thì mô hình Linear ngày càng tiệm cận Ridge, lúc đó có vẻ công thức chuẩn hóa của Ridge không còn quan trọng nữa. Một điểm chú ý nữa là khi dữ liệu càng nhiều thì training score của Linear sẽ giảm vì rất khó để có một mô hình có thể Overfitting cho đống dữ liệu nhiều như này.

LASO REGRESSION

Một mô hình anh em với Ridge là Laso, thay vì Ridge sử dụng công thức chuẩn hóa L2 khi tìm hệ số w thì Laso sử dụng công thức chuẩn hóa L1. Sử dụng công thức chuẩn hóa L1 nhằm mục đích loại bớt feature ít ảnh hưởng tới đầu ra nghĩa là làm cho phần lớn các trọng số w = 0.

Công thức chuẩn hóa L1:

Thay vì sử dụng bình phương các trọng số w (chính là bj trong công thức) thì L1 sử dụng hàm abs, để giảm tối đa giá trị trọng số w.

Input:

import numpy as np
from sklearn.linear_model import Lasso
lasso = Lasso().fit(X_train, y_train)
print("X.shape {}".format(X.shape))
print("Training set score: {:.2f}".format(lasso.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lasso.score(X_test, y_test)))
print("lasso.coef_: {}".format(lasso.coef_))
print("Number of features used: {}".format(np.sum(lasso.coef_ != 0)))

print("Number of features used: {}".format(np.sum(lasso.coef_ != 0)))

print("Number of features used: {}".format(np.sum(lasso.coef_ != 0)))

Output:

X.shape (506, 104) Training set score: 0.27 Test set score: 0.26

lasso.coef_: [-0. 0. -0. 0. -0. 0.
-0. 0. -0. -0. -0. 0.
-8.26069561 -0. 0. -0. 0. -0.
-0. -0. -0. -0. -0. -0.
-0. -0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. -0. 0. -0. -0.
-0. -0. -0. -0. -0. -0.
-0. 0. 0. 0. 0. 0.
0. 0. 0. 0. -0. -0.
-0. -0. -0. -0. -0. -0.
-0. -0. 0. 0. 0. -0.
-0. -0. 0. -0. -0. -0.
-0. -0. -0.50971544 -0. -0. 0.
-0. -0. -0. 0. -0. -1.13009513
-0. -0. -0. -0. -0. -0.
-0. -0. -0. -0. -0. 0.
-0. -0. ]

Number of features used: 3

Chúng ta thấy một kết quả tồi tệ, xảy ra hiện tượng underfitting bởi Laso đã loại bỏ gần hết các feature, cho ra một mô hình quá đơn giản. Cúng giống như Ridge, Laso có một hệ số alpha để điều chỉnh, mặc định alpha = 1.0, để tránh hiện tượng underfitting, chúng ta sẽ điều chỉnh giảm alpha và tăng tham số mặc định max_iter.

Input:

lasso001 = Lasso(alpha=0.01, max_iter=100000).fit(X_train, y_train)
print("Training set score: {:.2f}".format(lasso001.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lasso001.score(X_test, y_test)))
print("Number of features used: {}".format(np.sum(lasso001.coef_ != 0)))

Output:

Training set score: 0.89

Test set score: 0.80

Number of features used: 34

Kết luận: Trong thực tế, Ridge Regression sẽ là lựa chọn đầu tiên khi xét đến việc sử dụng Ridge hay Lasso. Tuy nhiên với bài toán có số lượng lớn dữ liệu và muốn giảm bớt các nhân tố thuộc tính ảnh hưởng đến kết quả đầu ra cho dễ hiểu thì chúng ta hay sử dụng Lasso hơn. Ngoài ra scikit-learn có lớp ElasticNet cho phép chúng ta sử dụng kết hợp cùng lúc 02 phương pháp Ridge và Lasso bằng cách cho phép điều chỉnh các trọng số sử dụng của chuẩn hóa L1 và L2.

Mô hình Linear cho bài toán phân loại (Linear model for classification)

Mô hình Linear Classification cũng được sử dụng trong bài toán phân loại. Biểu diễn công thức của mô hình cũng tương tự Linear Regression:

ŷ = w[0] * x[0] + w[1] * x[1] + … + w[p] * x[p] + b > 0

Tuy nhiên thay vì trả về con số tổng giá trị của các feature thì đầu ra sẽ được phân loại class là -1 nếu giá trị < 0, phân loại classs là +1 nếu giá trị > 0. Nếu như biểu đồ của Linear Regression thường được vẽ dưới dạng đường thẳng tuyến tính với single feature, dạng mặt phẳng hoặc nhiều mặt phẳng với nhiều thuộc tính multi features thì biểu đồ của Linear Classification biểu diễn dưới dạng các vùng biên ranh giới quyết định và các đường, mặt phẳng chia cắt các ranh giới đó chính là các đường mặt phẳng của Regression.

Có 02 mô hình Linear Classification chính:

  • Logistic Regression: sử dụng class linear_model.LogisticRegression
  • Linear Support Vector Machines: sử dụng class svm.LinearSVC

Ví dụ:

Input:

from sklearn.linear_model import LogisticRegression
from sklearn.svm import LinearSVC
import matplotlib.pyplot as plt
import mglearn

X,y = mglearn.datasets.make_forge()

fig, axes = plt.subplots(1,2, figsize=(10,3))

for model, ax in zip([LinearSVC(), LogisticRegression()], axes):
    clf = model.fit(X, y)
    mglearn.plots.plot_2d_separator(clf, X, fill=False, eps=0.5, ax=ax, alpha=.7)
    mglearn.discrete_scatter(X[:, 0], X[:, 1], y, ax=ax)
    ax.set_title("{}".format(clf.__class__.__name__))
    ax.set_xlabel("Feature 0")
    ax.set_ylabel("Feature 1")
axes[0].legend()

Output:

Cả 02 biểu đồ thể hiện đường kẻ chia ranh giới giữa 02 class 0 và 1. Ở dưới đường ranh giới là class 0, trên đường ranh giới là class 1. Cả 02 mô hình chúng ta thấy có đường biên ranh giới khá giống nhau do đều sử dụng chuẩn L2 regularization tương tự như thuật toán Ridge Regression.

Logistic và SVC có một tham số cho phép điều chỉnh điểm trade-off tối ưu hóa nhất bằng cách điều chỉnh hệ số của chuẩn L2 gọi là C, hệ số C càng cao thì càng tối thiểu hóa giá trị chuẩn hóa, càng dễ khớp với training data, khớp quá thì thành Overfitting, trong khi hệ số C càng thấp thì càng dễ triệt tiêu các trọng số C gây ra hiện tượng Underfitting. Ví dụ:

Input:

mglearn.plots.plot_linear_svc_regularization()

Output:

Chúng ta thấy khi C = 1000 có vẻ mô hình là khớp nhất so với training data, tuy nhiên vẫn bị sai mất 01 điểm. Nhìn chung mô hình Logistic và SVM đều bị hạn chế nếu lượng training data ít. Khi lượng training data nhiều lên thì sức mạnh của cả 02 thuật toán này mới được thể hiện. Sau đây, chúng ta sẽ thử với tập dữ liệu chẩn đoán ung thư của bệnh viện Boston, Mỹ:

Input:

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
cancer.data, cancer.target, stratify=cancer.target, random_state=42)
logreg = LogisticRegression().fit(X_train, y_train)
print("Training set score: {:.3f}".format(logreg.score(X_train, y_train)))
print("Test set score: {:.3f}".format(logreg.score(X_test, y_test)))

Output:

Training set score: 0.955

Test set score: 0.958

Chúng ta nhận thấy kết quả khá tốt với cả Training và Test data, tuy nhiên kết quả Training và Test khá giống nhau, có thể xảy ra hiện tượng underfitting. Chúng ta thử điều chỉnh tham số C để phân tích thêm:

Input:

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
cancer.data, cancer.target, stratify=cancer.target, random_state=42)

logreg = LogisticRegression().fit(X_train, y_train)

print("C=1.Training set score: {:.3f}".format(logreg.score(X_train, y_train)))
print("C=1.Test set score: {:.3f}".format(logreg.score(X_test, y_test)))

logreg100 = LogisticRegression(C=100).fit(X_train, y_train)
print("C=100.Training set score: {:.3f}".format(logreg100.score(X_train, y_train)))
print("C=100.Test set score: {:.3f}".format(logreg100.score(X_test, y_test)))

logreg001 = LogisticRegression(C=0.01).fit(X_train, y_train)
print("C=0.01.Training set score: {:.3f}".format(logreg001.score(X_train, y_train)))
print("C=0.01.Test set score: {:.3f}".format(logreg001.score(X_test, y_test)))

plt.plot(logreg.coef_.T, 'o', label="C=1")
plt.plot(logreg100.coef_.T, '^', label="C=100")
plt.plot(logreg001.coef_.T, 'v', label="C=0.001")
plt.xticks(range(cancer.data.shape[1]), cancer.feature_names, rotation=90)
plt.hlines(0, 0, cancer.data.shape[1])
plt.ylim(-5, 5)
plt.xlabel("Feature")
plt.ylabel("Coefficient magnitude")
plt.legend()

Output:

C=1.Training set score: 0.955

C=1.Test set score: 0.958

C=100.Training set score: 0.972

C=100.Test set score: 0.965

C=0.01.Training set score: 0.934

C=0.01.Test set score: 0.930

Hình vẽ trên cho thấy mối quan hệ giữa các feature với trọng số. Phần lớn các feature có giá trị bằng 0, bị triệt tiêu mức độ ảnh hưởng tới kết quả đầu ra. Các feature có giá trị khác 0 chứng tỏ là những thuộc tính ảnh hưởng lớn tới kết quả đầu ra, ví dụ như “texture error”, “mean radius”. Đồng thời thay đổi trọng số điều chỉnh C cũng cho kết quả khác nhau. Với trọng số C = 100 cho kết quả cao nhất chúng ta thấy khá nhiều feature có giá trị khác 0, mô hình có vẻ phức tạp vì có quá nhiều thuộc tính ảnh hưởng tới kết quả đầu ra. Trường hợp chúng ta muốn tiếp tục loại bớt sự ảnh hưởng của các thuộc tính thì có thể cấu hình sử dụng công thức chuẩn hóa L1.

Input:

for C, marker in zip([0.001, 1, 100], ['o', '^', 'v']):
lr_l1 = LogisticRegression(C=C, penalty="l1").fit(X_train, y_train)
print("Training accuracy of l1 logreg with C={:.3f}: {:.2f}".format(
C, lr_l1.score(X_train, y_train)))
print("Test accuracy of l1 logreg with C={:.3f}: {:.2f}".format(
C, lr_l1.score(X_test, y_test)))
plt.plot(lr_l1.coef_.T, marker, label="C={:.3f}".format(C))
plt.xticks(range(cancer.data.shape[1]), cancer.feature_names, rotation=90)
plt.hlines(0, 0, cancer.data.shape[1])
plt.xlabel("Feature")
plt.ylabel("Coefficient magnitude")
plt.ylim(-5, 5)
plt.legend(loc=3)

Output:

Training accuracy of l1 logreg with C=0.001: 0.91

Test accuracy of l1 logreg with C=0.001: 0.92

Training accuracy of l1 logreg with C=1.000: 0.96

Test accuracy of l1 logreg with C=1.000: 0.96

Training accuracy of l1 logreg with C=100.000: 0.99

Test accuracy of l1 logreg with C=100.000: 0.98

 

 

Các khái niệm Generalization, Overfitting, Underfitting và Trade-Off trong Machine Learning

Trong Supervised Machine Learning, chúng ta cố gắng đi tìm mô hình dự đoán chính xác nhất có thể dựa trên dữ liệu thu thập được trong quá khứ để có thể đoán được chính xác kết quả của dữ liệu mới, chưa từng gặp trong tương lai.

1.Generalization

Nếu một mô hình dự đoán được chính xác phần lớn các trường hợp của dữ liệu mới thì ta gọi đó là mô hình đạt được độ khái quát hóa (generalization).

2. Overfitting

Trong thực tế có rất nhiều biến số trong cuộc sống, việc đi tìm các mô hình không đơn giản, không phải lúc nào cũng tìm được generalization. Ví dụ: 01 công ty kinh doanh du thuyền muốn dự đoán một khách hàng nào có khả năng mua du thuyền cao nhất dựa trên dữ liệu về khách hàng đã mua du thuyền được thu thập và phân tích đặc tính trước đó.

Tuổi Số ô tô sở hữu Có nhà riêng Số người con Tình trạng hôn nhân Có nuôi chó Có mua du thuyền
66 1 2 Góa chồng Không
52 2 3 Đã cưới Không
22 0 Không 0 Đã cưới Không
25 1 Không 1 Độc thân Không Không
44 0 Không 2 Li dị Không
39 1 2 Đã cưới Không
26 1 Không 2 Độc thân Không Không
40 3 1 Đã cưới Không
53 2 2 Li dị Không
64 2 3 Li dị Không Không
58 2 2 Đã cưới
33 1 Không 1 Độc thân Không Không

Sau khi phân tích dữ liệu, một số nhà phân tích ít kinh nghiệm đưa ra quy tắc: “Nếu khách hàng trên 45, có nhỏ hơn 03 con hoặc chưa từng li dị thì có khả năng mua du thuyền”. Họ cho rằng quy tắc này đúng 100%. Quy tắc trên là khá phức tạp nhiều biến số dựa trên lượng dữ liệu quá ít làm cho các nhà phân tích trẻ chủ quan rằng quy tắc quá hoàn hảo. Khi đó, chúng ta gọi mô hình này xảy ra là overfitting. Overfitting xảy ra khi xây dựng một mô hình quá phức tạp để khớp với một lượng dữ liệu training không đủ, dẫn tới mô hình này lại không thể khớp với dữ liệu mới trong thực tế.

3. Underfitting

Ngược lại với Overfitting là khi cảm thấy quá phức tạp, chúng ta bỏ bớt các biến số, đơn giản hóa mô hình nhưng đơn giản quá đến mức không bao quát được hết các biến số trong thực tế. Khi đó ta gọi mô hình này xảy ra underfitting. Ví dụ: “Những ai mua nhà thì sẽ mua du thuyền”.

4. Trade-Off

Có một điểm vàng (sweet spot) ở giữa Overfitting và Underfitting, ở đó chúng ta đạt mức độ generalization cao nhất. Điểm này gọi là điểm thỏa thuận, chấp nhận được (Trade – Off). Điểm này nhắc cho chúng ta nhân sinh quan trong cuộc sống, cái gì nhiều quá cũng không tốt mà ít quá cũng không được, cần nỗ lực không ngừng nhưng cần biết điểm dừng vừa đủ mới là tốt. Đó cũng là triết lý của tự nhiên.

Supervised Learning (Thực hành – Phần 1)

1. Supervised Learning là gì?

  • Phương pháp bao gồm các thuật toán đoán trước giá trị dựa trên kinh nghiệm học của tập giá trị input – output trong quá khứ;
  • Điểm cốt lõi của phương pháp này là xây dựng tập giá trị đào tạo (training set data), bước này đòi hỏi nhiều nguồn lực, tuy nhiên sau khi có được bộ dữ liệu ngon thì việc tìm ra mô hình, công thức cho độ chính xác cao là rất nhanh;
  • Khi xây dựng được bộ dữ liệu, thông thường ta sẽ chia thành 02 bộ training settesting set data. Trong đó, training set để phục vụ cho việc học các mô hình (như k-Nearest Neighbors, linear, …v.v) còn testing set để đối chiếu so với kết quả học để check độ chính xác của các mô hình (ví dụ: training set chiếm 75%, testing set chiếm 25%). Trong thư viên scikit-learn của python có hàm train_test_split để thực hiện tạo 02 bộ dữ liệu từ 01 bộ dữ liệu mà ta đã thu thập từ trước: X_train, X_test, y_train, y_test = train_test_split(array_data, array_target, random_state=0). Lưu ý: X viết hoa đại diện cho input.

2. Phân loại Supervised Learning

02 loại chính của Supervised Learning là classification (phân loại) và regression (hồi qui).

Classification: mục đích là đoán trước để gán nhãn phân loại kết quả thuộc nhóm định sẵn. Chia làm 02 loại: binary classification (chỉ có 02 nhóm) và multi class (nhiều nhóm). Ví dụ về binary classification: phân tích kết quả chụp x-quang khối u đoán là u lành hay u ác; phân loại mail là spam hay không. Ví dụ dưới đây là code trên python để vẽ biểu đồ scatter biểu diễn dữ liệu chia thành 02 lớp xanh, đỏ tách biệt nhau rõ rệt:

import mglearn
import matplotlib.pyplot as plt
X, y = mglearn.datasets.make_forge()
mglearn.discrete_scatter(X[:,0], X[:,1],y)
plt.legend(["Class 0", "Class 1"], loc=4)
plt.xlabel("First Feature")
plt.ylabel("Second Feature")
print("X.shape: {}".format(X.shape))

Regression: mục đích là đoán trước kết quả là một số nguyên (floating point). Ví dụ: đoán thu nhập của một người dựa trên bằng cấp, tuổi tác và số năm kinh nghiệm; đoán giá nhà dựa trên diện tích và vùng miền. Ví dụ: đoạn code dưới đây mô phỏng dữ liệu dạng tuyến tính:

import mglearn
import matplotlib.pyplot as plt
X, y = mglearn.datasets.make_wave(n_samples=40)
plt.plot(X, y, 'o')
plt.ylim(-3, 3)
plt.xlabel("Feature")
plt.ylabel("Target")

3. Mô hình k-Nearest Neighbors

kNN Là một trong những mô hình đơn giản nhất của Machine Learning. Trong mô hình này, chúng ta xây dựng trước tập (input, output) cho training set, kết quả đoán trước của 01 input mới dựa vào quy tắc tìm điểm gần nhất của training set với input mới này (gọi là anh hàng xóm gần nhất). Dân gian có câu muốn biết tính cách của 01 người như nào hãy xem tính cách của anh/cô bạn thân của người đó; thuật toán này tương tự như vậy.

3.1. k-Neighbors classification

Trường hợp đơn giản nhất là chỉ xét cô bạn chỉ có 1 người bạn gái thân duy nhất, việc đoán tính cách có vẻ dễ dàng. 

mglearn.plots.plot_knn_classification(n_neighbors=1)

Như trong hình vẽ trên thì chúng ta chú ý hình ngôi sao là input cần test, chúng ta thấy có 3 đường kẻ tới các ngôi sao này, đó chính là đường nối giữa input training gần nhất với input test.

Tuy nhiên trong thực tế, rất ít trường hợp chỉ có 01 cô hàng xóm mà sẽ có thể có nhiều cô hàng xóm, khi đó ta có k-neighbors, đó chính là tên gọi của thuật toán này.

mglearn.plots.plot_knn_classification(n_neighbors=3)

Giờ chúng ta bắt đầu thử training với k-Neighbors với tập dữ liệu chuẩn đoán u lành hay u ác khi xét nghiệm ung thư:

from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn.neighbors import KNeighborsClassifier
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, stratify=cancer.target, random_state=66)
training_accuracy = []
test_accuracy = []
# try n_neighbors from 1 to 10
neighbors_settings = range(1, 11)
for n_neighbors in neighbors_settings:
   # build the model
   clf = KNeighborsClassifier(n_neighbors=n_neighbors)
   clf.fit(X_train, y_train)
   # record training set accuracy
   training_accuracy.append(clf.score(X_train, y_train))
   # record generalization accuracy
   test_accuracy.append(clf.score(X_test, y_test))
plt.plot(neighbors_settings, training_accuracy, label="training accuracy")
plt.plot(neighbors_settings, test_accuracy, label="test accuracy")
plt.ylabel("Accuracy")
plt.xlabel("n_neighbors")
plt.legend()

Với cùng tập dữ liệu training và testing có sẵn, chúng ta tiến hành đánh giá độ chính xác khi thử hệ số k-neighbors từ 1 đến 10. Dựa trên kết quả cho ta thấy, với tập dữ liệu training độ chính xác giảm xuống khi hệ số k tăng, còn với tập dữ liệu testing thì ngược lại, nghĩa là với chỉ 1 neighbors thì mô hình thực tế sẽ rất phức tạp (over fitting), độ chính xác thấp trong khi tăng số neighbors lên 10 (under fitting) thì mô hình quá đơn giản, kết quả cùng tồi không kém. Điểm kết quả khả quan nhất (generalization) rơi vào tầm 5-6, khoảng giữa 1 và 10. Trong thực tế khi triển khai các mô hình ML, chúng ta cần tìm ra điểm cho độ chính xác chấp nhận được.

3.2. k-Neighbors regression

Tương tự như classification, mô hình kNN regression rất đa dạng, phụ thuộc vào hệ k.

mglearn.plots.plot_knn_regression(n_neighbors=1)

mglearn.plots.plot_knn_regression(n_neighbors=3)

Triển khai thuật toán kNN regression sử dụng KNeighborsRegressor:

from sklearn.neighbors import KNeighborsRegressor
X, y = mglearn.datasets.make_wave(n_samples=40)
# split the wave dataset into a training and a test set
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
# instantiate the model and set the number of neighbors to consider to 3
reg = KNeighborsRegressor(n_neighbors=3)
# fit the model using the training data and training targets
reg.fit(X_train, y_train)

print("Test set predictions:\n{}".format(reg.predict(X_test)))

print("Test set R^2: {:.2f}".format(reg.score(X_test, y_test)))

Kết quả:

Test set predictions: [-0.05396539 0.35686046 1.13671923 -1.89415682 -1.13881398 -1.63113382 0.35686046 0.91241374 -0.44680446 -1.13881398] Test set R^2: 0.83


Bây giờ, chúng ta thực hiện vẽ biểu đồ để có thêm chiều sâu phân tích kết quả, sử dụng tập dữ liệu từ hàm linspace của thư viện numpy, random 1000 điểm tuyến tính, chúng ta vẽ biểu đồ cho 03 hệ số k = 1, 3, 9.
import numpy as np
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
# create 1,000 data points, evenly spaced between -3 and 3
line = np.linspace(-3, 3, 1000).reshape(-1, 1)
for n_neighbors, ax in zip([1, 3, 9], axes):
    # make predictions using 1, 3, or 9 neighbors
    reg = KNeighborsRegressor(n_neighbors=n_neighbors)
    reg.fit(X_train, y_train)
    ax.plot(line, reg.predict(line))
    ax.plot(X_train, y_train, '^', c=mglearn.cm2(0), markersize=8)
    ax.plot(X_test, y_test, 'v', c=mglearn.cm2(1), markersize=8)
    ax.set_title("{} neighbor(s)\n train score: {:.2f} test score: {:.2f}".format(n_neighbors, reg.score(X_train, y_train),
    reg.score(X_test, y_test)))
    ax.set_xlabel("Feature")
    ax.set_ylabel("Target")
axes[0].legend(["Model predictions", "Training data/target",
"Test data/target"], loc="best")

Kết quả:

Với k =  1 thì mô hình quá phức tạp, lên xuống liên tục, kết quả tồi;

Với k = 9 thì mô hình có vẻ đơn giản, đường nối rất trơn nhưng lại không khớp với training data.

Kết luận điểm mạnh, điểm yếu của kNN:

  • kNN phụ thuộc vào 02 yếu tố: hệ số k và hàm đo khoảng cách giữa các điểm để xác định khoảng cách nhỏ nhất, thực tế chúng ta sử dụng khoảng cách Euclidean để chuẩn hóa. Như trong training thì ta thấy điều chỉnh hệ số k sẽ cho ra kết quả độ chính xác khác nhau, k = 3 – 5 cho kết quả tốt nhưng trong thực tế chúng ta nên điều chỉnh nhiều hơn để tìm điểm tối ưu hóa nhất.
  • Điểm mạnh: dễ hiểu, dễ đạt được độ chính xác tốt mà ít phải điều chỉnh. 
  • Điểm yếu: phải xây dựng training set công phu và khi bộ dữ liệu lớn (hàng triệu) thì thuật toán sẽ chạy tương đối chậm. kNN không thể áp dụng được cho trường hợp mô hình có quá nhiều nhân tố biến số (lên đến hàng trăm). Chính vì vậy, kNN không được áp dụng nhiều trong thực tế.

 

 

Gradient Descent thần thánh

Như chúng ta đã biết, hiện nay Machine Learning nói riêng, AI nói chung không thể có công thức đúng 100% mà chỉ có thể tối ưu hóa đến khả năng đúng tốt hơn và khẩu hiệu của AI là “tốt hơn” và “tốt hơn”. Nghĩa là trong mạng lưới training với các cặp (x,y) đầu vào là x, đầu ra là y thì nhiệm vụ là đoán đầu ra y so với đầu vào x sao cho “đúng nhiều nhất có thể”. Làm thế nào để biết được là đúng nhiều nhất có thể? “Đúng nhiều nhất có thể” đồng nghĩa với  việc trong quá trình training, điều chỉnh các trọng số để đi tới mục tiêu sai số ít nhất  so với thực tế. Một trong những phương pháp giải quyết vấn đề đó là Gradient Descent. 

1. Gradient Descent là gì?

Là phương pháp điều chỉnh các trọng số (weight) để đi đến mục tiêu sai số, lỗi (error) ít nhất so với thực tế. Như vậy, 02 yếu tố cần quan tâm nhất là trọng số (weight)lỗi (error). Hình vẽ dưới đây mô tả mối quan hệ giữa 02 yếu tố trên và cách hoạt động của Gradient Descent:

Đường parapol màu xanh thể hiện quan hệ giữa lỗi và trọng số. Nhiệm vụ của Gradient Descent là tìm điểm cực tiểu (dấu x màu đen) ở đáy của parapol mà tại đó giá trị sai số là nhỏ nhất. 

Bắt đầu với giá trị ngẫu nhiên w1 (điểm màu đỏ) trên đồ thị, chúng ta cần thay đổi giá trị trọng số w để đi đến điểm cực tiểu x màu đen. Vậy thay đổi trọng số như thế nào, theo chiều nào? Trong 02 từ Gradient Descent thì Gradient nghĩa là tạo độ dốc, còn Descent nghĩa là đi xuống dưới, kết hợp 02 từ nghĩa là dốc xuống dưới, tức là thay đổi trọng số theo chiều dốc xuống dưới. 

Phương pháp Gradient Descent là phương pháp sử dụng đạo hàm để thay đổi trọng số w theo hướng đến điểm error tối thiểu trong đường cong parapol. Đây là quá trình lặp, biểu diễn dưới dạng công thức như sau:

wnew=woldαerror

wnew: trọng số tại thời điểm mới (hiện tại)

wold: trọng số cũ tại thời điểm quá khứ

error: đạo hàm của sai số tại thời điểm wold

α: bước nhảy, xác định tốc độ hội tu đến điểm cực tiểu của error trong đường cong parapol. Việc điều chỉnh giá trị của bước nhảy α rất quan trọng, nếu α quá lớn sẽ dẫn tới không hội tụ vào điểm cực tiểu được (giống như đi tàu vũ trụ để bay từ Hà Nội vào Nghệ An thì phanh không kịp, đến lúc phanh được thì đã ở Hồ Chí Minh rồi), nếu α quá nhỏ thì thời gian đi tới điểm hội tụ lại quá lâu.

Đoạn code mô phỏng quá trình tìm nghiệm w đơn giản bằng Grandient Descent:

Tìm điểm cực tiểu của phương trình: f(x)=x43.x3+2

Đạo hàm của f(x): f(x)=4.x39.x2

Bằng phương pháp tính toán sẽ cho ra nghiệm x = 2.25

x_old = 0 # The value does not matter as long as abs(x_new - x_old) > precision
x_new = 6 # The algorithm starts at x=6
gamma = 0.01 # step size
precision = 0.00001

def df(x):
y = 4 * x**3 - 9 * x**2
return y

while abs(x_new - x_old) > precision:
x_old = x_new
x_new += -gamma * df(x_old)

print("The local minimum occurs at %f" % x_new)

2.  Hàm chi phí

Gradient Descent là quá trình lặp để cực tiểu hóa các sai số error đầu ra bằng việc điều chỉnh các trọng số w. Tuy nhiên còn 01 điểm cần chú ý trước khi đi tìm trọng số w là xác định mô hình dữ liệu cho bài toán, ví dụ có thể là mô hình hồi quy tuyến tính đa thức bậc 1, bậc 2 hoặc có thể là đa thức bậc n. Việc xác định mô hình sẽ ảnh hưởng lớn đến kết quả chính xác của mạng lưới NN của Machine Learning, một trong những vấn đề đó là overfitting và underfitting. Overfitting là xảy ra khi mô hình dự đoán đưa ra đẹp quá, khớp quá với một số dữ liệu ban đầu ít ỏi đến nỗi đánh lừa kết quả, phức tạp quá đến nỗi ảnh hưởng tới quá trình tìm nghiệm. Một trong những cách để khắc phục overfitting là sử dụng hàm chi phí cost function.

J(w,b,x,y)=1/2.yzh(nl)(xz)2=1/2.yzypred(xz)2

 

Biểu diễn của bất kỳ Machine Learning dưới dạng công thức toán học như sau: f(x) = f(b0, b1, b2,…, bn). Gradient Descent là phương pháp được sử dụng để tìm ra các hệ số b0, b1, b2,…, bsao cho giảm thiểu sai lệch (hàm mất mát) so với kết quả thực tế. 

2. Gradient Descent hoạt động như thế nào?

Mô tả ngắn gọn về Gradient Descent như sau: phương pháp tìm các hệ số nghiệm b0, b1, b2,…, bn bằng cách thử nghiệm liên tục theo vòng lặp với các giá trị b0, b1, b2,…, bcho trước rồi tính toán hàm mất mát của các hệ số này để hệ số của lần thử nghiệm sau tốt hơn một chút so với lần thử nghiệm trước, cho đến khi tìm thấy hàm mất mát đạt giá trị nhỏ nhất.

  • Bước 1: gán giá trị default cho các hệ số
  • Bước 2: Tính giá trị hàm mất mát (cost function)
  • Bước 3: lựa chọn giá trị mới cho các hệ số
  • Lặp lại quá trình 03 bước trên với thời gian đủ dài đến khi cảm thấy hàm mất mát đạt giá trị nhỏ nhất.

Tưởng tượng hình ảnh của 1 cái bát ăn cơm cũng chính là hình vẽ của hàm mất mát (cost function), trong đó một điểm bất kỳ trên bề mặt cái bát cũng có thể là giá trị hiện tại của hàm mất mát của các hệ số nghiệm hiện tại, còn đáy của cái bát là nơi mà các hệ số nghiệm cho ra hàm mất mát tốt nhất, nơi mà các nghiệm hội tụ. 

Hình vẽ dưới đây mô phỏng quá trình đi tìm nghiệm của Gradient Descent, đồ thị của hàm mất mát là các vòng tròn đồng tâm, quá trình lặp của Gradient Descent để hội tụ điểm màu đỏ vào điểm giữa, đáy của các vòng tròn đồng tâm đó. 

 

3. Biễu diễn công thức Gradient Descent

  • Bước 1: gán các hệ số với giá trị default: coefficient = 0.0
  • Bước 2: Tính hàm cost = evaluate(f(coefficient)). Tính đạo hàm của cost để xác định hướng di chuyển của các hệ số trong lần lặp tiếp theo: delta = derivative(cost)
  • Bước 3: cập nhật giá trị các hệ số: coefficient = coefficient−(alpha×delta). Trong đó alpha là tốc độ học, việc lựa chọn tốc độ học khá quan trọng, nếu alpha lớn thì bước nhảy của hàm cost lớn dẫn tới không hội tụ đến được điểm chi phí mất mát nhỏ nhất. xt+1=xtη.f(xt)

Ví dụ: giả sử mô hình ML dưới dạng hàm số f(x)=x2+5.sin(x). Khi đó, đạo hàm của hàm số trên là f(x)=2.x+5.cos(x). Giá trị của hệ số tại thời điểm t được biểu diễn như sau:

bt+1 = btη.f(bt) = bt – 2.bt + 5.cos(bt)

4. Gradient Descent quy mô lớn

Chương trình dùng Gradient Descent có thể chạy rất chậm mới cho ra kết quả nếu áp dụng trên lượng dữ liệu lớn bởi mỗi vòng lặp phải tính toán nhiều bước cho mỗi hệ số, sẽ là rất lâu nếu chạy vòng lặp trên hàng triệu dữ liệu training set, thêm vào đó là nhiều hệ số sẽ càng chậm. Do vậy, một trong những cách tối ưu hóa cho Gradient Descent là cập nhật giá trị của các hệ số ngay lập tức trong mỗi vòng lặp thay vì đợi kết thúc mỗi vòng lặp mới cập nhật.

Ví dụ cụ thể: cho tập dữ liệu training set như sau:

x y
1 1
2 3
4 3
3 2
5 5

Đôi nét về Machine Learning

Từ năm 2013 trở lại đây, AI (trí tuệ nhân tạo) đã có những bước tiến vượt bậc so với thế kỷ trước dù những phát minh đầu tiên ra đời từ những năm 1950. Để có được những thành tựu đó là do các nhà khoa học đã thay đổi cách tiếp cận tư duy chiến lược từ tư duy toán học thuần túy sang tư duy khoa học tự nhiên. Đó là cách mà Machine Learning đã thực hiện để khiến cho AI trở nên thông minh hơn, có những bước tiến nhảy vọt như ngày nay. Nói không ngoa rằng Machine Learning đã cải tạo, thay đổi bản chất của trí tuệ nhân tạo.

Vậy Machine Learning là gì? tại sao ML lại tạo cho AI bước tiến nhảy vọt như vậy?

Hãy tưởng tượng cách học của người Việt ngày xưa: nặng nề, nhồi nhét kiến thức, học vẹt. Đây cũng là cách tiếp cận AI của các lập trình viên trong quá khứ, họ viết các chương trình giải quyết từng trường hợp cụ thể, sử dụng thuật toán cụ thể, điều này dẫn tới khi thay đổi biến số sẽ dẫn tới chương trình không còn đúng. 

Thời gian gần đây, chương trình cải cách giáo dục đã bớt nhồi nhét kiến thức thay vào đó là chuyển sang phương pháp tự học, nghĩa là cung cấp cho học sinh, sinh viên phương pháp và cung cấp dữ liệu (tài liệu học), học sinh và sinh viên sẽ tự đúc kết thành kiến thức, trí tuệ của mình. Đây cũng chính là phương pháp mà Machine Learning áp dụng cho AI. Nghĩa là cung cấp phương pháp học, dữ liệu, máy học sẽ dựa trên 02 nhân tố này để hình thành nên tri thức, phát hiện ra lỗi sai, lỗi đúng. Các lập trình viên không phải viết chương trình cho bài toán cụ thể mà họ chỉ cần viết phương pháp thuật toán chung, sau đó họ cung cấp đầu vào dữ liệu để máy tính phân biệt đúng sai, đây gọi là quá trình training, qua quá trình này máy tính sẽ tìm được hàm, thuật toán gần đúng nhất với bài toán.

Lấy ví dụ bài toán nhận dạng hình ảnh khuôn mặt, ngày xưa các lập trình viên say sưa đi theo lối mòn các thuật toán phân tích hình ảnh, xử lý hình ảnh, tuy nhiên chỉ cần khuôn mặt thay đổi đặc tính như người đàn ông béo lên 1 tí, có thêm râu ria hay người phụ nữ tô phấn hồng thêm 1 tí là khó phân biệt được. Thuật toán cụ thể rất khó giải quyết cho tất cả các trường hợp.

Logistic Regression
  1. Logistic Regression là gì?

  • Thuật toán Machine Learning này được vay mượn từ xác suất thống kê, được sử dụng để tính khả năng phân loại [0,1]  với đầu vào dữ liệu cụ thể, trong đó thuật toán được biểu diễn dựa trên hàm Logistic Funtion (hàm sigmoid của logarit tự nhiên)
  • Hàm sigmoid hay đường cong sigmoid: hàm logarit chuẩn, dạng: P = 1/(1+ evalue)

  • Hàm logistic Regression biểu diễn dưới dạng model như sau:

y = e(B0+B1×x)  / (1+ eB0+B1×x)

–> Nhiệm vụ là tìm nghiệm của phương trình trên (tức là B0, B1) đúng nhất với đầu vào dữ liệu có sẵn (training set)

  • Ví dụ: Dự đoán xác suất thi đỗ dựa trên số giờ học của sinh viên:
Hours Pass Hours Pass
.5 0 2.75 1
.75 0 3 0
1 0 3.25 1
1.25 0 3.5 0
1.5 0 4 1
1.75 0 4.25 1
1.75 1 4.5 1
2 0 4.75 1
2.25 1 5 1
2.5 0 5.5 1

Hình ảnh thu được của hàm Logistic Function (dạng chữ S uốn cong tuyến tính)

2. Logistic Regression – Tính ứng dụng?

Tính ứng dụng của Logistic Regression khá phổ biến, đặc biệt sử dụng trong bài toán phân loại (Classification) trong đó 02 lớp class dưới dạng tuyến tính cách nhau (linear separable) như chuẩn đoán bệnh ung thư, đoán trước tỷ lệ ủng hộ bỏ phiếu, thành công của sản phẩm, dự đoán đội bóng thắng/thua, mã chứng khoán tăng hay giảm…v.v.

Tuy nhiên trong thực tế dữ liệu của 01 class có thể nằm trong 1 vòng tròn, 1 class khác nằm ngoài vòng tròn, lúc đó Logistic Regression không còn đúng, không áp dụng được.

3. Học mô hình Logistic Regression như nào?

Learning là quá trình tìm, định lượng các hệ số B0, B1 trong mô hình Logistic Regression từ tập dữ liệu có sẵn (training data set). Trong Machine Learning nói riêng và AI nói chung rất khó có thể năng tìm ra đúng, chính xác 100% các hệ số này mà chỉ cố gắng định lượng giá trị có khả năng cao nhất gần đúng hay nói cách khác là giảm thiểu tối đa sai sót, chênh lệch khi lắp ghép các hệ số B0, B1 này vào model so với kết quả thực tế.

4. Đoán trước giá trị của Logistic Regression 

Đoán trước giá trị của model biểu diễn như sau:

p(class = 0) = 1/ (1 – eoutput)

prediction = 0 nếu p(class) < 0.5

prediction = 1 nếu p(class) >= 0.5

4. Học Logistic Regression bằng phương pháp Gradient Descent?

Phương pháp học sử dụng rộng rãi nhất trong Machine Learning vẫn là Gradient Descent (đi ngược đạo hàm) với learning rate (tốc độ học), điều chỉnh các hệ số để sao cho hội tụ hàm chi phí tối thiểu về 0.

xt+1=xt−ηf′(xt)

Trong đó: η (đọc là eta): Learning rate, số dương; f’: đạo hàm

Ví dụ: hàm số f(x)=x2+5sin(x) sẽ có đạo hàm f′(x)=2x+5cos(x)

5. Logistic Regression vì sao?