스플라인 결과 해석


20

R을 사용하여 GLM에 대한 스플라인을 맞추려고합니다. 스플라인에 맞으면 결과 모델을 가져 와서 Excel 통합 문서에서 모델링 파일을 만들 수 있기를 원합니다.

예를 들어, y가 x의 랜덤 함수이고 특정 지점 (이 경우 @ x = 500)에서 기울기가 갑자기 변하는 데이터 세트가 있다고 가정합니다.

set.seed(1066)
x<- 1:1000
y<- rep(0,1000)

y[1:500]<- pmax(x[1:500]+(runif(500)-.5)*67*500/pmax(x[1:500],100),0.01)
y[501:1000]<-500+x[501:1000]^1.05*(runif(500)-.5)/7.5

df<-as.data.frame(cbind(x,y))

plot(df)

나는 이제 이것을 사용하여 적합

library(splines)
spline1 <- glm(y~ns(x,knots=c(500)),data=df,family=Gamma(link="log"))

내 결과는 보여

summary(spline1)

Call:
glm(formula = y ~ ns(x, knots = c(500)), family = Gamma(link = "log"), 
    data = df)

Deviance Residuals: 
     Min       1Q   Median       3Q      Max  
-4.0849  -0.1124  -0.0111   0.0988   1.1346  

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)             4.17460    0.02994  139.43   <2e-16 ***
ns(x, knots = c(500))1  3.83042    0.06700   57.17   <2e-16 ***
ns(x, knots = c(500))2  0.71388    0.03644   19.59   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for Gamma family taken to be 0.1108924)

    Null deviance: 916.12  on 999  degrees of freedom
Residual deviance: 621.29  on 997  degrees of freedom
AIC: 13423

Number of Fisher Scoring iterations: 9

이 시점에서 r 내 예측 함수를 사용하고 완벽하게 수용 가능한 답변을 얻을 수 있습니다. 문제는 모델 결과를 사용하여 Excel에서 통합 문서를 작성하려고한다는 것입니다.

예측 함수에 대한 나의 이해는 새로운 "x"값이 주어지면 r은 새로운 x를 적절한 스플라인 함수 (500 이상의 값에 대한 함수 또는 500 미만의 값에 대한 함수)에 꽂은 다음 그 결과를 가져와 곱한다는 것입니다 적절한 계수로 계산하고 그 시점부터 다른 모형 항처럼 취급합니다. 이 스플라인 함수는 어떻게 얻습니까?

(참고 : 로그 링크 감마 GLM이 제공된 데이터 세트에 적합하지 않을 수 있음을 알고 있습니다. GLM을 언제 어떻게 적용 할 것인지 묻지 않습니다. 재현성을 위해 예제로 제공합니다.)


7
가능한 경우 rm(list=ls())모든 경고 를 삭제 하지 않는 모든 변수 ( ) 를 삭제하는 코드를 포함하지 않도록 제안 합니다. 그들이 어떤 이미 변수 (그러나 아무도 전화가 어디에 누군가가 R의 오픈 세션에 코드를 복사하여 붙여 넣을 수 있습니다 x, y, df또는 spline1)와 미스 코드가 자신의 작품을 지워 버리고있다. 그들이 그렇게 하는게 좀 멍청한가요? 예. 그러나 자신의 변수를 삭제할시기를 결정하는 것은 여전히 ​​예의입니다.
Glen_b-복지 모니카

답변:


25

R코드 에 들어 가지 않고도 스플라인 수식을 리버스 엔지니어링 할 수 있습니다 . 그것을 알고 있으면 충분하다

  • 스플라인은 부분 다항식 함수입니다.

  • dd+1

  • 다항식의 계수는 선형 회귀를 통해 얻을 수 있습니다.

d+1xxdd=34×4=16d+1=4x

64RR위에서 설명한대로 Excel과 유사한 수식으로 다시 포맷 한 다음 복사하여 Excel에 붙여 넣기 만하면됩니다.

이 방법은 소스 코드를 사용할 수없는 문서화되지 않은 독점 소프트웨어를 포함한 모든 통계 소프트웨어에서 작동합니다.

200,500,800(1,1000)RR

R 도표

엑셀 플롯

( R버전 의 세로 회색 눈금 선 은 내부 매듭이있는 위치를 보여줍니다.)


