Rの非負変数の密度プロットの良い方法は?


36
plot(density(rexp(100))

明らかに、ゼロの左側のすべての密度はバイアスを表します。

私は非統計学者のためにいくつかのデータを要約したいと思っています。そして、非負データがゼロの左側の密度を持っている理由についての質問を避けたいです。プロットはランダム化チェック用です。治療グループと対照グループごとの変数の分布を示したい。分布はしばしば指数関数的です。ヒストグラムにはさまざまな理由で注意が必要です。

グーグルで簡単に検索すると、非負のカーネルに関する統計学者の研究が得られます。 例: this

しかし、Rに実装されているものはありますか?実装されたメソッドのうち、記述統計に関して何らかの方法で「最良」のメソッドはありますか?

編集:fromコマンドが現在の問題を解決できる場合でも、非負の密度推定に関する文献に基づいて誰かがカーネルを実装しているかどうかを知ることは素晴らしいことです


3
あなたが求めているものではありませんが、特に統計的でない聴衆へのプレゼンテーションのために、指数関数的であるべきものにカーネル密度推定を適用しません。分位-分位数プロットを使用し、分布が指数関数的である場合、プロットは直線でなければならないことを説明します。
ニックコックス

6
plot(density(rexp(100), from=0))
ステファンローラン

4
私が時々かなり成功したことの1つは、ログでkdeを取得し、密度推定を変換することです(ヤコビアンを忘れないでください)。もう1つの可能性は、境界を認識するように設定された対数スプライン密度推定を使用することです。
Glen_b -Reinstateモニカ


1
@Glen_bで言及されている変換方法については、stata-journal.com / sjpdf.html?articlenum = gr0003で説明しました(pp.76-78を参照)。ログではなくlog(x + 1)を使用してヤコビアンを変更することにより、ゼロに対応できます。
ニックコックス

回答:


21

空間統計のエッジ重み付けのアプローチから借用された1つのソリューションは、左側の密度をゼロで切り捨て、ゼロに最も近いデータの重みを増やすことです。考え方は、各値xを中心とする単位総面積のカーネルに「拡散」することです。負の領域にあふれるカーネルの部分はすべて削除され、カーネルはユニット領域に再正規化されます。xx

たとえば、ガウスカーネル、再正規化重みでありますKh(y,x)=exp(12((yx)/h)2)/2π

wバツ=1/0Kyバツdy=11Φバツh0

ここで、は平均xと標準偏差hの正規変量の累積分布関数です。他のカーネルでも同等の数式を使用できます。Φバツh

これは、近い帯域幅を狭めようとするよりも単純で、計算がはるかに高速です。とにかく、0付近で帯域幅をどのように変更するかを正確に規定することは困難です。それにもかかわらず、この方法もアドホックです:0の近くにまだバイアスがあります。デフォルトの密度推定よりもうまく機能するようです。以下は、大きなデータセットを使用した比較です。000

図

青はデフォルトの密度を示し、赤はのエッジに対して調整された密度を示します。真の基礎となる分布は、参照用の点線としてトレースされます。0


Rコード

density関数はR、すべての実数の積分を1にしたいので、重みの合計が1でないことを訴えますが、このアプローチは正の数の積分を1に等しくします。チェックとして、後者の積分はリーマン和として推定されます。

set.seed(17)
x <- rexp(1000)
#
# Compute a bandwidth.
#
h <- density(x, kernel="gaussian")$bw # $
#
# Compute edge weights.
#
w <- 1 / pnorm(0, mean=x, sd=h, lower.tail=FALSE)
#
# The truncated weighted density is what we want.
#
d <- density(x, bw=h, kernel="gaussian", weights=w / length(x))
d$y[d$x < 0] <- 0
#
# Check: the integral ought to be close to 1:
#
sum(d$y * diff(d$x)[1])
#
# Plot the two density estimates.
#
par(mfrow=c(1,1))
plot(d, type="n", main="Default and truncated densities", xlim=c(-1, 5))
polygon(density(x, kernel="gaussian", bw=h), col="#6060ff80", border=NA)
polygon(d, col="#ff606080", border=NA)
curve(exp(-x), from=0, to=max(x), lty=2, add=TRUE)

21

別の方法は、スプラインを使用して密度を推定し、データのログ密度を概算することに基づいたKooperbergと同僚のアプローチです。@whuberの回答からのデータを使用した例を示します。これにより、アプローチの比較が可能になります。

set.seed(17)
x <- rexp(1000)

そのためには、logsplineパッケージをインストールする必要があります。そうでない場合はインストールしてください:

install.packages("logspline")

パッケージを読み込み、logspline()関数を使用して密度を推定します。

require("logspline")
m <- logspline(x)

以下では、d@ whuberの答えからのオブジェクトがワークスペースに存在すると仮定します。

plot(d, type="n", main="Default, truncated, and logspline densities", 
     xlim=c(-1, 5), ylim = c(0, 1))
polygon(density(x, kernel="gaussian", bw=h), col="#6060ff80", border=NA)
polygon(d, col="#ff606080", border=NA)
plot(m, add = TRUE, col = "red", lwd = 3, xlim = c(-0.001, max(x)))
curve(exp(-x), from=0, to=max(x), lty=2, add=TRUE)
rug(x, side = 3)

結果のプロットを以下に示します。logspline密度は赤い線で示されます

デフォルト、切り捨て、およびログスプライン密度

さらに、密度のサポートは、引数lboundおよびを使用して指定できますubound。密度が0の左側の0であり、0で不連続性があると仮定する場合lbound = 0、の呼び出しで使用できます。logspline()たとえば、

m2 <- logspline(x, lbound = 0)

次の密度推定値をm取得します(前の図がすでにビジーになっていたため、元のログスプラインに合わせてここに表示)。

plot.new()
plot.window(xlim = c(-1, max(x)), ylim = c(0, 1.2))
title(main = "Logspline densities with & without a lower bound",
      ylab = "Density", xlab = "x")
plot(m,  col = "red",  xlim = c(0, max(x)), lwd = 3, add = TRUE)
plot(m2, col = "blue", xlim = c(0, max(x)), lwd = 2, add = TRUE)
curve(exp(-x), from=0, to=max(x), lty=2, add=TRUE)
rug(x, side = 3)
axis(1)
axis(2)
box()

結果のプロットを以下に示します

サポートの下限の有無によるログスプライン密度推定の比較

xバツ=0x


1
01

@whuber良い質問です。私は最近、このアプローチに出くわしました。ここで尋ねるべき良い質問は、切り捨てられた方法とログスプラインの方法は真の密度の単なる推定値であるため、適合の差は統計的に有意ですか?しかし、なぜそれがゼロでうまくいくのか正確にはわかりません。理由も知っていただければ幸いです。
モニカの復職-G.シンプソン

@GavinSimpson、このいい答えをありがとう。の最新バージョンで最後のプロットを再現できますlogsplineか?私にとっては、有界バージョンと無界バージョンの両方の密度がゼロになりx = 0ます。
セル14年

4

グループごとの分布を比較するには(コメントの1つで目標としています)、もっと単純なものはありませんか?Nが大きい場合、平行箱型図はうまく機能します。平行ストリッププロットは、Nが小さい場合に機能します(両方とも異常値を示します。これはデータの問題です)。


1
ええ、ありがとう、うまくいきました。しかし、私は密度プロットが好きです。それらは、箱ひげ図よりもデータについて多くを示しています。私は、すでに何も実装されていないように見えることにちょっと驚いていると思います。たぶん、私はいつか自分でこれらのことを実装するでしょう。人々はおそらくそれが便利だと思うでしょう。
generic_user

1
密度プロットも好きです。ただし、視聴者を考慮する必要があります。
ピーターフロム-モニカの復職

1
これについて@PeterFlomに同意する必要があります。視聴者が統計的に知識がなくても、複雑になりすぎないでください。また、上部にバタフライプロットを重ねて比較/並列ボックスプロットを行うこともできます。これにより、すべてのデータと同様に箱ひげ図の概要が表示されます。
-doug.numbers

集約されたプロットを異なる人々が異なる方法で理解するという提案は確かに正しいです。密度プロットが何であるかを理解しているにもかかわらず(そして、それが確率ではないことを理解しているにもかかわらず)、「並列箱ひげ図」が何であるかを理解していません。それは平行座標プロットを示唆していますが、それは正しくないと思います。
DWin

2

Stéphaneがコメントするようfrom = 0に、使用することができ、さらに、密度曲線の下で値を表すことができますrug (x)


4
私が間違っているが、from=00未満の値のプロットを抑制するように見える場合は修正してください。それは、分布の一部が0未満に塗抹されたという事実のための計算が修正されない
ニック・コックス

1
それは正しいです。このfromコマンドを使用すると、ゼロのすぐ右側にピークがあるように見えるプロットが生成されます。しかし、継続的に小さなビンでヒストグラムを見ると、多くのデータがピークATゼロを示しています。これfromは単なるグラフィカルなトリックです。
generic_user

@NickCoxよくわかりませんが、from=0何も抑制しないと思います。「グリッド」をゼロから開始するだけです。
ステファンローラン

違いは、プロットされているかどうかではなく、推定値が負の値に対してゼロ以外であるかどうかです。研究者は、必要なのが視覚化だけである場合、これについて心配しないことを決定する場合があります。
ニックコックス

@NickCoxコマンドはdensity(rexp(100), from=0)、グラフィックとは何の関係もありません
ステファン・ローラン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.