Lựa chọn mô hình và xác nhận chéo: Đúng cách


34

Có rất nhiều chủ đề trong CrossValidated về chủ đề lựa chọn mô hình và xác nhận chéo. Ở đây có một ít:

Tuy nhiên, câu trả lời cho các chủ đề này khá chung chung và chủ yếu làm nổi bật các vấn đề với các cách tiếp cận cụ thể để xác nhận chéo và lựa chọn mô hình.

Để làm cho mọi thứ cụ thể nhất có thể , ví dụ: chúng tôi đang làm việc với một SVM với hạt nhân RBF: , và đó Tôi có bộ dữ liệu về các tính năng X và nhãn y và tôi muốnK(x,x)=(γ|xx|)2

  1. Tìm các giá trị tốt nhất có thể có trong mô hình của tôi ( vàγC )
  2. Huấn luyện SVM với tập dữ liệu của tôi (để triển khai cuối cùng)
  3. Ước tính lỗi tổng quát hóa và độ không đảm bảo (phương sai) xung quanh lỗi này

Để làm như vậy, cá nhân tôi sẽ thực hiện tìm kiếm dạng lưới, ví dụ: tôi thử mọi kết hợp có thể có của và . Để đơn giản, chúng ta có thể giả sử các phạm vi sau:Cγ

  • C{10,100,1000}
  • γ{0.1,0.2,0.5,1.0}

Cụ thể hơn, sử dụng bộ dữ liệu đầy đủ của tôi, tôi làm như sau:

  1. Đối với mỗi cặp ( , ), tôi thực hiện các lần lặp lại (ví dụ 100 lần lặp lại ngẫu nhiên) của xác thực chéo Fold (ví dụ: ), trên tập dữ liệu của tôi, tức là tôi huấn luyện SVM của mình trên nếp gấp và đánh giá lỗi ở nếp gấp bên trái, lặp qua tất cả các nếp gấpNhìn chung, tôi thu thập 100 x 10 = 1000 lỗi kiểm tra.CγKK=10K1K
  2. Đối với mỗi cặp ( , ) như vậy , tôi tính giá trị trung bình và phương sai của 1000 lỗi kiểm tra đó .CγμM,σM

Bây giờ tôi muốn chọn mô hình tốt nhất (các tham số kernel tốt nhất) mà tôi sẽ sử dụng để huấn luyện SVM cuối cùng của mình trên bộ dữ liệu đầy đủ. Tôi hiểu rằng việc chọn mô hình có trung bình sai số thấp nhất và phương sai và sẽ là lựa chọn đúng và rằng của mô hình này là σ M là ước tính tốt nhất của tôi về sai lệch và sai lệch tổng quát của mô hình khi đào tạo với bộ dữ liệu đầy đủ.μMσMμMσM

NHƯNG, sau khi đọc các câu trả lời trong các chủ đề ở trên, tôi có ấn tượng rằng phương pháp này để chọn SVM tốt nhất để triển khai và / hoặc để ước tính lỗi của nó (hiệu suất tổng quát), là thiếu sót, và có nhiều cách tốt hơn để chọn SVM tốt nhất và báo cáo lỗi của nó. Nếu vậy, chúng là gì? Tôi đang tìm kiếm một câu trả lời cụ thể xin vui lòng.

Bám sát vấn đề này, làm thế nào cụ thể tôi có thể chọn mô hình tốt nhấtước tính đúng lỗi tổng quát của nó ?


Để làm cho mọi thứ cụ thể nhất có thể, xin vui lòng cho chúng tôi biết: Bạn có bao nhiêu trường hợp độc lập thống kê trong bộ dữ liệu của mình? Hàm mục tiêu bạn đánh giá để tối ưu hóa là gì / Bạn sử dụng loại biện pháp lỗi nào? Bạn có thực sự quan sát một hành vi nhất quán của thước đo lỗi đã chọn trên lưới tham số của bạn không? Trong trường hợp bạn đang nói về phân loại và biện pháp lỗi của bạn cho phép điều này: làm thế nào để kết quả xác thực chéo được lặp lại so với phương sai bạn mong đợi (nhưng không thể đo lường) do kích thước mẫu hữu hạn?
cbeleites hỗ trợ Monica

