Tổng số lượt xem trang

Thứ Năm, 27 tháng 7, 2017

BÀI 6: MULTIPLE LINEAR REGRESSION (HỒI QUY TUYẾN TÍNH NHIỀU BIẾN)

Trong Bài 5, chúng là đã thảo luận thuật toán Simple Linear Regression. Thuật toán Linear Regression đó chỉ phụ thuộc vào một biến độc lập để dự đoán cho một biến phụ thuộc khác. Trong Bài 6, chúng ta sẽ tìm hiểu và cài đặt thuật toán Multiple Linear Regression. Thuật toán này phụ thuộc vào hai hay nhiều biến độc lập để dự đoán cho một biến phụ thuộc khác.
 Sau bài học này, người học có khả năng:
·         Tìm hiểu bài toán và dữ liệu
·         Cài đặt thuật toán Gradient descent
·         Sử dụng thư viện scikit-learn 

6.1 Bài toán và dữ liệu

Trong bài này chúng ta sẽ tìm hiểu dữ liệu được thu thập có 2 biến độc lập là: diện tích của ngôi nhà (Size - tính bằng feet2), cùng số phòng ngủ (Bedrooms); và một biến phụ thuộc đó là giá của ngôi nhà (Price – tính bằng USD) tương ứng được bán (dữ liệu lấy từ [1], có thể download từ [2]). Người ta muốn đoán giá của ngôi nhà thông qua thông tin thu thập được: diện tích và số phòng ngủ.
Chương trình 6.1 không khác ở Bài 5, ngoại trừ dòng 04 và 05:
01. import pandas as pd
02. import numpy as np
03. import os
04. from matplotlib import pyplot
05. duongDan = os.getcwd() + '\data\ex1data2.txt'
06. tenCot = ['Size', 'Bedrooms', 'Price']
07. duLieu = pd.read_csv(duongDan, names= tenCot)
08. print (duLieu.shape)
09. print (duLieu.head())
Chương trình 6.1

Thông tin dữ liệu chúng ta có được như sau:
(47, 3)
   Size  Bedrooms   Price
0  2104     3      399900
1  1600     3      329900
2  2400     3      369000
3  1416     2      232000
4  3000     4      539900

Vậy chúng ta biết dữ liệu gồm có 47 hàng và 3 cột (Size, Bedrooms, và Price). Chúng ta cũng biết thêm rằng giá trị trên cột Bedrooms rất khác so với các giá trị trên cột Size, và cả hai cột đầu có giá trị rất khác so với cột Price. 
duLieu.plot(kind='box', subplots=True, layout=(2,2), sharex=False, sharey=False)
pyplot.show()

Chúng ta có biểu đồ (giống như Hình 6.1)
 
Hình 6.1 Đồ thị dữ liệu cho diện tích, số phòng
ngủ và giá của một ngôi nhà.

Chúng ta thấy khoảng giá trị của từng cột là rất khác nhau, với dữ liệu cột Bedrooms ở trong đoạn [1,5], với cột Size khoảng từ 800 tới 3200, với cột Price trong khoảng từ 170.000 tới 580.000.
Chính vì sự khác biệt lớn này, nên nếu chúng ta không xử lý dữ liệu, thuật toán sẽ gặp vấn đề lớn.

6.2 Thuật toán Gradient descent

Chương trình không khác gì ở Bài 5, ngoại trừ chúng ta cho số lần lặp là soLanLap = 10:
01. maTran = duLieu.values
02. m,n = maTran.shape
03. X_cacCot = maTran[:,0:n-1]
04. X = np.insert(X_cacCot, 0, values = 1, axis = 1)
05. y = maTran[:,n-1:n]
06. print X[:5]
07. print y[:5]
08. theta = np.zeros((1, X.shape[1]))
09. print theta
10. print X.shape, y.shape, theta.shape

11. def h_X(X, theta):
12.     return np.dot(X, theta.T)

13. def computeCost(X, y, theta):
14.     saiSo = np.power((h_X(X, theta) - y),2)
15.     J = (1.0/(2 * m)) * np.sum(saiSo)
16.     return J

17. print computeCost(X, y, theta)

18. def gradientDescent(X, y, theta, alpha, soLanLap):
01.     theta_tam = np.zeros(theta.shape)
19.     heso_Theta = theta.shape[1]
20.     J_tam = np.zeros(soLanLap)
21.     for i in range(soLanLap):
22.         saiSo = h_X(X,theta) - y
23.         for j in range(heso_Theta):
24.             X_ij = np.reshape(X[:, j],(len(X),1))
25.             term = np.multiply(saiSo, X_ij)
26.             theta_tam[0, j] = theta[0, j] - ((alpha / len(X)) * np.sum(term))
27.         theta = theta_tam
28.         J_tam[i] = computeCost(X, y, theta)
29.     return theta, J_tam

