Hoc may voi Python (2)

(Tiếp theo của học máy với Python 1)



Xử lý tình trạng thiếu dữ liệu

Khi đọc dữ liệu từ tập tin dạng văn bản (text), sẽ xảy ra tình trạng có những chỗ dữ liệu không hợp lệ. Trong trường hợp đó, NumPy cho phép đánh dấu chỗ dữ liệu bị thiếu bằng kí hiệu numpy.NAN.

In [3]: c = np.array([1,2,np.NAN,3,4]) # giả sử dữ liệu này vừa được nhập từ tập tin dữ liệu
In [4]: c
Out[4]: array([ 1., 2., nan, 3., 4.])
In [5]: np.isnan(c) # kiểm tra phần tử chứa giá trị NAN
Out[5]: array([False, False, True, False, False], dtype=bool)
In [6]: c[~np.isnan(c)] # mảng các phần tử không bao gồm NAN
Out[6]: array([ 1., 2., 3., 4.])
In [7]: np.mean(c[~np.isnan(c)]) # mean( ): hàm tính giá trị trung bình
Out[7]: 2.5s

So sánh thời gian xử lý

Ví dụ sau thực hiện so sánh thời gian xử lý giữa NumPy và Python. Nội dung công việc là tính tổng bình phương các số từ 1 tới 1000, thực hiện 10000 lần và đo tổng thời gian cần thiết để thực hiện.

In [1]: import timeit
In [2]: normal_py_sec = timeit.timeit('sum(x*x for x in xrange (1000))', number=10000)
In [4]: naive_np_sec = timeit.timeit('sum(na*na)',setup="import numpy as np; na = np.arange(1000)",number = 10000)
In [5]: good_np_sec = timeit.timeit('na.dot(na)',setup="import numpy as np; na = np.arange(1000)", number = 10000)
In [6]: print("Normal Python: %f sec"%normal_py_sec)
Normal Python: 1.874073 sec
In [7]: print("Naive Numpy: %f sec"%naive_np_sec)
Naive Numpy: 6.491387 sec
In [8]: print("Good Numpy: %f sec"%good_np_sec)
Good Numpy: 0.094852 sec

Nếu sử dụng Python, thời gian xử lý là 1,874073 giây.

Nếu sử dụng NumPy với vai trò là thành phần lưu trữ dữ liệu (Naïve NumPy), thì thời gian xử lý là 6,491387 giây, chậm hơn 3,5 lần so với sử dụng Python.

Nếu sử dụng hàm dot() của Numpy, đây là hàm đã được tối ưu của NumPy, thì thời gian xử lý là 0,094852 giây, nhanh hơn 20 lần so với sử dụng Python.

Vì vậy, trong một số trường hợp, nên sử dụng các hàm đã được tối ưu trong NumPy hoặc SciPy để tăng tốc độ xử lý của hệ thống.

Tuy nhiên, kiểu dữ liệu mảng (array) trong NumPy lại không linh hoạt bằng kiểu dữ liệu danh sách (list) trong Python. Mảng trong NumPy chỉ chứa được một kiểu dữ liệu, trong khi danh sách trong Python có thể chứa nhiều kiểu dữ liệu.

In [9]: a = np.array([1,2,3])
In [10]: a.dtype
Out[10]: dtype('int32')

Nếu có nhiều kiểu dữ liệu trong mảng, NumPy sẽ cố gắng chuyển tất cả về một kiểu dữ liệu hợp lý nhất. Ví dụ:

In [11]: import numpy as np
In [12]: np.array([1,"string"])
Out[12]:
array(['1', 'string'], dtype='|S6')

Số 1 đã được chuyển thành kiểu kí tự ‘1’.

In [13]: np.array([1, "stringy", set([1,2,3])])
Out[13]: array([1, 'stringy', set([1, 2, 3])], dtype=object)

Số 1 và chuỗi ‘stringy’ đã được chuyển thành kiểu đối tượng (object).

 

Làm quen với SciPy


SciPy cung cấp các giải thuật hiệu quả trên kiểu dữ liệu mảng của NumPy.

SciPy hỗ trợ các tính toán liên quan đến: tính toán trên ma trận, đại số tuyến tính, tối ưu, clustering, spatial operation, biến đổi Fast Fourier.

Có thể sử dụng tất cả các chức năng của NumPy thông qua SciPy.

Bảng sau là các gói SciPy phổ biến:

Gói SciPy
Chức năng
Cluster

Constants

Fftpack

Integrate

Interpolate

Io
Nhập, xuất dữ liệu
Linalg

Maxentropy

Ndimage

Odr

Optimize

Signal

Sparse

Spatial

Special

Stats
Bộ công cụ về thống kê

 

Ứng dụng máy học đầu tiên


