Trong bài viết ngày hôm nay, mình sẽ cùng các bạn giới thiệu về thuật toán linear regression và áp dụng vào bài toán dự đoán điểm thi.
Bài viết này yêu cầu các bạn cần có một chút kiến thức về lập trình python và hiểu về thuật toán linear regression. Với thuật toán linear regression, bạn có thể đọc bài viết ở link tham khảo phía cuối bài viết này của anh Vũ Hữu Tiệp. Còn đối với python, bạn cũng đừng quá lo lắng vì mình sẽ giải thích từng đoạn code để các bạn có thể hiểu. Trong thời gian tới, mình sẽ cố gắng viết một khóa học python để các bạn có thể học tốt hơn. Rất mong nhận được sự ủng hộ của các bạn.
Đây là một bài viết trong chuyên mục machine learning.
Bài viết này sẽ gồm 3 phần chính:
- Giới thiệu về bài toán và dữ liệu
- Triển khai code giải quyết bài toán
- Đánh giá và kết quả
Phát biểu bài toán linear regression
Bài toán mình đưa ra là cho một tập dữ liệu điểm sinh viên bao gồm các trường: điểm thi lần 1, điểm thi lần 2, điểm thi lần 3 và điểm thi lần cuối cùng. Các bạn có thể hiểu là 3 lần thi đầu là thi định kỳ( điểm nằm trong đoạn 0 – 100) và lần thi cuối cùng là thi kết thúc môn (điểm nằm trong đoạn 0 – 200). Mục tiêu của chúng ta cần giải quyết là dựa vào dữ liệu đã có, xây dựng mô hình học máy cho phép dự đoán điểm thi lần cuối của một sinh viên khi đã biết điểm 3 lần thi trước đó.
Vậy input của chúng ta là điểm thi của các thí sinh ở 3 lần đầu, và outcome là điểm ở lần final
Đây là hình ảnh mô tả dữ liệu, dữ liệu mình lưu trữ ở file .csv, mình sẽ cung cấp cho các bạn ở cuối bài
Triển khai code giải quyết bài toán linear regression
Đầu tiên, ta cần import các thư viện cần thiết.
- thư viện numpy để tính toán và thao tác với ma trận
- thư viện pandas để thao tác đọc file .csv
- thư viện sklearn có thể dùng để giải quyết bài toán này, ở đây mình dùng để so sánh với kết quả tự tính
0
1
2
3
4
|
import numpy as np
import pandas as pd
from sklearn import linear_model
|
Một số hàm sẽ được sử dụng trong bài toán
Đọc dữ liệu từ file .csv trả về một dataframe (cái này tương tự data_table trong C#).
0
1
2
3
4
|
def read_data(csv_file):
csv_df = pd.read_csv(csv_file)
return csv_df
|
Bạn có thể sử in ra csv_df, kết quả sẽ như hình sau
Hàm tiếp theo, chuyển dataframe về ma trận và tách riêng input, outcome
0
1
2
3
4
5
6
7
|
def split_data(csv_df):
input = csv_df.iloc[:, :-1] # lấy trên mọi hàng, và chỉ bỏ cột cuối cùng
output = csv_df.iloc[:, -1] # lấy trên mọi hàng, và chỉ lấy cột cuối cùng
x = input.values
y = output.values.reshape((-1, 1)) # reshape để chuyển y thành ma trận cột
return x, y
|
Sau bước này, input và outcome lần lượt là các ma trận.
Tiếp theo là hàm tìm các hệ số w, ở đây do input có 3 tham số, nên chúng ta cần tìm w0, w1, w2, w3.
0
1
2
3
4
5
6
7
8
9
|
def find_optimize(input, outcome):
"""
input.T: chuyển vị của ma trận input
np.dot(a,b) : nhân từng phần tử của ma trận a với ma trận b
np.linalg.pinv(x): tìm giả ngịch đảo/ ngịch đảo của ma trận x
"""
w = np.dot(np.linalg.pinv(np.dot(input.T, input)), np.dot(input.T, outcome))
return w
|
Hàm tương đương sử dụng thư viện sklearn để đối chiếu kết quả
0
1
2
3
4
5
|
def optimize_with_sklearn(input, outcome):
regr = linear_model.LinearRegression(fit_intercept=False) # fit_intercept = False for calculating the bias
regr.fit(input, outcome)
return regr.coef_
|
Hàm tiếp theo là hàm tìm sai số của mô hình
0
1
2
3
4
5
6
7
8
|
def get_loss_value(input, outcome, w):
cost = 0
y_hat = np.dot(input, w)
for x, y in zip(outcome, y_hat):
print('Outcome:', x[0], 'Predict:', y[0])
cost += pow(x[0] - y[0], 2)
return cost / 2
|
Sau khi có các hàm trên, chúng ta tiến hành gọi lần lượt ở hàm main để kiểm tra kết quả. Tuy nhiên, chúng ta cần 2 dòng code để biến ma trận input thành input bar bằng cách thêm một cột giá trị 1 vào trước.
0
1
2
3
4
5
|
# chuyển ma trận input sang ma trận input bar
# bằng cách thêm vector cột giá trị 1 vào trước ma trận
one = np.ones((input.shape[0], 1))
input = np.concatenate((one, input), axis=1)
|
Đánh giá kết quả mô hình linear regression
Đối chiếu kết quả giữa mô hình tự tính và mô hình sử dụng thư viện sklearn
0
1
2
3
4
5
|
w1 = find_optimize(input, outcome)
w2 = optimize_with_sklearn(input, outcome)
print(w1.T) # chuyển vị ma trận
print(w2)
|
Kết quả cho thấy là giống nhau.
0
1
2
3
|
[[-4.3361024 0.35593822 0.54251876 1.16744422]]
[[-4.3361024 0.35593822 0.54251876 1.16744422]]
|
Tính toán giá trị mất mát và hiển thị sự sai khác giữa kết quả dự đoán và kết quả thực tế trên tập dữ liệu huấn luyện. Outcome là kết quả thật sự, và Predict là kết quả dự đoán của mô hình. Ở đây giá trị mất mát trên tập huấn luyện xấp xỉ 71,72.
Chúng ta có thể dự đoán cho một dữ liệu chưa biết, bằng cách sử dụng hàm sau
0
1
2
3
4
5
6
|
def predict_new_data(input, w):
# convert to input_bar
one = np.ones((input.shape[0], 1))
input = np.concatenate((one, input), axis=1)
return np.dot(input, w)
|
Và thử xem kết quả với một dữ liệu chưa biết ở hàm main
0
1
2
|
print(predict_new_data(np.array([[70, 73, 79]]), w1))
|
Kết quả:
0
1
2
|
[[152.4115353]]
|
Hi vọng bài viết của mình đem lại sự hữu ích cho tất cả các bạn, nếu có bất kỳ câu hỏi hay thắc mắc nào bạn có thể để lại bình luận. Mình sẽ giải thích sớm nhất có thể cho các bạn.
Và cuối cùng, để tải toàn bộ source code và dữ liệu của bài hướng dẫn, bạn đọc hãy truy cập vào link này: https://github.com/NguyenVanHieuBlog/predict-student-score