30. alpha = 0.01
31. soLanLap = 10
32. theta_sauCung, J_chiphi = gradientDescent(X, y, theta, alpha, soLanLap)
33. print theta_sauCung
34. print J_chiphi[-1]
Chương trình 6.2
Khi chạy chương trình 6.2 sẽ cho kết quả:
[[   1 2104    3]
 [   1 1600    3]
 [   1 2400    3]
 [   1 1416    2]
 [   1 3000    4]]
[[399900]
 [329900]
 [369000]
 [232000]
 [539900]]
[[ 0.  0.  0.]]
(47, 3) (47, 1) (1, 3)
65591548106.5
[[ -3.17739580e+45 -7.33861634e+48  -1.05993953e+46]]
1.24428862154e+104
Kết quả lần lượt in ra 5 dòng đầu của X, y, theta (khởi tạo) cùng kích thước của chúng. Thật đáng ngạc nhiên khi dòng 17 cho kết quả một con số rất lớn. Với giá trị khởi tạo, hàm chi phí của chúng ta lên tới xấp xỉ 65 tỉ. Và sau 10 vòng lặp, trị giá của theta một con số không tưởng, và hàm chi phí khoảng 1.24.10104.
Chúng ta có thể cho rằng do hệ số theta chưa hội tụ sau số lần lặp ít như vậy. Tuy nhiên khi càng tăng số lần lặp lên, con số dự đoán lại càng lớn hơn. Khi thử với soLanLap từ 50 trở đi, giá trị dự đoán vượt cả giới hạn số mà Python sử dụng.
Nguyên nhân vì sao? Như chúng ta đã quan sát dữ liệu ở phần 6.1: có sự chênh lệch rất lớn giữa giá trị và tỉ lệ giữa các cột. Chính điều này làm thuật toán của chúng ta không hội tụ (càng lặp nhiều, càng phân tán).
 Vậy thì ta cần điều chuẩn hóa dữ liệu. Trong bài này ta dùng kĩ thuật chuẩn hóa dữ liệu Standardization. Bằng cách thêm vào dòng lệnh:
duLieu = (duLieu - duLieu.mean())/duLieu.std()
 vào trước dòng lệnh 01 trong Chương trình 6.2 trên. Sau đó chạy chương trình thì kết quả in ra sẽ là (với soLanLap = 1000):
[[ 1.          0.13000987 -0.22367519]
 [ 1.         -0.50418984 -0.22367519]
 [ 1.          0.50247636 -0.22367519]
 [ 1.         -0.73572306 -1.53776691]
 [ 1.          1.25747602  1.09041654]]
[[ 0.47574687]
 [-0.08407444]
 [ 0.22862575]
 [-0.86702453]
 [ 1.59538948]]
[[ 0.  0.  0.]]
(47, 3) (47, 1) (1, 3)
0.489361702128
[[ -1.10963248e-16   8.78503652e-01  -4.69166570e-02]]
0.130703369608
Như chúng ta thấy, giá trị của theta ở ngưỡng phù hợp (θ  = [θ0  θθ2] = [0  0.8785  -0.0469]), và chi phí sau 1000 lần lặp là 0.131.
Chúng ta sử dụng lại Chương trình 5.5, ta sẽ có đồ thị của hàm chi phí ứng với số lần lăp:

Hình 6.2 Hàm chi phí biến đổi sau các bước lặp của thuật toán.
Nhìn vào đồ thị chúng ta thấy rằng không có sự thay đổi nhiều từ bước lặp 500 trở đi. Nói một cách khác, sau 500 vòng lặp, theta của chúng ta đã hội tụ.
Và khi chúng ta thay soLanLap = 500 thì kết quả cho theta và hàm chi phí là:
[[ -1.24238681e-16   8.30383883e-01   8.23982853e-04]]
0.131951337758
Kết quả rất gần với kết quả sau 1000 lặp ở phía trên.

6.3 Kết luận

Cần bổ sung vào đây.

Bài tập:
Bạn thử áp dụng các kĩ thuật điều chỉnh dữ liệu khác trong Bài 4 để áp dụng vào Bài 6 này xem kết quả khác nhau như thế nào?

Tài liệu tham khảo:


2.    https://github.com/alexband/ml-class/blob/master/mlclass-ex1/ex1data2.txt

0 nhận xét: