"PCA ถ่วงน้ำหนักทางภูมิศาสตร์" เป็นคำอธิบายที่ดีมาก: ในR
โปรแกรมนั้นจะเขียนเอง (ต้องการบรรทัดความคิดเห็นมากกว่าบรรทัดโค้ดจริง)
เริ่มต้นด้วยน้ำหนักเพราะนี่คือส่วนที่ PCA ให้น้ำหนักกับ บริษัท จาก PCA คำว่า "ทางภูมิศาสตร์" หมายถึงน้ำหนักขึ้นอยู่กับระยะทางระหว่างจุดฐานและที่ตั้งข้อมูล มาตรฐาน - แต่ไม่ได้หมายถึง - การถ่วงน้ำหนักเป็นฟังก์ชันเกาส์เซียน; นั่นคือการสลายตัวแบบเอกซ์โปเนนเชียลด้วยระยะห่างกำลังสอง ผู้ใช้จำเป็นต้องระบุอัตราการสลายตัวหรือ - เพิ่มเติมอย่างสังหรณ์ใจ - ระยะทางลักษณะที่จำนวนการสลายตัวคงที่เกิดขึ้น
distance.weight <- function(x, xy, tau) {
# x is a vector location
# xy is an array of locations, one per row
# tau is the bandwidth
# Returns a vector of weights
apply(xy, 1, function(z) exp(-(z-x) %*% (z-x) / (2 * tau^2)))
}
PCA ใช้กับความแปรปรวนร่วมหรือเมทริกซ์สหสัมพันธ์ (ซึ่งได้มาจากความแปรปรวนร่วม) จากนั้นที่นี่เป็นฟังก์ชั่นในการคำนวณค่าความแปรปรวนร่วมแบบถ่วงน้ำหนักในวิธีที่มีเสถียรภาพเชิงตัวเลข
covariance <- function(y, weights) {
# y is an m by n matrix
# weights is length m
# Returns the weighted covariance matrix of y (by columns).
if (missing(weights)) return (cov(y))
w <- zapsmall(weights / sum(weights)) # Standardize the weights
y.bar <- apply(y * w, 2, sum) # Compute column means
z <- t(y) - y.bar # Remove the means
z %*% (w * t(z))
}
ความสัมพันธ์นั้นได้มาจากวิธีปกติโดยใช้ค่าเบี่ยงเบนมาตรฐานสำหรับหน่วยการวัดของตัวแปรแต่ละตัว:
correlation <- function(y, weights) {
z <- covariance(y, weights)
sigma <- sqrt(diag(z)) # Standard deviations
z / (sigma %o% sigma)
}
ตอนนี้เราสามารถทำ PCA:
gw.pca <- function(x, xy, y, tau) {
# x is a vector denoting a location
# xy is a set of locations as row vectors
# y is an array of attributes, also as rows
# tau is a bandwidth
# Returns a `princomp` object for the geographically weighted PCA
# ..of y relative to the point x.
w <- distance.weight(x, xy, tau)
princomp(covmat=correlation(y, w))
}
(นั่นคือโค้ดที่สามารถเรียกใช้งานได้สุทธิ 10 บรรทัดจนถึงตอนนี้เราจะต้องเพิ่มอีกเพียงหนึ่งอันด้านล่างหลังจากเราอธิบายกริดที่จะทำการวิเคราะห์)
มาแสดงตัวอย่างกับข้อมูลตัวอย่างแบบสุ่มเปรียบเทียบกับที่อธิบายไว้ในคำถาม: ตัวแปร 30 ตัวที่ 550 ตำแหน่ง
set.seed(17)
n.data <- 550
n.vars <- 30
xy <- matrix(rnorm(n.data * 2), ncol=2)
y <- matrix(rnorm(n.data * n.vars), ncol=n.vars)
การคำนวณน้ำหนักทางภูมิศาสตร์มักดำเนินการในชุดของสถานที่ที่เลือกเช่นตามแนวตัดขวางหรือที่จุดของกริดปกติ ลองใช้กริดหยาบเพื่อรับมุมมองเกี่ยวกับผลลัพธ์ ต่อมา - เมื่อเรามั่นใจว่าทุกอย่างทำงานได้และเราได้สิ่งที่ต้องการ - เราสามารถปรับแต่งกริด
# Create a grid for the GWPCA, sweeping in rows
# from top to bottom.
xmin <- min(xy[,1]); xmax <- max(xy[,1]); n.cols <- 30
ymin <- min(xy[,2]); ymax <- max(xy[,2]); n.rows <- 20
dx <- seq(from=xmin, to=xmax, length.out=n.cols)
dy <- seq(from=ymin, to=ymax, length.out=n.rows)
points <- cbind(rep(dx, length(dy)),
as.vector(sapply(rev(dy), function(u) rep(u, length(dx)))))
มีคำถามว่าข้อมูลใดที่เราต้องการเก็บจาก PCA แต่ละรายการ โดยปกติแล้ว PCA สำหรับnตัวแปรส่งกลับรายการที่เรียงลำดับของnค่าลักษณะเฉพาะและ - ในรูปแบบต่างๆ - รายการที่สอดคล้องกันของnเวกเตอร์ของแต่ละคนความยาวn นั่นคือตัวเลข n * (n + 1) เพื่อทำแผนที่! นำเอาสัญญาณจากคำถามมาแมปค่าลักษณะเฉพาะ สิ่งเหล่านี้ถูกแยกออกมาจากผลลัพธ์ของgw.pca
ผ่านทางแอ$sdev
ททริบิวต์ซึ่งเป็นรายการของค่าลักษณะเฉพาะโดยค่าจากมากไปน้อย
# Illustrate GWPCA by obtaining all eigenvalues at each grid point.
system.time(z <- apply(points, 1, function(x) gw.pca(x, xy, y, 1)$sdev))
สิ่งนี้จะเสร็จสมบูรณ์ในเวลาน้อยกว่า 5 วินาทีในเครื่องนี้ ขอให้สังเกตว่าระยะทางที่มีลักษณะเฉพาะ (หรือ "แบนด์วิดธ์") 1 gw.pca
ถูกใช้ในการเรียกร้องให้
ส่วนที่เหลือเป็นเรื่องของการถูขึ้น ลองแมปผลลัพธ์ด้วยraster
ไลบรารี (แต่อาจเขียนผลลัพธ์ในรูปแบบกริดแทนการประมวลผลด้วย GIS แทน)
library("raster")
to.raster <- function(u) raster(matrix(u, nrow=n.cols),
xmn=xmin, xmx=xmax, ymn=ymin, ymx=ymax)
maps <- apply(z, 1, to.raster)
par(mfrow=c(2,2))
tmp <- lapply(maps, function(m) {plot(m); points(xy, pch=19)})
นี่เป็นสี่แผนที่แรกจาก 30 แผนที่แสดงค่าลักษณะเฉพาะที่ใหญ่ที่สุดสี่แห่ง (อย่าตื่นเต้นเกินไปกับขนาดของพวกเขาซึ่งเกิน 1 ในทุกสถานที่จำได้ว่าข้อมูลเหล่านี้ถูกสร้างขึ้นแบบสุ่มทั้งหมดและถ้าพวกเขามีโครงสร้างความสัมพันธ์ใด ๆ เลย - ซึ่งค่าลักษณะเฉพาะขนาดใหญ่ในแผนที่เหล่านี้ดูเหมือนจะบ่งบอก - มันเป็นเพราะโอกาสเพียงอย่างเดียวและไม่ได้สะท้อนอะไร "ของจริง" ที่อธิบายกระบวนการสร้างข้อมูล)
เป็นคำแนะนำในการเปลี่ยนแบนด์วิดธ์ หากมีขนาดเล็กเกินไปซอฟต์แวร์จะบ่นเกี่ยวกับสิ่งแปลกประหลาด (ฉันไม่ได้สร้างในการตรวจสอบข้อผิดพลาดใด ๆ ในการใช้งานกระดูกเปลือยนี้) แต่การลดจาก 1 เป็น 1/4 (และใช้ข้อมูลเดิมเหมือนเดิม) จะให้ผลลัพธ์ที่น่าสนใจ:
สังเกตแนวโน้มของจุดรอบ ๆ ขอบเขตเพื่อให้ค่าลักษณะเฉพาะขนาดใหญ่ผิดปกติ (แสดงในตำแหน่งสีเขียวของแผนที่ด้านซ้ายมือ) ในขณะที่ค่าลักษณะเฉพาะอื่น ๆ จะถูกชดเชยเพื่อชดเชย (แสดงโดยสีชมพูอ่อนในอีกสามแผนที่) . ปรากฏการณ์นี้และรายละเอียดปลีกย่อยอื่น ๆ ของ PCA และการกำหนดน้ำหนักทางภูมิศาสตร์จะต้องมีการทำความเข้าใจก่อนจึงจะสามารถหวังได้ว่าจะตีความรุ่น PCA ที่มีน้ำหนักตามภูมิศาสตร์ได้อย่างน่าเชื่อถือ แล้วมีอีก 30 * 30 = 900 eigenvectors (หรือ "loadings") ที่ต้องพิจารณา ...