Giả sử bạn có một website bán hàng, bạn đã thiết lập hạ tầng để có thể đáp ứng số lượng truy cập là 100 000 lần/giờ.

Để theo dõi tình trạng hoạt động của hệ thống, bạn thực hiện đếm và ghi lại số lần truy cập website theo từng giờ.

Dựa vào thông tin theo dõi, bạn sẽ 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?

 

Đọc dữ liệu


Dữ liệu theo dõi số lần truy cập theo từng giờ được lưu trong tập tin dạng .tsv.

TSV (tab-separated values): là tập tin dạng văn bản, được sử dụng để lưu dữ liệu có cấu trúc bảng, trong đó mỗi hàng của bảng được lưu trên một dòng, mỗi trường dữ liệu trên một dòng được ngăn cách bởi một khoảng tab (hay kí tự tab).


Bấm Ctrl + A để chọn toàn bộ dữ liệu, bấm Ctrl + C để copy dữ liệu, mở chương trình Notepad, bấm Ctrl + V để dán dữ liệu vào Notepad.

Bấm vào mục File của Notepad, chọn Save, tại mục File name nhập tên cho tập tin, nhớ để tất cả trong dấu nháy kép, ví dụ “web_traffic.tsv”.

Một phần của tập tin dữ liệu web_traffic.tsv được thể hiện ở hình sau:



Dữ liệu gồm hai cột, cột đầu tiên là giờ, cột thứ hai là số lượt truy cập tương ứng. Tất cả gồm 743 hàng.

Sử dụng hàm genfromtxt () của SciPy để đọc dữ liệu.

In [1]: import scipy as sp
In [2]: data = sp.genfromtxt("D:\Liv\Re\Ebooks\ML\web_traffic.tsv", delimiter="\t")

Xuất thử dữ liệu để kiểm tra, ví dụ xuất 10 hàng đầu tiên.

In [3]: print(data[:10])
[[ 1.00000000e+00 2.27200000e+03]
[ 2.00000000e+00 nan]
[ 3.00000000e+00 1.38600000e+03]
[ 4.00000000e+00 1.36500000e+03]
[ 5.00000000e+00 1.48800000e+03]
[ 6.00000000e+00 1.33700000e+03]
[ 7.00000000e+00 1.88300000e+03]
[ 8.00000000e+00 2.28300000e+03]
[ 9.00000000e+00 1.33500000e+03]
[ 1.00000000e+01 1.02500000e+03]]

Xem định dạng dữ liệu:

In [4]: print (data.shape)

(743, 2)
Dữ liệu gồm 743 hàng, 2 cột.

 

Tiền xử lý và làm sạch dữ liệu


Để tiện xử lý trên SciPy, tạo hai vector ứng với hai chiều của dữ liệu, mỗi vector có kích thước 743. Vector x ứng với số giờ, và vector y ứng với số lần truy cập/giờ tương ứng.
In [5]: x = data[:,0]
In [6]: y = data[:,1]
Quan sát giá trị của y, sẽ thấy có một số giá trị không hợp lệ, chứa giá trị “nan”.
Tổng số giá trị không hợp lệ của y là: 8
In [7]: sp.sum(sp.isnan(y))
Out[7]: 8
Loại bỏ các hàng chứa giá trị không hợp lệ, cụ thể sẽ bỏ đi 8 hàng trong tổng số 743 hàng.
In [8]: x = x[~sp.isnan(y)]
In [9]: y = y[~sp.isnan(y)]
Biểu diễn dữ liệu dưới dạng đồ thị không gian hai chiều.
Sử dụng gói pyplot của Matplotlib.
In [11]: import matplotlib.pyplot as plt
In [12]: plt.scatter(x,y)
Out[12]: <matplotlib.collections.PathCollection at 0x6ad9df0>
In [13]: plt.title("Luu luong truy cap web")
Out[13]: <matplotlib.text.Text at 0x6ab4130>
In [15]: plt.xlabel("Thoi gian")
Out[15]: <matplotlib.text.Text at 0x6a90c70>
In [16]: plt.ylabel("Truy cap/gio")
Out[16]: <matplotlib.text.Text at 0x6a9ac10>
In [20]: plt.xticks([w*7*24 for w in range(5)],['Tuan %i'%(w+1) for w in range(5)])
Out[20]:
([<matplotlib.axis.XTick at 0x6aa3bf0>,
<matplotlib.axis.XTick at 0x6a9aa70>,
<matplotlib.axis.XTick at 0x472f790>,
<matplotlib.axis.XTick at 0x6ad62b0>,
<matplotlib.axis.XTick at 0x6ad65f0>],
<a list of 5 Text xticklabel objects>)
In [22]: plt.autoscale(tight=True)
In [23]: plt.grid()
In [24]: plt.show()
Đồ thị 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/1/27)
--------------------------
Đọc thêm