ポリゴンの共分散行列を見つける方法は?


9

一連の座標(x1,y1)...(xn,yn)によって定義されたポリゴンがあると想像してくださいX NY Nと質量の中心は、である(0,0)。多角形は、多角形の境界を持つ均一な分布として扱うことができます。 ここに画像の説明を入力してください

私は多角形の共分散行列を見つける方法の後にいます

ポリゴンの共分散行列は面積2次モーメントと密接に関連していると思いますが、それらが同等であるかどうかはわかりません。リンクしたWikipediaの記事にある数式は、多角形の主軸ではなく、x、y、z軸の周りの回転慣性を参照しているようです(この記事から推測すると、ここでは特にわかりません)。

(ちなみに、ポリゴンの主軸の計算方法を誰かに教えてもらえれば、それも役に立ちます)

座標PCAを実行するのは魅力的ですが、そうすると、座標が必ずしもポリゴンの周囲に均等に分散されないため、ポリゴンの密度が表されないという問題が発生します。極端な例は、ノースダコタの輪郭です。そのポリゴンは、レッドリバーに続く多数のポイントと、州の西端を定義するポイントが2つだけ多いことによって定義されます。


「見つける」とは、多角形から単純にサンプリングしてから、サンプルの共分散を計算することを想定していますが、あなたは何を考えていませんか?
Stephan Kolassa

また、あなたの投稿を編集してポリゴンの座標を含めて、人々がそれをいじることができるようにできますか?
ステファンコラサ

1
@StephanKolassa多角形を、多角形の境界を持つ均一な2変量確率密度として扱うことを意味します。確かに、ポイントをサンプリングでき、制限も同じですが、私は先験的な方法を探しています。写真は私が使った絵の具のイラストです。私が利用しようとしている実世界のデータは、州や地域の概要です。
インゴリフ

1
「共分散行列」の通常の用語は慣性モーメントまたは二次モーメントであることは正しいです。主軸は固有方向を向いています。座標でのPCAの実行は正しくありません。すべての質量が頂点にあると仮定することと同じです。重心の最も直接的な計算方法(最初の瞬間)は、gis.stackexchange.com / a / 22744/664にある私の投稿で説明されています。2次モーメントは、マイナーな変更を加えて同じ方法で計算されます。球には特別な配慮が必要です。
whuber

2
μk,l(P)=Pxkyldxdy
Pωdω=xkyldxdy.xkyl+1dxxk+1yldy

回答:


10

最初にいくつかの分析を行いましょう。

多角形内で、その確率密度が比例関数 次に、比例定数は、ポリゴン上のの積分の逆数です。Pp(x,y).p

μ0,0(P)=Pp(x,y)dxdy.

ポリゴンの重心は、最初のモーメントとして計算される平均座標のポイントです。最初は

μ1,0(P)=1μ0,0(P)Pxp(x,y)dxdy.

慣性テンソルは、第二モーメントの対称的なアレイが原点にその重心を置くためにポリゴンを変換した後に計算されるように表すことができる:、の行列である中央の第二モーメント

μk,l(P)=1μ0,0(P)P(xμ1,0(P))k(yμ0,1(P))lp(x,y)dxdy

ここで、範囲はからから テンソル自体(別名共分散行列)は、(k,l)(2,0)(1,1)(0,2).

I(P)=(μ2,0(P)μ1,1(P)μ1,1(P)μ0,2(P)).

のPCAは、主軸を生成しますこれらは、固有値でスケーリングされた単位固有ベクトルです。I(P)P:


次に、計算方法を考えてみましょう。 多角形は、その方向付けられた境界を記述する一連の頂点として提示されるため、呼び出すのは自然ですP,

グリーンの定理: whereは、と近傍で定義された1つの形式です

Pdω=Pω
ω=M(x,y)dx+N(x,y)dyP
dω=(xN(x,y)yM(x,y))dxdy.

たとえば、と定数(つまり、均一)密度場合、(検査により)多くの1つを選択できますなどの解dω=xkyldxdyp,

ω(x,y)=1l+1xkyl+1dx.

これのポイントは、等高線積分が一連の頂点によって決定される線分セグメントに従うことです。頂点から頂点までの任意のラインセグメントは、次の形式の実数変数によってパラメーター化できます。uvt

