.. _sec_linear_regression: Hồi quy tuyến tính ================== *Hồi quy* đề cập đến một tập hợp các phương pháp để mô hình hóa mối quan hệ giữa một hoặc nhiều biến độc lập và một biến phụ thuộc. Trong khoa học tự nhiên và khoa học xã hội, mục đích của hồi quy thường là *characterize* mối quan hệ giữa các đầu vào và đầu ra. Mặt khác, học máy thường liên quan đến \* dự đoán \*. Vấn đề hồi quy bật lên bất cứ khi nào chúng ta muốn dự đoán một giá trị số. Các ví dụ phổ biến bao gồm dự đoán giá (nhà cửa, cổ phiếu, v.v.), dự đoán thời gian lưu trú (đối với bệnh nhân trong bệnh viện), dự báo nhu cầu (đối với doanh số bán lẻ), trong số vô số những người khác. Không phải mọi vấn đề dự đoán đều là một vấn đề hồi quy cổ điển. Trong các phần tiếp theo, chúng tôi sẽ giới thiệu các vấn đề phân loại, trong đó mục tiêu là dự đoán tư cách thành viên trong một tập hợp các loại. Các yếu tố cơ bản của hồi quy tuyến tính ---------------------------------------- *Hồi quy tuyến tính* có thể là đơn giản nhất và phổ biến nhất trong số các công cụ tiêu chuẩn để hồi quy. Có niên đại từ bình minh của thế kỷ 19, hồi quy tuyến tính chảy từ một vài giả định đơn giản. Đầu tiên, chúng ta giả định rằng mối quan hệ giữa các biến độc lập :math:`\mathbf{x}` và biến phụ thuộc :math:`y` là tuyến tính, tức là :math:`y` có thể được biểu thị dưới dạng tổng trọng số của các phần tử trong :math:`\mathbf{x}`, cho một số tiếng ồn trên các quan sát. Thứ hai, chúng tôi giả định rằng bất kỳ tiếng ồn nào cũng được cư xử tốt (theo phân phối Gaussian). Để thúc đẩy cách tiếp cận, chúng ta hãy bắt đầu với một ví dụ đang chạy. Giả sử rằng chúng tôi muốn ước tính giá nhà ở (tính bằng đô la) dựa trên diện tích của họ (tính bằng feet vuông) và tuổi (tính bằng năm). Để thực sự phát triển một mô hình để dự đoán giá nhà, chúng ta sẽ cần phải có được bàn tay của chúng tôi trên một bộ dữ liệu bao gồm doanh số bán hàng mà chúng tôi biết giá bán, diện tích và tuổi cho mỗi ngôi nhà. Trong thuật ngữ học máy, tập dữ liệu được gọi là tập dữ liệu đào tạo\* hoặc \* bộ đào tạo\* và mỗi hàng (ở đây dữ liệu tương ứng với một lần bán) được gọi là *ví dụ* (hoặc điểm dữ liệu\ *, *\ dữ liệu instance\ *, *\ mẫu\ *). Điều chúng tôi đang cố gắng dự đoán (giá) được gọi là * nhãy\* (hoặc *mục tiêu *). Các biến độc lập (tuổi và khu vực) dựa trên dự đoán được gọi là *features* (hoặc *covariates*). Thông thường, chúng ta sẽ sử dụng :math:`n` để biểu thị số ví dụ trong tập dữ liệu của chúng ta. Chúng tôi lập chỉ mục các ví dụ dữ liệu bằng :math:`i`, biểu thị mỗi đầu vào là :math:`\mathbf{x}^{(i)} = [x_1^{(i)}, x_2^{(i)}]^\top` và nhãn tương ứng là :math:`y^{(i)}`. .. _subsec_linear_model: Mô hình tuyến tính ~~~~~~~~~~~~~~~~~~ Giả định tuyến tính chỉ nói rằng mục tiêu (giá) có thể được biểu thị dưới dạng tổng trọng số của các tính năng (diện tích và tuổi): .. math:: \mathrm{price} = w_{\mathrm{area}} \cdot \mathrm{area} + w_{\mathrm{age}} \cdot \mathrm{age} + b. :label: eq_price-area Trong :eq:`eq_price-area`, :math:`w_{\mathrm{area}}` và :math:`w_{\mathrm{age}}` được gọi là *trọng lượng*, và :math:`b` được gọi là *bias* (còn được gọi là *offset* hoặc *intercept*). Trọng lượng xác định ảnh hưởng của từng tính năng đối với dự đoán của chúng tôi và sự thiên vị chỉ nói giá trị mà giá dự đoán nên mất khi tất cả các tính năng có giá trị 0. Ngay cả khi chúng ta sẽ không bao giờ nhìn thấy bất kỳ ngôi nhà nào có diện tích bằng 0, hoặc chính xác là 0 năm tuổi, chúng ta vẫn cần sự thiên vị nếu không chúng ta sẽ hạn chế tính biểu cảm của mô hình của mình. Nói đúng ra, :eq:`eq_price-area` là một biến đổi \* affine\* của các tính năng đầu vào, được đặc trưng bởi sự biến đổi tuyến tính\* của các tính năng thông qua tổng trọng số, kết hợp với một \* dịch\* thông qua sự thiên vị được thêm vào. Với một tập dữ liệu, mục tiêu của chúng tôi là chọn trọng lượng :math:`\mathbf{w}` và thiên vị :math:`b` sao cho trung bình, các dự đoán được thực hiện theo mô hình của chúng tôi phù hợp nhất với giá thực sự quan sát thấy trong dữ liệu. Các mô hình có dự đoán đầu ra được xác định bởi sự biến đổi affine của các tính năng đầu vào là \* mô hình tuyến tính\*, trong đó chuyển đổi affine được chỉ định bởi các trọng lượng và thiên vị đã chọn. Trong các ngành mà người ta thường tập trung vào các bộ dữ liệu chỉ với một vài tính năng, thể hiện rõ ràng các mô hình dạng dài như thế này là phổ biến. Trong học máy, chúng ta thường làm việc với các bộ dữ liệu chiều cao, vì vậy thuận tiện hơn khi sử dụng ký hiệu đại số tuyến tính. Khi đầu vào của chúng tôi bao gồm các tính năng :math:`d`, chúng tôi thể hiện dự đoán của chúng tôi :math:`\hat{y}` (nói chung là biểu tượng “mũ” biểu thị ước tính) như .. math:: \hat{y} = w_1 x_1 + ... + w_d x_d + b. Thu thập tất cả các tính năng thành một vector :math:`\mathbf{x} \in \mathbb{R}^d` và tất cả các trọng lượng thành một vector :math:`\mathbf{w} \in \mathbb{R}^d`, chúng ta có thể thể hiện mô hình của mình một cách nhỏ gọn bằng cách sử dụng một sản phẩm chấm: .. math:: \hat{y} = \mathbf{w}^\top \mathbf{x} + b. :label: eq_linreg-y Trong :eq:`eq_linreg-y`, vector :math:`\mathbf{x}` tương ứng với các tính năng của một ví dụ dữ liệu duy nhất. Chúng ta thường sẽ thấy thuận tiện khi tham khảo các tính năng của toàn bộ dữ liệu của chúng tôi :math:`n` ví dụ thông qua ma trận thiết kế\*\ :math:`\mathbf{X} \in \mathbb{R}^{n \times d}`. Ở đây, :math:`\mathbf{X}` chứa một hàng cho mỗi ví dụ và một cột cho mọi tính năng. Đối với một bộ sưu tập các tính năng :math:`\mathbf{X}`, các dự đoán :math:`\hat{\mathbf{y}} \in \mathbb{R}^n` có thể được thể hiện thông qua sản phẩm ma trục-vector: .. math:: {\hat{\mathbf{y}}} = \mathbf{X} \mathbf{w} + b, nơi phát sóng (xem :numref:`subsec_broadcasting`) được áp dụng trong quá trình tổng kết. Với các tính năng của tập dữ liệu đào tạo :math:`\mathbf{X}` và các nhãn tương ứng (đã biết) :math:`\mathbf{y}`, mục tiêu của hồi quy tuyến tính là tìm vector trọng lượng :math:`\mathbf{w}` và thuật ngữ thiên vị :math:`b` đưa ra các tính năng của một ví dụ dữ liệu mới được lấy mẫu từ cùng một phân phối như :math:`\mathbf{X}`, nhãn của ví dụ mới sẽ (trong kỳ vọng) được dự đoán với lỗi thấp nhất. Ngay cả khi chúng tôi tin rằng mô hình tốt nhất để dự đoán :math:`y` cho :math:`\mathbf{x}` là tuyến tính, chúng tôi sẽ không mong đợi để tìm thấy một bộ dữ liệu thế giới thực của :math:`n` ví dụ trong đó :math:`y^{(i)}` chính xác bằng :math:`\mathbf{w}^\top \mathbf{x}^{(i)}+b` cho tất cả :math:`1 \leq i \leq n`. Ví dụ, bất kỳ công cụ nào chúng tôi sử dụng để quan sát các tính năng :math:`\mathbf{X}` và nhãn :math:`\mathbf{y}` có thể bị sai số đo nhỏ. Do đó, ngay cả khi chúng tôi tự tin rằng mối quan hệ cơ bản là tuyến tính, chúng tôi sẽ kết hợp một thuật ngữ tiếng ồn để tính đến các lỗi như vậy. Trước khi chúng ta có thể tìm kiếm các thông số\* tốt nhất\* (hoặc tham số *model *) :math:`\mathbf{w}` và :math:`b`, chúng ta sẽ cần thêm hai điều nữa: (i) một biện pháp chất lượng cho một số mô hình nhất định; và (ii) một quy trình để cập nhật mô hình để cải thiện chất lượng của nó. Chức năng mất ~~~~~~~~~~~~~ Trước khi chúng ta bắt đầu suy nghĩ về cách \* phù hợp\* dữ liệu với mô hình của chúng tôi, chúng ta cần xác định thước đo\* phù hợp\ *. Chức năng *\ loss\* định lượng khoảng cách giữa giá trị *real* và *dự đoán * của mục tiêu. Sự mất mát thường sẽ là một số không âm trong đó các giá trị nhỏ hơn là dự đoán tốt hơn và hoàn hảo sẽ bị mất 0. Chức năng mất phổ biến nhất trong các bài toán hồi quy là lỗi bình phương. Khi dự đoán của chúng ta cho một ví dụ :math:`i` là :math:`\hat{y}^{(i)}` và nhãn đúng tương ứng là :math:`y^{(i)}`, lỗi bình phương được đưa ra bởi: .. math:: l^{(i)}(\mathbf{w}, b) = \frac{1}{2} \left(\hat{y}^{(i)} - y^{(i)}\right)^2. :label: eq_mse Hằng số :math:`\frac{1}{2}` không tạo ra sự khác biệt thực sự nhưng sẽ chứng minh một cách rõ ràng thuận tiện, hủy bỏ khi chúng ta lấy dẫn xuất của sự mất mát. Kể từ khi tập dữ liệu đào tạo được cung cấp cho chúng tôi, và do đó ngoài tầm kiểm soát của chúng tôi, lỗi thực nghiệm chỉ là một chức năng của các tham số mô hình. Để làm cho mọi thứ cụ thể hơn, hãy xem xét ví dụ dưới đây nơi chúng ta vẽ một bài toán hồi quy cho một trường hợp một chiều như thể hiện trong :numref:`fig_fit_linreg`. .. _fig_fit_linreg: .. figure:: ../img/fit-linreg.svg Fit data with a linear model. Lưu ý rằng sự khác biệt lớn giữa các ước tính :math:`\hat{y}^{(i)}` và quan sát :math:`y^{(i)}` dẫn đến những đóng góp thậm chí còn lớn hơn cho sự mất mát, do sự phụ thuộc bậc hai. Để đo lường chất lượng của một mô hình trên toàn bộ dữ liệu :math:`n` ví dụ, chúng tôi chỉ đơn giản là trung bình (hoặc tương đương, tổng hợp) các tổn thất trên bộ đào tạo. .. math:: L(\mathbf{w}, b) =\frac{1}{n}\sum_{i=1}^n l^{(i)}(\mathbf{w}, b) =\frac{1}{n} \sum_{i=1}^n \frac{1}{2}\left(\mathbf{w}^\top \mathbf{x}^{(i)} + b - y^{(i)}\right)^2. Khi đào tạo mô hình, chúng tôi muốn tìm các tham số (:math:`\mathbf{w}^*, b^*`) giúp giảm thiểu tổng tổn thất trên tất cả các ví dụ đào tạo: .. math:: \mathbf{w}^*, b^* = \operatorname*{argmin}_{\mathbf{w}, b}\ L(\mathbf{w}, b). Giải pháp phân tích ~~~~~~~~~~~~~~~~~~~ Hồi quy tuyến tính xảy ra là một vấn đề tối ưu hóa đơn giản bất thường. Không giống như hầu hết các mô hình khác mà chúng ta sẽ gặp phải trong cuốn sách này, hồi quy tuyến tính có thể được giải quyết một cách phân tích bằng cách áp dụng một công thức đơn giản. Để bắt đầu, chúng ta có thể đặt sai lệch :math:`b` vào tham số :math:`\mathbf{w}` bằng cách thêm một cột vào ma trận thiết kế bao gồm tất cả các cột. Sau đó, vấn đề dự đoán của chúng tôi là giảm thiểu :math:`\|\mathbf{y} - \mathbf{X}\mathbf{w}\|^2`. Chỉ có một điểm quan trọng trên bề mặt mất mát và nó tương ứng với mức tối thiểu tổn thất trên toàn bộ miền. Lấy đạo hàm của tổn thất đối với :math:`\mathbf{w}` và đặt nó bằng 0 mang lại giải pháp phân tích (dạng đóng): .. math:: \mathbf{w}^* = (\mathbf X^\top \mathbf X)^{-1}\mathbf X^\top \mathbf{y}. Trong khi các vấn đề đơn giản như hồi quy tuyến tính có thể thừa nhận các giải pháp phân tích, bạn không nên quen với may mắn như vậy. Mặc dù các giải pháp phân tích cho phép phân tích toán học tốt đẹp, yêu cầu của một giải pháp phân tích rất hạn chế đến mức nó sẽ loại trừ tất cả các học sâu. Minibatch Stochastic Gradient Descent ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Ngay cả trong trường hợp chúng ta không thể giải quyết các mô hình một cách phân tích, hóa ra chúng ta vẫn có thể đào tạo các mô hình hiệu quả trong thực tế. Hơn nữa, đối với nhiều nhiệm vụ, những mô hình khó tối ưu hóa đó hóa ra trở nên tốt hơn nhiều đến mức tìm ra cách đào tạo chúng sẽ rất đáng để gặp rắc rối. Kỹ thuật chính để tối ưu hóa gần như bất kỳ mô hình học sâu nào và chúng ta sẽ kêu gọi trong suốt cuốn sách này, bao gồm việc giảm lỗi lặp đi lặp lại bằng cách cập nhật các tham số theo hướng làm giảm chức năng mất dần. Thuật toán này được gọi là *gradient descent*. Ứng dụng ngây thơ nhất của gradient descent bao gồm lấy đạo hàm của hàm mất, là trung bình của các tổn thất được tính toán trên mỗi ví dụ duy nhất trong tập dữ liệu. Trong thực tế, điều này có thể cực kỳ chậm: chúng ta phải vượt qua toàn bộ tập dữ liệu trước khi thực hiện một bản cập nhật duy nhất. Do đó, chúng ta thường sẽ giải quyết để lấy mẫu một minibatch ngẫu nhiên các ví dụ mỗi khi chúng ta cần tính toán bản cập nhật, một biến thể được gọi là \* minibatch stochastic gradient descent\*. Trong mỗi lần lặp lại, lần đầu tiên chúng ta lấy mẫu ngẫu nhiên một minibatch :math:`\mathcal{B}` bao gồm một số ví dụ đào tạo cố định. Sau đó chúng ta tính toán đạo hàm (gradient) của tổn thất trung bình trên minibatch liên quan đến các tham số mô hình. Cuối cùng, chúng ta nhân gradient với giá trị dương được xác định trước :math:`\eta` và trừ thuật ngữ kết quả từ các giá trị tham số hiện tại. Chúng ta có thể thể hiện bản cập nhật về mặt toán học như sau (:math:`\partial` biểu thị đạo hàm một phần): .. math:: (\mathbf{w},b) \leftarrow (\mathbf{w},b) - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \partial_{(\mathbf{w},b)} l^{(i)}(\mathbf{w},b). Tóm lại, các bước của thuật toán như sau: (i) chúng ta khởi tạo các giá trị của các tham số mô hình, thường là ngẫu nhiên; (ii) chúng ta lặp lại lấy mẫu minibatches ngẫu nhiên từ dữ liệu, cập nhật các tham số theo hướng của gradient âm. Đối với tổn thất bậc hai và biến đổi affine, chúng ta có thể viết ra điều này một cách rõ ràng như sau: .. math:: \begin{aligned} \mathbf{w} &\leftarrow \mathbf{w} - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \partial_{\mathbf{w}} l^{(i)}(\mathbf{w}, b) = \mathbf{w} - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \mathbf{x}^{(i)} \left(\mathbf{w}^\top \mathbf{x}^{(i)} + b - y^{(i)}\right),\\ b &\leftarrow b - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \partial_b l^{(i)}(\mathbf{w}, b) = b - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}} \left(\mathbf{w}^\top \mathbf{x}^{(i)} + b - y^{(i)}\right). \end{aligned} :label: eq_linreg_batch_update Lưu ý rằng :math:`\mathbf{w}` và :math:`\mathbf{x}` là vectơ trong :eq:`eq_linreg_batch_update`. Ở đây, ký hiệu vector thanh lịch hơn làm cho toán học dễ đọc hơn nhiều so với thể hiện mọi thứ về hệ số, nói :math:`w_1, w_2, \ldots, w_d`. Tập cardinality :math:`|\mathcal{B}|` đại diện cho số lượng ví dụ trong mỗi minibatch (\* batch size\ *) và :math:`\eta` biểu thị tỷ lệ học tập *. Chúng tôi nhấn mạnh rằng các giá trị của quy mô lô và tốc độ học tập được chỉ định trước bằng tay và thường không được học thông qua đào tạo mô hình. Các tham số này có thể điều chỉnh nhưng không được cập nhật trong vòng đào tạo được gọi là *hyperparameters*. *Điều chỉnh siêu tham số* là quá trình mà các siêu tham số được chọn, và thường yêu cầu chúng tôi điều chỉnh chúng dựa trên kết quả của vòng lặp đào tạo như được đánh giá trên một bộ dữ liệu xác thực \* riêng biệt\* (hoặc bộ xác thực \*). Sau khi đào tạo cho một số lần lặp lại được xác định trước (hoặc cho đến khi đáp ứng một số tiêu chí dừng khác), chúng tôi ghi lại các tham số mô hình ước tính, ký hiệu là :math:`\hat{\mathbf{w}}, \hat{b}`. Lưu ý rằng ngay cả khi chức năng của chúng ta thực sự tuyến tính và không ồn ào, các tham số này sẽ không phải là bộ giảm thiểu chính xác của sự mất mát bởi vì, mặc dù thuật toán hội tụ chậm về phía các bộ giảm thiểu, nó không thể đạt được chính xác trong một số bước hữu hạn. Hồi quy tuyến tính xảy ra là một vấn đề học tập mà chỉ có một mức tối thiểu so với toàn bộ miền. Tuy nhiên, đối với các mô hình phức tạp hơn, như mạng sâu, các bề mặt mất mát chứa nhiều minima. May mắn thay, vì những lý do chưa được hiểu đầy đủ, các học viên học sâu hiếm khi đấu tranh để tìm ra các thông số giảm thiểu tổn thất \* trong bộ đào tạo\ *. Nhiệm vụ ghê gớm hơn là tìm các tham số sẽ đạt được tổn thất thấp đối với dữ liệu mà chúng ta chưa thấy trước đây, một thách thức được gọi là *\ generalization\*. Chúng tôi quay trở lại các chủ đề này trong suốt cuốn sách. Đưa ra dự đoán với mô hình đã học ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Với mô hình hồi quy tuyến tính đã học :math:`\hat{\mathbf{w}}^\top \mathbf{x} + \hat{b}`, bây giờ chúng ta có thể ước tính giá của một ngôi nhà mới (không chứa trong dữ liệu đào tạo) cho khu vực của nó :math:`x_1` và :math:`x_2` tuổi. Ước tính các mục tiêu được đưa ra các tính năng thường được gọi là *prediction* hoặc *inference*. Chúng tôi sẽ cố gắng gắn bó với *prediction* vì gọi bước này\* suy tiế\ *, mặc dù nổi lên như là thuật ngữ tiêu chuẩn trong học sâu, nhưng có phần là một sự sai lầm. Trong thống kê, *\ inference\* thường biểu thị các tham số ước tính dựa trên tập dữ liệu. Việc sử dụng sai thuật ngữ này là một nguồn gây nhầm lẫn phổ biến khi các học viên học sâu nói chuyện với các nhà thống kê. Vectorization cho tốc độ ------------------------ Khi đào tạo các mô hình của chúng tôi, chúng tôi thường muốn xử lý toàn bộ minibatches ví dụ cùng một lúc. Làm điều này một cách hiệu quả đòi hỏi rằng we vectorize các phép tính và tận dụng các thư viện đại số tuyến tính nhanh hơn là viết tốn kém cho - vòng lặp trong Python. .. raw:: html