如何基于控制变量计算空间距离矩阵(R语言)
问题描述
我想要结合空间数据与两个控制变量,用自定义欧氏距离函数计算距离矩阵,以此通过层次聚类划分“地理市场”。我手头有包含买卖双方城市、坐标、采购量及两个控制变量的空间数据集,目标距离公式为:
√[(xᵢ-xⱼ)²+(yᵢ-yⱼ)²+(v1ᵢ-v1ⱼ)²+(v2ᵢ-v2ⱼ)²]
其中x为经度,y为纬度,v1、v2为两个控制变量。我尝试了以下代码,但不确定对象W是否正确:
# Sample data (because is private info). set.seed(123) n <- 100 cities <- c("City1", "City2", "City3", "City4", "City5") seller_city <- sample(cities, n, replace = TRUE) buyer_city <- sample(cities, n, replace = TRUE) seller_coords <- data.frame(lon = rnorm(n, -80, 1), lat = rnorm(n, 40, 1)) buyer_coords <- data.frame(lon = rnorm(n, -80, 1), lat = rnorm(n, 40, 1)) quantity <- rpois(n, 10) var1 <- rnorm(n, 0, 1) #First control variable. var2 <- rnorm(n, 0, 1) #Second control variable. df <- data.frame(seller_city, buyer_city, seller_coords, buyer_coords, quantity, var1, var2) # Compute distance matrix city_dist <- distm(x =df[,c("lon", "lat")] , y = df[,c("lon.1", "lat.1")]) city_dist <- (city_dist - mean(city_dist)) / sd(city_dist) #Normalising, because its units differ to the control variables. var_dist <- as.matrix(dist(df %>% select(var1, var2))) var_dist <- (var_dist - mean(var_dist)) / sd(var_dist) #Normalising, because its units differ to the control variables. W <- city_dist + var_dist # sum up # Perform hierarchical clustering hc <- hclust(as.dist(W), method = "ward.D2")
解答
你的W不符合目标公式,核心问题是:
当前代码先分别计算空间坐标维度的两两欧氏距离矩阵和控制变量维度的两两欧氏距离矩阵,各自标准化后直接相加。但这和你想要的“四个维度联合计算欧氏距离”逻辑完全不同——目标公式是将四个特征放在同一空间下计算距离,而非两个子空间距离的叠加。
正确实现方式
1. 明确聚类对象
如果目标是划分地理市场(城市聚类),需先将交易数据聚合到城市层面(比如取每个城市的平均坐标、平均控制变量值);如果是对交易样本聚类,可直接用每行数据的特征。
2. 标准化单个特征后计算联合欧氏距离
不同特征量纲不同,需先对每个特征(经度、纬度、var1、var2)单独标准化,再基于标准化后的特征矩阵计算两两欧氏距离,这才符合你给出的目标公式。
修正代码
情况1:对城市聚类(符合地理市场划分目标)
library(dplyr) library(geosphere) # 聚合城市层面的数据(以卖家城市为例,可根据需求替换为买家城市或合并) city_level_df <- df %>% group_by(seller_city) %>% summarise( lon = mean(lon), lat = mean(lat), var1 = mean(var1), var2 = mean(var2) ) %>% ungroup() # 标准化每个特征 scaled_city_df <- city_level_df %>% mutate(across(c(lon, lat, var1, var2), scale)) # 计算符合公式的联合欧氏距离矩阵 W_correct <- dist(scaled_city_df[, -1]) # 排除城市名称列 # 层次聚类 hc <- hclust(W_correct, method = "ward.D2")
情况2:对交易样本聚类
library(dplyr) library(geosphere) # 标准化交易数据的四个特征(这里用卖家坐标,可根据需求替换为买家坐标) scaled_df <- df %>% mutate(across(c(lon, lat, var1, var2), scale)) # 计算符合公式的联合欧氏距离矩阵 W_correct <- dist(scaled_df[, c("lon", "lat", "var1", "var2")]) # 层次聚类 hc <- hclust(W_correct, method = "ward.D2")
关键说明
- 单个特征标准化:用
scale()对每个特征做Z-score标准化(均值为0,标准差为1),确保不同量纲的特征对距离的贡献均衡。 - 联合欧氏距离:
dist()函数默认计算欧氏距离,传入标准化后的四个特征列,得到的距离矩阵完全匹配你给出的公式。
内容的提问来源于stack exchange,提问作者SMD
相关产品推荐
相关产品推荐