tu+tw

ここで、は、からへの単位法線方向値、したがって範囲に このパラメータ化では、とは線形関数であり、とは線形関数です したがって、各エッジの輪郭積分の被積分関数多項式関数になり、小さいとwvuuv.t0|vu|.xytdxdydt.t,kl.


この分析の実装は、そのコンポーネントのコーディングと同じくらい簡単です。最低レベルでは、多項式1フォームを線分セグメントに統合する関数が必要です。より高いレベルの関数は、これらを集約して生および中心モーメントを計算して、重心および慣性テンソルを取得します。最後に、そのテンソルを操作して主軸(スケーリングされた固有ベクトル)を見つけることができます。R以下のコードはこの作業を実行します。それは効率のふりをしません:それは前述の分析の実際の応用を説明することだけを目的としています。各関数は単純であり、命名規則は分析のものに対応しています。

コードに含まれているのは、有効な閉じた、単純に接続された、自己交差しないポリゴンを生成する手順です(円に沿って点をランダムに変形し、閉じたループを作成するために開始点をその最終点として含めます)。これに続いて、ポリゴンをプロットし、その頂点を表示し、重心に隣接し、主軸を赤(最大)と青(最小)でプロットして、ポリゴン中心の正の方向の座標系を作成するいくつかのステートメントを次に示します。

ポリゴンと主軸を示す図

#
# Integrate a monomial one-form x^k*y^l*dx along the line segment given as an 
# origin, unit direction vector, and distance.
#
lintegrate <- function(k, l, origin, normal, distance) {
  # Binomial theorem expansion of (u + tw)^k
  expand <- function(k, u, w) {
    i <- seq_len(k+1)-1
    u^i * w^rev(i) * choose(k,i)
  }
  # Construction of the product of two polynomials times a constant.
  omega <- normal[1] * convolve(rev(expand(k, origin[1], normal[1])), 
                                expand(l, origin[2], normal[2]),
                                type="open")
  # Integrate the resulting polynomial from 0 to `distance`.
  sum(omega * distance^seq_along(omega) / seq_along(omega))
}
#
# Integrate monomials along a piecewise linear path given as a sequence of
# (x,y) vertices.
#
cintegrate <- function(xy, k, l) {
  n <- dim(xy)[1]-1 # Number of edges
  sum(sapply(1:n, function(i) {
    dv <- xy[i+1,] - xy[i,]               # The direction vector
    lambda <- sum(dv * dv)
    if (isTRUE(all.equal(lambda, 0.0))) {
      0.0
    } else {
      lambda <- sqrt(lambda)              # Length of the direction vector
      -lintegrate(k, l+1, xy[i,], dv/lambda, lambda) / (l+1)
    }
  }))
}
#
# Compute moments of inertia.
#
inertia <- function(xy) {
  mass <- cintegrate(xy, 0, 0)
  barycenter = c(cintegrate(xy, 1, 0), cintegrate(xy, 0, 1)) / mass
  uv <- t(t(xy) - barycenter)   # Recenter the polygon to obtain central moments
  i <- matrix(0.0, 2, 2)
  i[1,1] <- cintegrate(uv, 2, 0)
  i[1,2] <- i[2,1] <- cintegrate(uv, 1, 1)
  i[2,2] <- cintegrate(uv, 0, 2)
  list(Mass=mass,
       Barycenter=barycenter,
       Inertia=i / mass)
}
#
# Find principal axes of an inertial tensor.
#
principal.axes <- function(i.xy) {
  obj <- eigen(i.xy)
  t(t(obj$vectors) * obj$values)
}
#
# Construct a polygon.
#
circle <- t(sapply(seq(0, 2*pi, length.out=11), function(a) c(cos(a), sin(a))))
set.seed(17)
radii <- (1 + rgamma(dim(circle)[1]-1, 3, 3))
radii <- c(radii, radii[1])  # Closes the loop
xy <- circle * radii
#
# Compute principal axes.
#
i.xy <- inertia(xy)
axes <- principal.axes(i.xy$Inertia)
sign <- sign(det(axes))
#
# Plot barycenter and principal axes.
#
plot(xy, bty="n", xaxt="n", yaxt="n", asp=1, xlab="x", ylab="y",
     main="A random polygon\nand its principal axes", cex.main=0.75)