Một bài viết mà bạn có thể thấy thú vị: Optimprediction.com/files/pdf/V2A5.pdf
user31256

2
+1 cho câu hỏi rất rõ ràng và chi tiết, cũng như câu hỏi rất phù hợp với cộng đồng khoa học dữ liệu nói chung.
NickBraunagel

Câu trả lời:


20

Bài viết của tôi trong JMLR giải quyết câu hỏi chính xác này và giải thích lý do tại sao quy trình được đề xuất trong câu hỏi (hoặc ít nhất là một câu hỏi rất giống nó) dẫn đến ước tính hiệu suất thiên vị lạc quan:

Gavin C. Cawley, Nicola LC Talbot, "Về sự phù hợp quá mức trong lựa chọn mô hình và xu hướng lựa chọn tiếp theo trong đánh giá hiệu suất", Tạp chí nghiên cứu máy học, 11 (tháng 7): 2079−2107, 2010 ( www )

Điều quan trọng cần nhớ là xác thực chéo là một kỹ thuật để ước tính hiệu suất tổng quát hóa cho một phương pháp tạo ra một mô hình, chứ không phải là chính mô hình đó. Vì vậy, nếu chọn tham số kernel là một phần của quá trình tạo mô hình, bạn cũng cần xác thực chéo quy trình chọn mô hình, nếu không, bạn sẽ kết thúc với ước tính hiệu suất sai lệch lạc quan (như sẽ xảy ra với quy trình bạn đề xuất).

Giả sử bạn có một hàm fit_model, lấy một tập dữ liệu bao gồm các thuộc tính X và các phản hồi mong muốn Y, và trả về mô hình được trang bị cho tập dữ liệu đó, bao gồm cả điều chỉnh các tham số siêu (trong trường hợp này là các tham số chính quy và nhân). Điều chỉnh siêu tham số này có thể được thực hiện theo nhiều cách, ví dụ như giảm thiểu lỗi xác thực chéo so với X và T.

Bước 1 - Điều chỉnh mô hình cho tất cả dữ liệu có sẵn, sử dụng chức năng fit_model. Điều này cung cấp cho bạn mô hình mà bạn sẽ sử dụng trong hoạt động.

Bước 2 - Đánh giá hiệu suất. Thực hiện xác nhận chéo nhiều lần bằng cách sử dụng tất cả các dữ liệu có sẵn. Trong mỗi lần gấp, dữ liệu được phân vùng thành tập huấn luyện và tập kiểm tra. Điều chỉnh mô hình bằng cách sử dụng tập huấn luyện (ghi lại các giá trị siêu tham số cho mô hình được trang bị) và đánh giá hiệu suất trên tập kiểm tra. Sử dụng giá trị trung bình trên tất cả các bộ kiểm tra làm ước tính hiệu suất (và có lẽ cũng xem xét mức độ lây lan của các giá trị).

Bước 3 - Biến đổi của cài đặt siêu tham số - thực hiện phân tích các giá trị siêu tham số được thu thập ở bước 3. Tuy nhiên tôi nên chỉ ra rằng không có gì đặc biệt về siêu tham số, chúng chỉ là các tham số của mô hình đã được ước tính (gián tiếp ) từ dữ liệu. Chúng được coi là siêu tham số thay vì tham số để thuận tiện cho việc tính toán / toán học, nhưng điều này không phải là trường hợp.

Vấn đề với việc sử dụng xác thực chéo ở đây là dữ liệu huấn luyện và kiểm tra không phải là các mẫu độc lập (vì chúng chia sẻ dữ liệu), điều đó có nghĩa là ước tính phương sai của ước tính hiệu suất và các tham số siêu có thể bị sai lệch (nghĩa là nhỏ hơn so với các mẫu dữ liệu thực sự độc lập trong mỗi lần gấp). Thay vì xác nhận chéo lặp đi lặp lại, có lẽ tôi sẽ sử dụng bootstrapping thay vào đó và bỏ túi các mô hình kết quả nếu điều này khả thi về mặt tính toán.