전체 R코드 는 다음과 같습니다 . paste문자열 조작을 수행하는 기능에 전적으로 의존하는 정교한 해킹 입니다. 더 좋은 방법은 수식 템플릿을 만들고 문자열 일치 및 대체 명령을 사용하여 채우는 것입니다.

#
# Create and display a spline basis.
#
x <- 1:1000
n <- ns(x, knots=c(200, 500, 800))

colors <- c("Orange", "Gray", "tomato2", "deepskyblue3")
plot(range(x), range(n), type="n", main="R Version",
     xlab="x", ylab="Spline value")
for (k in attr(n, "knots")) abline(v=k, col="Gray", lty=2)
for (j in 1:ncol(n)) {
  lines(x, n[,j], col=colors[j], lwd=2)
}
#
# Export this basis in Excel-readable format.
#
ns.formula <- function(n, ref="A1") {
  ref.p <- paste("I(", ref, sep="")
  knots <- sort(c(attr(n, "Boundary.knots"), attr(n, "knots")))
  d <- attr(n, "degree")
  f <- sapply(2:length(knots), function(i) {
    s.pre <- paste("IF(AND(", knots[i-1], "<=", ref, ", ", ref, "<", knots[i], "), ", 
                   sep="")
    x <- seq(knots[i-1], knots[i], length.out=d+1)
    y <- predict(n, x)
    apply(y, 2, function(z) {
      s.f <- paste("z ~ x+", paste("I(x", 2:d, sep="^", collapse=")+"), ")", sep="")
      f <- as.formula(s.f)
      b.hat <- coef(lm(f))
      s <- paste(c(b.hat[1], 
            sapply(1:d, function(j) paste(b.hat[j+1], "*", ref, "^", j, sep=""))), 
            collapse=" + ")
      paste(s.pre, s, ", 0)", sep="")
    })
  })
  apply(f, 1, function(s) paste(s, collapse=" + "))
}
ns.formula(n) # Each line of this output is one basis formula: paste into Excel

첫 번째 스플라인 출력 공식 (여기서 생성 된 4 개 중)은

"IF(AND(1<=A1, A1<200), -1.26037447288906e-08 + 3.78112341937071e-08*A1^1 + -3.78112341940948e-08*A1^2 + 1.26037447313669e-08*A1^3, 0) + IF(AND(200<=A1, A1<500), 0.278894459758071 + -0.00418337927419299*A1^1 + 2.08792741929417e-05*A1^2 + -2.22580643138594e-08*A1^3, 0) + IF(AND(500<=A1, A1<800), -5.28222778473101 + 0.0291833541927414*A1^1 + -4.58541927409268e-05*A1^2 + 2.22309136420529e-08*A1^3, 0) + IF(AND(800<=A1, A1<1000), 12.500000000002 + -0.0375000000000067*A1^1 + 3.75000000000076e-05*A1^2 + -1.25000000000028e-08*A1^3, 0)"

Rxx

엑셀 스 니펫


2
ns.formula.. 당신 R에 생각 하십니까 ?! 진지하게 귀하의 방법은 매우 유용 해 보이지만 이러한 매개 변수를 얻으려면 해킹을 해킹 해야하는 것은 역설적입니다. 테이블을 출력하는 데 매우 유용합니다.
geotheory

이것은 어리석은 질문 일 수 있습니다.하지만 플롯하는 4 개의 스플라인입니까 아니면 하나의 스플라인의 4 기초입니까?
Erosennin

@Erosennin 나는 "하나의 스플라인"의 의미에 달려 있습니다. 이 네 개의 곡선은 내 대답을 소개하는 세 개의 글 머리 기호로 설명 된 것처럼 4 개의 간격으로 조각으로 입방체이며 간격이 만나는 3 개의 지점에서 연속적으로 두 번째로 차별화되는 스플라인의 기초입니다.
whuber

감사! 나는 nitpicking을 의미하지는 않았다. 그것은 단지 네 개의 스플라인이 있고 (대답에서) 네 개의 곡선이 아닌 것처럼 보입니다. 다시, 나는 단지 이해하려고 노력하고있다.
Erosennin