polygon(xy, col="#e0e0e080")
arrows(rep(i.xy$Barycenter[1], 2), 
       rep(i.xy$Barycenter[2], 2),
       -axes[1,] + i.xy$Barycenter[1],     # The -signs make the first axis .. 
       -axes[2,]*sign + i.xy$Barycenter[2],# .. point to the right or down.
       length=0.1, angle=15, col=c("#e02020", "#4040c0"), lwd=2)
points(matrix(i.xy$Barycenter, 1, 2), pch=21, bg="#404040")

+1うわー、これは素晴らしい答えです!
アメーバ

7

編集:whuberがすでに答えたことに気づかなかった。これは、問題に対する別の(おそらくあまりエレガントではない)アプローチの例として残しておきます。

共分散行列

ましょう、ポリゴン上の一様分布からランダムなポイントである領域と。共分散行列は次のとおりです。(X,Y)PA

C=[CXXCXYCXYCYY]

ここで、はの分散、はの分散、は間の共分散そして。ポリゴンの重心が原点にあるため、これはゼロ平均を想定しています。一様分布は、すべての点に一定の確率密度を割り当てます。したがって、CXX=E[X2]XCYY=E[Y2]YCXY=E[XY]XY1AP

(1)CXX=1APx2dVCYY=1APy2dVCXY=1APxydV

三角測量

ような複雑な領域を直接統合する代わりに、を三角形のサブ領域に分割することで問題を単純化できます。PPn

P=T1Tn

あなたの例では、1つの可能なパーティション分割は次のようになります。

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

三角測量を生成するにはさまざまな方法があります(ここを参照)。たとえば、頂点のDelaunay三角形分割を計算してから、外側にあるエッジを破棄できます(例のように非凸形である可能性があるため)。P

上の積分は、三角形上の積分の合計に分割できます。P

(2)CXX=1Ai=1nTix2dVCYY=1Ai=1nTiy2dVCXY=1Ai=1nTixydV

三角形には素晴らしく単純な境界があるため、これらの積分は評価が簡単です。

三角形を統合する

三角形の上に統合するには、さまざまな方法があります。この例では、三角形を単位正方形にマッピングするトリックを使用しました。重心座標に変換することをお勧めします。

以下は、頂点定義された任意の三角形に対する上記の積分の解です。みましょう:T(x1,y1),(x2,y2),(x3,y3)

vx=[x1x2x3]vy=[y1y2y3]1=[111]L=[100110111]

次に:

(3)Tx2dV=A6Tr(vxvxTL)Ty2dV=A6Tr(vyvyTL)TxydV=A12(1TvxvyT1+vxTvy)

すべてをまとめる

ましょうと各三角形の頂点のためのX / Y座標含む上記のように、。プラグに各三角形について、領域の項は相殺することを指摘します。これは解決策を与えます:vxivyiTi(3)(2)

(4)CXX=16i=1nTr(vxi(vxi)TL)CYY=16i=1nTr(vyi(vyi)TL)CXY=112i=1n(1Tvxi(vyi)T1+(vxi)Tvyi)

主軸

主軸は、PCAと同様に、共分散行列固有ベクトルによって与えられます。PCAとは異なり、サンプルデータポイントから推定するのではなく、分析式があります。頂点自体はの一様分布からの代表的なサンプルではないので、頂点のサンプル共分散行列を単純に取得することはできないことに注意してください。しかし、は見られるように、頂点の比較的単純な関数です。CCPC(4)


2
+1これは、方向付けされた三角形を許可することで簡略化でき、適切な三角形分割の必要性を排除します。代わりに、任意の中心を確立して、三角形の(符号付き)値を合計するだけです。総和の各項は最終的にエッジ関数であるため、このような総和は本質的にグリーンの定理を適用することと同じであることが簡単にわかりこのアプローチは、quantdec.com / SYSEN597 / GTKAV / section2 / chapter_11.htmの「エリア」セクションに示されています。OOPiPi+1:PiPi+1.
whuber

@whuber興味深い、これを指摘してくれてありがとう
user20160

これらの答えはどちらも良いですが、私の教育レベルを少し上回っています。それらを完全に理解していると確信したら、誰が賞金を手に入れられるかを理解しようとします。
インゴリフ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.