вторник, 3 сентября 2019 г.

Machine Learning cơ bản

Bài 10: Logistic Regression. Trong trang này: 1. Giới thiệu. Nhắc lại hai mô hình tuyến tính. Hai mô hình tuyến tính (linear models) Linear Regression và Perceptron Learning Algorithm (PLA) chúng ta đã biết đều có chung một dạng: \[ y = f(\mathbf ^T\mathbf ) \] trong đó \(f()\) được gọi là activation function , và \(\mathbf \) được hiểu là dữ liệu mở rộng với \(x_0 = 1\) được thêm vào để thuận tiện cho việc tính toán. Với linear regression thì \(f(s) = s\), với PLA thì \(f(s) = \text (s)\). Trong linear regression, tích vô hướng \(\mathbf ^T\mathbf \) được trực tiếp sử dụng để dự đoán output \(y\), loại này phù hợp nếu chúng ta cần dự đoán một giá trị thực của đầu ra không bị chặn trên và dưới. Trong PLA, đầu ra chỉ nhận một trong hai giá trị \(1\) hoặc \(-1 \), phù hợp với các bài toán binary classification . Trong bài này, tôi sẽ giới thiệu mô hình thứ ba với một activation khác, được sử dụng cho các bài toán flexible hơn. Trong dạng này, đầu ra có thể được thể hiện dưới dạng xác suất (probability). Ví dụ: xác suất thi đỗ nếu biết thời gian ôn thi, xác suất ngày mai có mưa dựa trên những thông tin đo được trong ngày hôm nay,… Mô hình mới này của chúng ta có tên là logistic regression . Mô hình này giống với linear regression ở khía cạnh đầu ra là số thực, và giống với PLA ở việc đầu ra bị chặn (trong đoạn \([0, 1]\)). Mặc dù trong tên có chứa từ regression , logistic regression thường được sử dụng nhiều hơn cho các bài toán classification. Một ví dụ nhỏ. Một nhóm 20 sinh viên dành thời gian trong khoảng từ 0 đến 6 giờ cho việc ôn thi. Thời gian ôn thi này ảnh hưởng đến xác suất sinh viên vượt qua kỳ thi như thế nào? Kết quả thu được như sau: Mặc dù có một chút bất công khi học 3.5 giờ thì trượt, còn học 1.75 giờ thì lại đỗ, nhìn chung, học càng nhiều thì khả năng đỗ càng cao. PLA không thể áp dụng được cho bài toán này vì không thể nói một người học bao nhiêu giờ thì 100% trượt hay đỗ, và thực tế là dữ liệu này cũng không linearly separable (điệu kiện để PLA có thể làm việc). Chú ý rằng các điểm màu đỏ và xanh được vẽ ở hai tung độ khác nhau để tiện cho việc minh họa. Các điểm này được vẽ dùng cả dữ liệu đầu vào \(\mathbf \) và đầu ra \(y). Khi ta nói linearly seperable là khi ta chỉ dùng dữ liệu đầu vào \(\mathbf \). Chúng ta biểu diễn các điểm này trên đồ thị để thấy rõ hơn: Nhận thấy rằng cả linear regression và PLA đều không phù hợp với bài toán này, chúng ta cần một mô hình flexible hơn. Mô hình Logistic Regression. Đầu ra dự đoán của: Linear Regression: \[ f(\mathbf ) = \mathbf ^T \mathbf \] PLA: \[ f(\mathbf ) = \text (\mathbf ^T\mathbf ) \] Đầu ra dự đoán của logistic regression thường được viết chung dưới dạng: \[ f(\mathbf ) = \theta(\mathbf ^T\mathbf ) \] Trong đó \(\theta\) được gọi là logistic function. Một số activation cho mô hình tuyến tính được cho trong hình dưới đây: Đường màu vàng biểu diễn linear regression. Đường này không bị chặn nên không phù hợp cho bài toán này. Có một trick nhỏ để đưa nó về dạng bị chặn: cắt phần nhỏ hơn 0 bằng cách cho chúng bằng 0, cắt các phần lớn hơn 1 bằng cách cho chúng bằng 1. Sau đó lấy điểm trên đường thẳng này có tung độ bằng 0.5 làm điểm phân chia hai class , đây cũng không phải là một lựa chọn tốt. Giả sử có thêm vài bạn sinh viên tiêu biểu ôn tập đến 20 giờ và, tất nhiên, thi đỗ. Khi áp dụng mô hình linear regression như hình dưới đây và lấy mốc 0.5 để phân lớp, toàn bộ sinh viên thi trượt vẫn được dự đoán là trượt, nhưng rất nhiều sinh viên thi đỗ cũng được dự đoán là trượt (nếu ta coi điểm x màu xanh lục là ngưỡng cứng để đưa ra kết luận). Rõ ràng đây là một mô hình không tốt. Anh chàng sinh viên tiêu biểu này đã kéo theo rất nhiều bạn khác bị trượt. Đường màu đỏ (chỉ khác với activation function của PLA ở chỗ hai class là 0 và 1 thay vì -1 và 1) cũng thuộc dạng ngưỡng cứng (hard threshold). PLA không hoạt động trong bài toán này vì dữ liệu đã cho không linearly separable . Các đường màu xanh lam và xanh lục phù hợp với bài toán của chúng ta hơn. Chúng có một vài tính chất quan trọng sau: Là hàm số liên tục nhận giá trị thực, bị chặn trong khoảng \((0, 1)\). Nếu coi điểm có tung độ là 1/2 làm điểm phân chia thì các điểm càng xa điểm này về phía bên trái có giá trị càng gần 0. Ngược lại, các điểm càng xa điểm này về phía phải có giá trị càng gần 1. Điều này khớp với nhận xét rằng học càng nhiều thì xác suất đỗ càng cao và ngược lại. Mượt (smooth) nên có đạo hàm mọi nơi, có thể được lợi trong việc tối ưu. Sigmoid function. Trong số các hàm số có 3 tính chất nói trên thì hàm sigmoid : \[ f(s) = \frac > \triangleq \sigma(s) \] được sử dụng nhiều nhất, vì nó bị chặn trong khoảng \((0, 1)\). Thêm nữa: \[ \lim_ \sigma(s) = 0; \lim_ \sigma(s) = 1 \] Đặc biệt hơn nữa: \[ \begin \sigma’(s) &=& \frac > )^2> \\ &=& \frac > \frac > > \\ &=& \sigma(s)(1 - \sigma(s)) \end \] Công thức đạo hàm đơn giản thế này giúp hàm số này được sử dụng rộng rãi. Ở phần sau, tôi sẽ lý giải việc người ta đã tìm ra hàm số đặc biệt này như thế nào . Ngoài ra, hàm tanh cũng hay được sử dụng: \[ \text (s) = \frac - e^ > > \] Hàm số này nhận giá trị trong khoảng \((-1, 1)\) nhưng có thể dễ dàng đưa nó về khoảng \((0, 1)\). Bạn đọc có thể chứng minh được: \[ \text (s) = 2\sigma(2s) - 1 \] 2. Hàm mất mát và phương pháp tối ưu. Xây dựng hàm mất mát. Với mô hình như trên (các activation màu xanh lam và lục), ta có thể giả sử rằng xác suất để một điểm dữ liệu \(\mathbf \) rơi vào class 1 là \(f(\mathbf ^T\mathbf )\) và rơi vào class 0 là \(1 - f(\mathbf ^T\mathbf )\). Với mô hình được giả sử như vậy, với các điểm dữ liệu training (đã biết đầu ra \(y\)), ta có thể viết như sau: \[ \begin P(y_i = 1 | \mathbf _i; \mathbf ) &=& &f(\mathbf ^T\mathbf _i) (1) \\ P(y_i = 0 | \mathbf _i; \mathbf ) &=& 1 - &f(\mathbf ^T\mathbf _i) (2) \\ \end \] trong đó \( P(y_i = 1 | \mathbf _i; \mathbf )\) được hiểu là xác suất xảy ra sự kiện đầu ra \(y_i = 1\) khi biết tham số mô hình \(\mathbf \) và dữ liệu đầu vào \(\mathbf _i\). Bạn đọc có thể đọc thêm Xác suất có điều kiện. Mục đích của chúng ta là tìm các hệ số \(\mathbf \) sao cho \(f(\mathbf ^T\mathbf _i)\) càng gần với 1 càng tốt với các điểm dữ liệu thuộc class 1 và càng gần với 0 càng tốt với những điểm thuộc class 0. Ký hiệu \(z_i = f(\mathbf ^T\mathbf _i)\) và viết gộp lại hai biểu thức bên trên ta có: \[ P(y_i| \mathbf _i; \mathbf ) = z_i^ (1 - z_i)^ \] Biểu thức này là tương đương với hai biểu thức \((1)\) và \((2)\) ở trên vì khi \(y_i=1\), phần thứ hai của vế phải sẽ triệt tiêu, khi \(y_i = 0\), phần thứ nhất sẽ bị triệt tiêu! Chúng ta muốn mô hình gần với dữ liệu đã cho nhất, tức xác suất này đạt giá trị cao nhất. Xét toàn bộ training set với \(\mathbf = [\mathbf _1,\mathbf _2, \dots, \mathbf _N] \in \mathbb ^ \) và \(\mathbf = [y_1, y_2, \dots, y_N]\), chúng ta cần tìm \(\mathbf \) để biểu thức sau đây đạt giá trị lớn nhất: \[ P(\mathbf |\mathbf ; \mathbf ) \] ở đây, ta cũng ký hiệu \(\mathbf \) như các biến ngẫu nhiên (random variables). Nói cách khác: \[ \mathbf = \arg\max_ > P(\mathbf |\mathbf ; \mathbf ) \] Bài toán tìm tham số để mô hình gần với dữ liệu nhất trên đây có tên gọi chung là bài toán maximum likelihood estimation với hàm số phía sau \(\arg\max\) được gọi là likelihood function . Khi làm việc với các bài toán Machine Learning sử dụng các mô hình xác suất thống kê, chúng ta sẽ gặp lại các bài toán thuộc dạng này, hoặc maximum a posteriori estimation , rất nhiều. Tôi sẽ dành 1 bài khác để nói về hai dạng bài toán này. Giả sử thêm rằng các điểm dữ liệu được sinh ra một cách ngẫu nhiên độc lập với nhau (independent), ta có thể viết: \[ \begin P(\mathbf |\mathbf ; \mathbf ) &=& \prod_ ^N P(y_i| \mathbf _i; \mathbf ) \\ &=& \prod_ ^N z_i^ (1 - z_i)^ \end \] với \(\prod\) là ký hiệu của tích. Bạn đọc có thể muốn đọc thêm về Độc lập thống kê. Trực tiếp tối ưu hàm số này theo \(\mathbf \) nhìn qua không đơn giản! Hơn nữa, khi \(N\) lớn, tích của \(N\) số nhỏ hơn 1 có thể dẫn tới sai số trong tính toán (numerial error) vì tích là một số quá nhỏ. Một phương pháp thường được sử dụng đó là lấy logarit tự nhiên (cơ số \(e\)) của likelihood function biến phép nhân thành phép cộng và để tránh việc số quá nhỏ. Sau đó lấy ngược dấu để được một hàm và coi nó là hàm mất mát. Lúc này bài toán tìm giá trị lớn nhất (maximum likelihood) trở thành bài toán tìm giá trị nhỏ nhất của hàm mất mát (hàm này còn được gọi là negative log likelihood): \[ \begin J(\mathbf ) = -\log P(\mathbf |\mathbf ; \mathbf ) \\ = -\sum_ ^N(y_i \log _i + (1-y_i) \log (1 - _i)) \end \] với chú ý rằng \(z_i\) là một hàm số của \(\mathbf \). Bạn đọc tạm nhớ biểu thức vế phải có tên gọi là cross entropy , thường được sử dụng để đo khoảng cách giữa hai phân phối (distributions). Trong bài toán đang xét, một phân phối là dữ liệu được cho, với xác suất chỉ là 0 hoặc 1; phân phối còn lại được tính theo mô hình logistic regression. Khoảng cách giữa hai phân phối nhỏ đồng nghĩa với việc ( có vẻ hiển nhiên là ) hai phân phối đó rất gần nhau. Tính chất cụ thể của hàm số này sẽ được đề cập trong một bài khác mà tầm quan trọng của khoảng cách giữa hai phân phối là lớn hơn. Chú ý: Trong machine learning, logarit thập phân ít được dùng, vì vậy \(\log\) thường được dùng để ký hiệu logarit tự nhiên. Tối ưu hàm mất mát. Chúng ta lại sử dụng phương pháp Stochastic Gradient Descent (SGD) ở đây ( Bạn đọc được khuyến khích đọc SGD trước khi đọc phần này ) . Hàm mất mát với chỉ một điểm dữ liệu \((\mathbf _i, y_i)\) là: \[ J(\mathbf ; \mathbf _i, y_i) = -(y_i \log _i + (1-y_i) \log (1 - _i)) \] Để cho biểu thức này trở nên gọn và đẹp hơn, chúng ta sẽ tìm hàm \(z = f(\mathbf ^T\mathbf )\) sao cho mẫu số bị triệt tiêu. Nếu đặt \(s = \mathbf ^T\mathbf \), chúng ta sẽ có: \[ \frac > = \frac \frac > = \frac \mathbf \] Một cách trực quan nhất, ta sẽ tìm hàm số \(z = f(s)\) sao cho: \[ \frac = z(1 - z) (4) \] để triệt tiêu mẫu số trong biểu thức \((3)\). Chúng ta cùng khởi động một chút với phương trình vi phân đơn giản này. Phương trình \((4)\) tương đương với: \[ \begin &\frac &=& \partial s \\ \Leftrightarrow & (\frac + \frac )\partial z &=&\partial s \\ \Leftrightarrow & \log z - \log(1 - z) &=& s \\ \Leftrightarrow & \log \frac &=& s \\ \Leftrightarrow & \frac &=& e^s \\ \Leftrightarrow & z &=& e^s (1 - z) \\ \Leftrightarrow & z = \frac &=&\frac > = \sigma(s) \end \] Đến đây, tôi hy vọng các bạn đã hiểu hàm số sigmoid được tạo ra như thế nào. Chú ý: Trong việc giải phương trình vi phân ở trên, tôi đã bỏ qua hằng số khi lấy nguyên hàm hai vế. Tuy vậy, việc này không ảnh hưởng nhiều tới kết quả. Công thức cập nhật cho logistic sigmoid regression. Tới đây, bạn đọc có thể kiểm tra rằng: \[ \frac ; \mathbf _i, y_i)> > = (z_i - y_i)\mathbf _i \] Qúa đẹp! Và công thức cập nhật (theo thuật toán SGD) cho logistic regression là: \[ \mathbf = \mathbf + \eta(y_i - z_i)\mathbf _i \] Khá đơn giản! Và, như thường lệ, chúng ta sẽ có vài ví dụ với Python. 3. Ví dụ với Python. Ví dụ với dữ liệu 1 chiều. Quay trở lại với ví dụ nêu ở phần Giới thiệu. Trước tiên ta cần khai báo vài thư viện và dữ liệu:

Комментариев нет:

Отправить комментарий