1
@Erosennin 문제 없습니다. 어쩌면 이것이 도움이 될 것입니다. "스플라인"은 회귀 피팅 프로세스에 의해 결정되는이 네 곡선의 선형 조합입니다. 또 다른 방법 : 스플라인은이 네 개의 커브를 선형 조합하여 만들 수있는 커브의 벡터 공간으로 구성됩니다.
whuber

4

이미 다음을 수행했습니다.

> rm(list=ls())
> set.seed(1066)
> x<- 1:1000
> y<- rep(0,1000)
> y[1:500]<- pmax(x[1:500]+(runif(500)-.5)*67*500/pmax(x[1:500],100),0.01)
> y[501:1000]<-500+x[501:1000]^1.05*(runif(500)-.5)/7.5
> df<-as.data.frame(cbind(x,y))
> library(splines)
> spline1 <- glm(y~ns(x,knots=c(500)),data=df,family=Gamma(link="log"))
> 

이제 두 가지 다른 방법으로 x = 12에 대한 (응답)을 예측하는 방법을 보여 드리겠습니다.

> new.dat=data.frame(x=12)
> predict(spline1,new.dat,type="response")
       1 
68.78721 

두 번째 방법은 모델 매트릭스를 직접 기반으로합니다. 사용 exp된 링크 기능이 로그이기 때문에 사용했습니다.

> m=model.matrix( ~ ns(df$x,knots=c(500))) 
> prd=exp(coefficients(spline1) %*% t(m)) 
> prd[12]
[1] 68.78721

위의 12 번째 요소는 x = 12에 해당하므로 추출했습니다. 트레이닝 세트 외부의 x를 예측하려면 간단히 예측 기능을 다시 사용할 수 있습니다. x = 1100에 대해 예측 된 반응 값을 찾고 싶다고하자

> predict(spline1, newdata=data.frame(x=1100),type="response")
       1 
366.3483 

당신의 응답을 주셔서 감사합니다! 그러나 여전히 혼란 스럽습니다. 이 매트릭스로 무엇을해야할지 잘 모르겠습니다. 예를 들어, x = 12 인 경우 y = 68.78721을 예측하지만 해당 행렬에서 12를 조회하면 0.016816392가됩니다. x <500의 원래 절편과 계수는 각각 4.174603과 3.830416입니다. exp (4.174603 + 3.8304116 * 0.016816392) <> 68.78721. 또한 x가 훈련 세트에 없으면 어떻게 x 값을 얻을 수 있습니까?
Eric

나는 대답을 바꿨다.
통계

x가 훈련 세트에없는 경우에 대한 코드를 추가했습니다.
Stat

2
예측 함수를 사용하지 않고 x = 1100에 대해 366.3483을 얻는 방법이 있습니까?
Eric

4

R rms패키지를 사용하여 3 차 회귀 스플라인에 대해 잘린 전력 기준을 사용하는 것이 더 쉽다는 것을 알 수 있습니다 . 모델을 맞추면의 Function또는 latex함수를 사용하여 피팅 된 스플라인 함수의 대수적 표현을 검색 할 수 있습니다 .rms .


고맙습니다. 실제로 게시하기 전에 stats.stackexchange.com/questions/67607/…에서 귀하의 답변을 읽었습니다 . 나는 rms로 할 수있는 일을 더 잘 이해해야한다고 생각합니다.
Eric

에 대한 문서 Function()는 실제로 무엇을 말하지는 않습니다. 내 경우에는 (Rpubs에 대한 자세한 내용을 참조 rpubs.com/EmilOWK/rms_splines을 , 나는 수) 값이 모델은 최초의 COEF이고 , 두 번째와 마지막 COEF는 방정식 어디에서 볼 수 없습니다. 의 출력에도 동일하게 적용됩니다 . function(x = NA) {-2863.7787+245.72672* x-0.1391794*pmax(x-10.9,0)^3+0.27835881*pmax(x-50.5,0)^3-0.1391794*pmax(x-90.1,0)^3 } <environment: 0x556156e80db8>-2863.7787245.72672-873.0223latex()
Deleet

Function스플라인 함수로 Glm()사용할 때 작동 rcs합니다. 출력은 RMS 코스 노트에 설명 된 것처럼 선형 테일 제한이없는 것처럼 작성하여 스플라인을 가장 간단한 형태로 표현 합니다 .
Frank Harrell
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.