Điểm mấu chốt là để có được ước tính hiệu suất không thiên vị, bất kỳ quy trình nào bạn sử dụng để tạo mô hình cuối cùng (fit_model) phải được lặp lại một cách độc lập trong toàn bộ quy trình xác thực chéo.


Đây là một câu trả lời tuyệt vời. Khi bạn nói rather than repeated cross-validation you would go for bootstrapping- chính xác sự khác biệt là gì? Cả hai liên quan đến nhiều lần lặp lại phân chia dữ liệu vào traintestvà sau đó đào tạo trong trainvà đánh giá trong test, phải không?
Josh

4
Bootstrapping (lấy mẫu bằng thay thế) có vẻ là một cách tự nhiên hơn để thực hiện một số lượng lớn các lần lấy mẫu lại, vì nó ngẫu nhiên hơn so với xác nhận chéo lặp đi lặp lại. Đối với bootstrapping, việc sử dụng các enembled đóng gói là một tính năng hay, với lỗi ngoài túi là ước tính hiệu suất. Không có một số lượng lớn để lựa chọn giữa hai.
Dikran Marsupial

Cảm ơn @Dikran - Điều này khiến tôi tự hỏi, giả sử rằng một người sử dụng ví dụ như bootstrapping, làm thế nào bạn chọn một mô hình tốt xem xét giá trị trung bình và phương sai trong các lần lặp lại? (tức là giao thức lựa chọn mô hình nào bạn sẽ làm theo?). Câu hỏi này đặt ra chính xác câu hỏi này. Nhận đầu vào của bạn trên chủ đề đó sẽ vô cùng có giá trị!
Josh

@DikranMarsupial Bạn có thể đăng mã (ví dụ: Python hoặc R) cho các bước 1-3 của bạn không? Tôi thấy dễ dàng hơn nhiều để hiểu các thủ tục như vậy khi nhìn thấy mã cụ thể.
tobip

1
Thông báo chính: "Điểm mấu chốt là để có được ước tính hiệu suất không thiên vị, bất kỳ quy trình nào bạn sử dụng để tạo mô hình cuối cùng (fit_model) phải được lặp lại một cách độc lập trong mỗi lần của quy trình xác thực chéo." Thông điệp chính xác này cũng được truyền tải trong Các yếu tố của học thống kê (xem phần 7.10.2
NickBraunagel

0

γC

Một thủ tục tối ưu hóa các siêu đường kính này và huấn luyện một SVM với chúng cũng chỉ là một thuật toán học máy . Thay vì chỉ tối ưu hóa các tham số bên trong của SVM (các vectơ hỗ trợ), nó cũng tối ưu hóa các siêu đường kính.

Bây giờ bạn có hai vấn đề [có thể được giải quyết độc lập]:

Đọc lạm dụng xác thực chéo (hiệu suất báo cáo cho giá trị siêu tham số tốt nhất) để đảm bảo rằng bạn không trộn lẫn chúng.


Một giải pháp cụ thể (có thể không tối ưu) cho vấn đề cụ thể của câu hỏi của bạn:

k = 5
loss_CV = zeros(k)
for i in 1:k 
    Xi_train, Xi_test = folds(X,k)[i]
    loss = zeros((3,3))
    for lambda in {0.1,0.2,0.5,1.0}
        for C in {10,100,1000}
            for j in 1:k
                Xj_train, Xj_test = folds(Xi_train,k)[j]
                model = SVM(Xj_train,lambda, C)
                loss[lambda,C] += test_error(model,Xj_test)
    lambda, C = argmax(loss)
    model = SVM(Xi_train,lambda, C)
    loss_CV += test_error(model,Xi_test)

loss = zeros((3,3))
for lambda in {0.1,0.2,0.5,1.0}
    for C in {10,100,1000}
        for j in 1:k
            Xj_train, Xj_test = folds(Xi_train,k)[j]
            model = SVM(Xj_train,lambda, C)
            loss[lambda,C] += test_error(model,Xj_test)
lambda, C = argmax(loss)
model = SVM(Xi_train,lambda, C)

Ở đây, modelsẽ là "mô hình tốt nhất" của bạn và loss_CVlà "ước tính chính xác về lỗi tổng quát hóa của nó" (mặc dù thiên về hướng lên, nhưng bạn không thể có bánh và ăn nó).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.