Lựa chọn mô hình và giải thuật phù hợp
Tới đây, bạn đã có những ấn tượng, những cảm nhận ban đầu về
dữ liệu. Tuy nhiên, yêu cầu đặt ra cho ứng dụng này là chúng ta phải dự báo “khi
nào thì số lượng truy cập sẽ chạm ngưỡng 100 000 lần/giờ? hay dự báo khi nào sẽ
phải nâng cấp hệ thống?”
Để trả lời câu hỏi này, cần phải giải quyết hai vấn đề sau:
- Tìm
ra mô hình phù hợp dựa trên các dữ liệu đã quan sát được. (Nói nôm na là tìm ra
được một biểu thức thể hiện mối liên hệ giữa x và y).
- Sử
dụng mô hình để dự báo: thời điểm nào thì số lượng truy cập sẽ chạm ngưỡng 100
000 lần/giờ?
Khi nói về mô hình (model), bạn có thể nghĩ đến một mô phỏng
của thế giới thật, tất nhiên, nó mang tính giả định và đã được đơn giản hóa. Mô
hình luôn luôn có độ sai khác so với thực tế, còn được gọi là sai số xấp xỉ
(approximate error). Sai số xấp xỉ chính
là một tiêu chí giúp chúng ta đánh giá được mô hình nào là phù hợp với bài
toán. Sai số xấp xỉ được tính bằng bình phương khoảng cách (squared distance)
giữa dữ liệu thật (quan sát được) và kết quả dự báo của mô hình.
Giả sử f là hàm số của mô hình, để tính sai số, chúng ta
định nghĩa hàm error để tính sai số như sau:
Def error (f, x, y):
return sp.sum((f(x) – y ** 2)
Trong đó, x và y là hai vector chứa dữ liệu (x: giờ, y: số
lần truy cập) đã quan sát được; f là hàm số chúng ta đã rút trích được từ dữ
liệu, đó chính là hàm mô phỏng mối liên hệ giữa x và y.
Bắt đầu với mô hình đường thẳng đơn giản
Giả sử mô hình cho bài toán chúng ta đang xem xét là một
đường thẳng, viết dưới dạng biểu thức (hàm số) sẽ là y = ax + b. Khi đó, vấn đề
cần quan tâm tiếp theo là sẽ đặt đường thẳng này theo vị trí nào để sai số xấp
xỉ là nhỏ nhất. Hàm polyfit() của
SciPy sẽ giúp bạn thực hiện điều này.
Với dữ liệu đầu vào là các giá trị đã quan sát được của x,
y, cộng với bậc của đa thức cần tìm (vì là đường thẳng, nên bậc của đa thức là
bậc 1), hàm polyfit() sẽ tìm ra được
hàm số của mô hình, với sai số xấp xỉ là nhỏ nhất.
Cú pháp của hàm polyfit():
fp1, residuals, rank, sv, rcond = sp.polyfit(x, y, 1, full = True)
Hàm polyfit() sẽ
trả về các tham số của hàm fp1; với tham
số full = True, hàm polyfit() cũng sẽ
cung cấp thêm cho chúng ta các thông tin liên quan khác. Trong các thông tin
liên quan khác, bạn sẽ quan tâm tới giá trị của residuals, đây là sai số giữa các giá trị y quan sát và các giá trị
y dự báo của mô hình.
Chạy thử trên SciPy:
In [1]:
import scipy as sp
In [2]:
data = sp.genfromtxt("D:\Liv\Re\Ebooks\ML\web_traffic.tsv",
delimiter="\t")
In [3]: x = data[:,0]
In [4]: y = data[:,1]
In [5]:
x = x[~sp.isnan(y)]
In [6]: y = y[~sp.isnan(y)]
In [7]:
fp1, residuals, rank, sv, rcond = sp.polyfit(x, y, 1, full = True)
In [8]:
print ("Cac tham so cua mo hinh: %s" % fp1)
Cac tham so cua mo hinh: [ 2.59619213 989.02487106]
In [10]:
print(residuals)
[ 3.17389767e+08]
Vậy hàm số (hay đường thẳng) chúng ta cần tìm có dạng:
y = f(x) = 2.59619213*
x + 989.02487106
Dựa vào các tham số trả về của polyfit(), sử dụng hàm poly1d()
của SciPy để tạo ra hàm số của mô hình.
In [11]: f1 = sp.poly1d(fp1)
Định nghĩa hàm error (), để tính và xuất sai số xấp xỉ của hàm số mô hình.
In [14]:
def error(f, x, y):return sp.sum((f(x) - y)**2)
In [15]:
print (error(f1, x, y))
317389767.34
Chúng ta sẽ biểu diễn dữ liệu đã quan sát và mô hình đường
thẳng vừa tìm được.
Đầu tiên, chúng ta sẽ biểu diễn dữ liệu đã quan sát dưới
dạng đồ thị không gian hai chiều (xem lại bài viết số 2).
Tiếp theo, chúng ta thực hiện vẽ đường thẳng của mô hình.
In [25]:
fx = sp.linspace(0, x[-1], 1000) # tao cac gia tri tren truc X
In [26]:
plt.plot(fx, f1(fx), linewidth=4)
Out[26]:
[<matplotlib.lines.Line2D at 0x66d7890>]
In [27]:
plt.legend(["Bac = %i" % f1.order], loc = "upper left")
Out[27]:
<matplotlib.legend.Legend at 0x66d7eb0>
Kết quả:
Quan sát đường thẳng trên đồ thị, bạn sẽ nhận thấy bước sang
tuần thứ năm thì mô hình đã thể hiện sai rất nhiều so với quan sát thực tế.
Ngoài ra, với sai số xấp xỉ là 317389767,34, bạn cũng không biết là nó có phải
là một mô hình phù hợp nhất hay không?
Giá trị tuyệt đối của sai số rất ít khi được sử dụng riêng
biệt. Tuy nhiên, khi thực hiện so sánh giữa hai mô hình, thì bạn có thể sử dụng
nó để đánh giá xem mô hình nào phù hợp hơn.
Mặc dù chúng ta sẽ không sử dụng mô hình đường thẳng này để
dự đoán, nhưng nó sẽ là mô hình xuất phát, làm cơ sở để chúng ta tìm các mô
hình khác phù hợp hơn. Các mô hình chúng ta tìm ra sau này sẽ được so sánh với
mô hình xuất phát.
Tăng thêm độ phức tạp của mô hình
Chúng ta sẽ chọn một mô hình khác phức tạp hơn, đó là một đa
thức bậc 2. Chúng ta sẽ xem đa thức bậc 2 này có mô phỏng dữ liệu tốt hơn hay
không.
Hàm số bậc 2 có dạng: y = ax**2 + bx + c.
Rút trích hàm số bậc 2 từ dữ liệu quan sát:
In [28]: f2p = sp.polyfit(x, y, 2)
Xuất kết quả:
In [29]:
print(f2p)
[ 1.05322215e-02 -5.26545650e+00 1.97476082e+03]
Vậy hàm số bậc 2 rút trích được là:
y = f(x) = 0,0105322215*x**2 - 5.26545650*x + 1974,76082
Sai số xấp xỉ của hàm số:
In [30]:
f2=sp.poly1d(f2p)
In [31]:
print(error(f2, x, y))
179983507.878
Vẽ đồ thị của hàm số bậc 2 (đường nét đứt, màu đỏ):
Để đỡ phải gõ lại các dòng lệnh, bạn có thể viết riêng đoạn
mã vẽ đồ thị. Để thực hiện, bạn chạy phần mềm Enthought Canopy, chọn Editor,
chọn Create a new file, nhập vào đoạn mã cần thực thi, lưu lại, bấm Run\Run
file để xem kết quả.
import scipy as sp
import matplotlib.pyplot as plt
#
Nhap du lieu tu tap tin
data =
sp.genfromtxt("D:\Liv\Re\Ebooks\ML\web_traffic.tsv",
delimiter="\t")
#
Tao hai vector du lieu
x
= data[:,0]
y
= data[:,1]
#
Loai bo cac gia tri NAN
x
= x[~sp.isnan(y)]
y
= y[~sp.isnan(y)]
# tao cac gia tri tren truc X cho cac mo
hinh
fx = sp.linspace(0, x[-1], 1000)
# Chuan bi ve duong 1
fp1 = sp.polyfit(x, y, 1)
f1 = sp.poly1d(fp1)
plt.plot(fx, f1(fx), label = 'Bac = 1',
linewidth=4)
#
Chuan bi ve duong 2
fp2
= sp.polyfit(x, y, 2)
f2
= sp.poly1d(fp2)
plt.plot(fx,
f2(fx), 'r--', label = 'Bac = 2', linewidth=4)
#
Hien thi ket qua
plt.scatter(x,y)
plt.title("Luu luong truy cap
web")
plt.xlabel("Thoi gian")
plt.ylabel("Truy cap/gio")
plt.xticks([w*7*24 for w in range(5)],['Tuan
%i'%(w+1) for w in range(5)])
plt.autoscale(tight=True)
plt.grid()
plt.legend(loc='upper left')
plt.show()
Kết quả:
--------------------------
Tham khảo (lược dịch)
Willi Richert, Luis Pedro Coelho, Building Machine Learning Systems with Python, PACKT publishing,
2013
--------------------------
Cập nhật (2015/2/3)
--------------------------
Đọc thêm
Hoc may voi Python (4)