データを平滑化し、単調性を強制する方法


14

平滑化されたポイントが単調に減少するように、平滑化するデータがいくつかあります。私のデータは急激に減少し、その後横ばいになり始めます。Rを使用した例を次に示します

df <- data.frame(x=1:10, y=c(100,41,22,10,6,7,2,1,3,1))
ggplot(df, aes(x=x, y=y))+geom_line()

平滑化するデータのプロット

使用できる優れた平滑化手法は何ですか?また、最初の平滑化されたポイントを強制的に観測ポイントに近づけることができればいいと思います。


1
サンプル値が整数であることに気付きました。あなたの本当の価値は重要ですか?もしそうであれば(これは単調性の保証ではありませんが、これらのようなデータに対しては一般にそれを与えます)、このような何かが役に立つかもしれません:plot(y~x,data=df); f=fitted( glm( y~ns(x,df=4), data=df,family=quasipoisson)); lines(df$x,f)
Glen_b -Reinstate Monica

回答:


18

これを行うには、mgcvパッケージのmono.con()and pcls()関数を使用して、単調性制約のあるペナルティスプラインを使用します。これらの関数はのようにユーザーフレンドリーではないため、やることが少しありますが、手順は以下に示します。主にの例に基づいて、与えたサンプルデータに合わせて修正します。gam()?pcls

df <- data.frame(x=1:10, y=c(100,41,22,10,6,7,2,1,3,1))

## Set up the size of the basis functions/number of knots
k <- 5
## This fits the unconstrained model but gets us smoothness parameters that
## that we will need later
unc <- gam(y ~ s(x, k = k, bs = "cr"), data = df)

## This creates the cubic spline basis functions of `x`
## It returns an object containing the penalty matrix for the spline
## among other things; see ?smooth.construct for description of each
## element in the returned object
sm <- smoothCon(s(x, k = k, bs = "cr"), df, knots = NULL)[[1]]

## This gets the constraint matrix and constraint vector that imposes
## linear constraints to enforce montonicity on a cubic regression spline
## the key thing you need to change is `up`.
## `up = TRUE` == increasing function
## `up = FALSE` == decreasing function (as per your example)
## `xp` is a vector of knot locations that we get back from smoothCon
F <- mono.con(sm$xp, up = FALSE)   # get constraints: up = FALSE == Decreasing constraint!

ここで、pcls()フィットさせたいペナルティ付き制約付きモデルの詳細を含むために渡されるオブジェクトに入力する必要があります

## Fill in G, the object pcsl needs to fit; this is just what `pcls` says it needs:
## X is the model matrix (of the basis functions)
## C is the identifiability constraints - no constraints needed here
##   for the single smooth
## sp are the smoothness parameters from the unconstrained GAM
## p/xp are the knot locations again, but negated for a decreasing function
## y is the response data
## w are weights and this is fancy code for a vector of 1s of length(y)
G <- list(X = sm$X, C = matrix(0,0,0), sp = unc$sp,
          p = -sm$xp, # note the - here! This is for decreasing fits!
      y = df$y,
          w = df$y*0+1)
G$Ain <- F$A    # the monotonicity constraint matrix
G$bin <- F$b    # the monotonicity constraint vector, both from mono.con
G$S <- sm$S     # the penalty matrix for the cubic spline
G$off <- 0      # location of offsets in the penalty matrix

これでようやくフィッティングを行うことができます

## Do the constrained fit 
p <- pcls(G)  # fit spline (using s.p. from unconstrained fit)

pスプラインに対応する基底関数の係数のベクトルが含まれています。近似スプラインを視覚化するために、xの範囲で100箇所のモデルから予測できます。100個の値を使用して、プロット上にすてきな滑らかな線を取得します。

## predict at 100 locations over range of x - get a smooth line on the plot
newx <- with(df, data.frame(x = seq(min(x), max(x), length = 100)))

予測値を生成するにはPredict.matrix()、を使用します。これにより、係数による倍数pが近似モデルから予測値を生成するような行列が生成されます。

fv <- Predict.matrix(sm, newx) %*% p
newx <- transform(newx, yhat = fv[,1])

plot(y ~ x, data = df, pch = 16)
lines(yhat ~ x, data = newx, col = "red")

これにより、以下が生成されます。

ここに画像の説明を入力してください

ggplotでプロットするためのデータを整然とした形式にするのはあなたにお任せします...

の基底関数の次元を大きくすることで、(最初のデータ点によりスムーズにフィットさせることについての質問に部分的に答えるために)近似を強制できますx。たとえば、()にk等しく設定し、上記のコードを再実行すると、8k <- 8

ここに画像の説明を入力してください

kこれらのデータをこれ以上高くすることはできません。また、オーバーフィッティングに注意する必要があります。すべてpcls()がやっているのは、制約と与えられた基底関数を与えられたペナルティ最小二乗問題を解くことです、それはあなたのために滑らかさの選択を実行していません-私が知っていることではありません...)

補間が必要な場合は?splinefun、単調性制約のあるエルミートスプラインとキュービックスプラインを持つベースR関数を参照してください。この場合、データは厳密には単調ではないため、これは使用できません。


ありがとう。あなたのソリューションは適切なものであると確信していますが、それは非常に複雑で難読化されているため、使用できません。 splinefun同様に私の最初の考えでした(私は補間しています)がspline(x=df$x, y=df$y, n=nrow(df), method="monoH.FC")spline(x=df$x, y=df$y, n=nrow(df), method="hyman")両方ともエラーを発生させる
ベン

1
試してみれば、それを使用できると確信しています。ここでは、フードの下で何が起こっているのかほとんど分かりませんが、私はそれを解決し、物事を変える必要がある場所を示しました。もちろん、ある程度のRを知っていると仮定します。詳細の大部分は実装的なものであり、単調に制約されたスプラインに合わせたい場合は無視できます。コードにもう少し注釈を付けて、各ステップが何をしているのかをさらに強調してほしいですか?のリファレンスに?mono.conは、メソッドの詳細が記載されています。
モニカの復活-G.シンプソン

なぜsplinefunエラーが発生するのか; 気づいたところですが、それ自体が単調ではないデータを補間する単調スプラインを当てはめることができます。の観測x = 6yは、の観測値よりも大きくなっていx = 5ます。あなたは答えのその部分を無視する必要があります:-)
モニカを回復-G.シンプソン

とった。必要ありません-私はかなり経験豊富なRユーザーです。私は自分が使用しているものの背後にある数学を理解したいだけで、この解決策は内部で非常に多くのことが行われているように見えます。ご協力ありがとうございます。
ベン

それぞれのことを説明するために、いくつかのメモを追加しました。注意すべき主な点は、単調性制約がmono.con、3次スプラインに対して返される特定の不等式制約のセットによって課せられていることです。?pcls上記よりもユーザーフレンドリーではない薄板スプラインと加法モデルの例がありますが、これらのタイプのスプラインの数学に精通している場合は、より多くの数学を公開する可能性があります(私はそれほど馴染みがありません)。
モニカの復活-G.シンプソン

13

Natalya Pyaによる最近の詐欺パッケージとPya&Wood(2015)による論文「Shape constrained Additive Models」に基づくと、Gavinの優れた答えで言及されているプロセスの一部がはるかに簡単になります。

library(scam)
con <- scam(y ~ s(x, k = k, bs = "mpd"), data = df)
plot(con)

使用できるbs関数は多数あります。上記では、「単調減少Pスプライン」にmpdを使用しましたが、凸面または凹面を個別に、または単調制約と一緒に強制する関数もあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.