Tôi không nghĩ rằng bạn đã phạm sai lầm trong mã. Đây là một vấn đề của việc giải thích đầu ra.
Lasso không chỉ ra các biến hồi quy riêng lẻ nào "dễ dự đoán" hơn các biến khác. Nó chỉ đơn giản là có xu hướng tích hợp để ước tính các hệ số là 0. Hệ số hình phạt càng lớn thì xu hướng đó càng lớn.log(λ)
Biểu đồ xác thực chéo của bạn cho thấy rằng càng nhiều hệ số bị buộc về 0, mô hình thực hiện công việc tốt hơn và tốt hơn để dự đoán các tập hợp con của các giá trị đã được xóa ngẫu nhiên khỏi bộ dữ liệu. Khi các lỗi dự đoán được xác thực chéo tốt nhất (được đo là "Độ lệch nhị phân" ở đây) đạt được khi tất cả các hệ số bằng 0, bạn nên nghi ngờ rằng không có sự kết hợp tuyến tính nào của bất kỳ tập hợp con nào của biến hồi quy có thể hữu ích để dự đoán kết quả.
Bạn có thể xác minh điều này bằng cách tạo các phản hồi ngẫu nhiên độc lập với tất cả các biến hồi quy và áp dụng quy trình phù hợp của bạn với chúng. Đây là một cách nhanh chóng để mô phỏng tập dữ liệu của bạn:
n <- 570
k <- 338
set.seed(17)
X <- data.frame(matrix(floor(runif(n*(k+1), 0, 2)), nrow=n,
dimnames=list(1:n, c("y", paste0("x", 1:k)))))
Khung dữ liệu X
có một cột nhị phân ngẫu nhiên có tên là "y" và 338 cột nhị phân khác (tên của chúng không quan trọng). Tôi đã sử dụng cách tiếp cận của bạn để hồi quy "y" chống lại các biến đó, nhưng - chỉ cần cẩn thận - tôi đã đảm bảo rằng vectơ phản hồi y
và ma trận mô hình x
khớp với nhau (điều mà chúng có thể không làm trong trường hợp có bất kỳ giá trị bị thiếu nào trong dữ liệu) :
f <- y ~ . - 1 # cv.glmnet will include its own intercept
M <- model.frame(f, X)
x <- model.matrix(f, M)
y <- model.extract(M, "response")
fit <- cv.glmnet(x, y, family="binomial")
Kết quả rất giống với bạn:
plot(fit)
Thật vậy, với những dữ liệu hoàn toàn ngẫu nhiên này, Lasso vẫn trả về chín ước tính hệ số khác không (mặc dù chúng ta biết, bằng cách xây dựng, các giá trị chính xác đều bằng không). Nhưng chúng ta không nên mong đợi sự hoàn hảo. Hơn nữa, vì sự phù hợp dựa trên việc loại bỏ ngẫu nhiên các tập hợp con của dữ liệu để xác thực chéo, thông thường bạn sẽ không nhận được cùng một đầu ra từ lần chạy này đến lần chạy tiếp theo. Trong ví dụ này, một cuộc gọi thứ hai để cv.glmnet
tạo ra sự phù hợp chỉ với một hệ số khác không. Vì lý do này, nếu bạn có thời gian, luôn luôn nên chạy lại quy trình lắp đặt nhiều lần và theo dõi các ước tính hệ số nào là không khác nhau. Đối với những dữ liệu này - với hàng trăm biến hồi quy - việc này sẽ mất vài phút để lặp lại chín lần nữa.
sim <- cbind(as.numeric(coef(fit)),
replicate(9, as.numeric(coef(cv.glmnet(x, y, family="binomial")))))
plot(1:k, rowMeans(sim[-1,] != 0) + runif(k, -0.025, 0.025),
xlab="Coefficient Index", ylab="Frequency not zero (jittered)",
main="Results of Repeated Cross-Validated Lasso Fits")
Tám trong số các biến hồi quy này có ước tính khác không trong khoảng một nửa số phù hợp; phần còn lại của họ không bao giờ có ước tính khác không. Điều này cho thấy mức độ nào Lasso vẫn sẽ bao gồm các ước tính hệ số khác không ngay cả khi bản thân các hệ số thực sự bằng không.