Nếu bạn vẫn quan tâm đến việc làm mịn với các hình phạt L0, tôi sẽ xem qua tài liệu tham khảo sau: "Trực quan hóa các thay đổi gen bằng cách làm mịn phân đoạn bằng cách sử dụng hình phạt L0" - DOI: 10.1371 / tạp chí.pone.0038230 (một đoạn giới thiệu hay về Whittaker mượt hơn có thể được tìm thấy trong giấy P. Eilers "A mượt hoàn hảo hơn" - DOI: 10.1021 / ac034173t). Tất nhiên, để đạt được mục tiêu của bạn, bạn phải làm việc một chút xung quanh phương pháp.
Về nguyên tắc, bạn cần 3 thành phần:
- Nhẹ nhàng hơn - Tôi sẽ sử dụng Whittaker mượt mà hơn. Ngoài ra, tôi sẽ sử dụng phép tăng ma trận (xem Eilers và Marx, 1996 - "Làm mịn linh hoạt với B-splines và Penalies", tr.101).
- Hồi quy lượng tử - Tôi sẽ sử dụng gói lượng tử R (rho = 0,5) cho sự lười biếng :-)
- Hình phạt L0 - Tôi sẽ theo dõi "Trực quan hóa các thay đổi gen bằng cách làm mịn phân đoạn bằng cách sử dụng hình phạt L0" - DOI: 10.1371 / tạp chí.pone.0038230
Tất nhiên, bạn cũng sẽ cần một cách để chọn mức độ làm mịn tối ưu. Điều này được thực hiện bởi mắt thợ mộc của tôi cho ví dụ này. Bạn có thể sử dụng các tiêu chí trong DOI: 10.1371 / Tạp chí.pone.0038230 (trang 5, nhưng tôi đã không thử nó trong ví dụ của bạn).
Bạn sẽ tìm thấy một mã nhỏ dưới đây. Tôi để lại một số ý kiến như hướng dẫn thông qua nó.
# Cross Validated example
rm(list = ls()); graphics.off(); cat("\014")
library(splines)
library(Matrix)
library(quantreg)
# The data
set.seed(20181118)
n = 400
x = 1:n
true_fct = stepfun(c(100, 200, 250), c(200, 250, 300, 250))
y = true_fct(x) + rt(length(x), df = 1)
# Prepare bases - Identity matrix (Whittaker)
# Can be changed for B-splines
B = diag(1, n, n)
# Prepare penalty - lambda parameter fix
nb = ncol(B)
D = diff(diag(1, nb, nb), diff = 1)
lambda = 1e2
# Solve standard Whittaker - for initial values
a = solve(t(B) %*% B + crossprod(D), t(B) %*% y, tol = 1e-50)
# est. loop with L0-Diff penalty as in DOI: 10.1371/journal.pone.0038230
p = 1e-6
nit = 100
beta = 1e-5
for (it in 1:nit) {
ao = a
# Penalty weights
w = (c(D %*% a) ^ 2 + beta ^ 2) ^ ((p - 2)/2)
W = diag(c(w))
# Matrix augmentation
cD = lambda * sqrt(W) %*% D
Bp = rbind(B, cD)
yp = c(y, 1:nrow(cD)*0)
# Update coefficients - rq.fit from quantreg
a = rq.fit(Bp, yp, tau = 0.5)$coef
# Check convergence and update
da = max(abs((a - ao)/ao))
cat(it, da, '\n')
if (da < 1e-6) break
}
# Fit
v = B %*% a
# Show results
plot(x, y, pch = 16, cex = 0.5)
lines(x, y, col = 8, lwd = 0.5)
lines(x, v, col = 'blue', lwd = 2)
lines(x, true_fct(x), col = 'red', lty = 2, lwd = 2)
legend("topright", legend = c("True Signal", "Smoothed signal"),
col = c("red", "blue"), lty = c(2, 1))
Tái bút Đây là câu trả lời đầu tiên của tôi về Xác thực chéo. Tôi hy vọng nó hữu ích và đủ rõ ràng :-)