机器学习 + 城市规划第九期:地理加权回归(GWR)算法的应用

机器学习 + 城市规划第九期:地理加权回归(GWR)算法的应用

🧭 引言

在城市规划与空间分析中,我们常常面对这样的问题:某个变量(比如自行车使用量)是否在不同区域受到不同程度的影响?传统回归方法只能给出“全局平均效应”,而忽略了空间异质性。

这时,地理加权回归(GWR)就派上了用场。

🧠 什么是 GWR?

Geographically Weighted Regression(GWR) 是一种局部回归模型,它允许解释变量的回归系数在地理空间中发生变化。也就是说,它假设城市空间是“多样”的,而不是“一刀切”的。

与传统线性回归的对比:

模型假设适用
线性回归所有区域参数相同(全局)整体趋势建模
GWR每个位置参数不同(局部回归)空间异质建模

🧪 数据与研究背景

本期案例中,我们使用了一组城市区域的空间数据,每个观测点包含:

  • 经度、纬度
  • 自行车事故的严重性(作为因变量 Y)
  • 一个影响变量(该数据采用骑行者年龄,作为解释变量 X)

目标:分析这个城市特征因子在不同区域对自行车事故的空间作用差异

🧰 GWR 模型实现(Python)

我们使用 mgwrgeopandas 在 Python 中实现 GWR。以下是核心代码:

激活必要环境

# ===== 导入依赖库 =====
import pandas as pd
import geopandas as gpd
from shapely.geometry import Point
import numpy as np
np.float = float # 修复 mgwr 包中对 np.float 的兼容性问题
from mgwr.gwr import GWR
from mgwr.sel_bw import Sel_BW

# 配置 matplotlib 中文显示
import matplotlib
matplotlib.use('TkAgg')# 设置图像后端(防止警告)
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']# 设置中文字体
plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号

from gwr_tools import save_gwr_summary  # 引入我们自定义的结果保存函数

数据处理部分

# ===== 1. 读取数据 =====
df = pd.read_csv("shuju bike.csv", header=None)   # 读取无表头的 CSV
df.columns = ["lon", "lat", "Y", "X"]              # 人工指定列名
 
# 清洗数据
for col in ["lon", "lat", "Y", "X"]:
    df[col] = pd.to_numeric(df[col], errors="coerce")  # 转换为浮点型,非法值变 NaN
df.dropna(subset=["lon", "lat", "Y", "X"], inplace=True)  # 删除缺失值
df.reset_index(drop=True, inplace=True)

空间数据格式处理

# 构造空间数据
geometry = [Point(xy) for xy in zip(df["lon"], df["lat"])]  # 创建点对象
gdf = gpd.GeoDataFrame(df, geometry=geometry)               # 构建 GeoDataFrame
gdf.set_crs(epsg=4326, inplace=True)                        # 设置为地理坐标系
gdf = gdf.to_crs(epsg=3857)                                 # 转为平面投影(用于计算距离)

🌍 说明:GWR 建模需要空间坐标,且必须是平面坐标系(不能直接用经纬度计算距离)。

# ===== 2. 提取建模数据 =====
coords = np.array([(point.x, point.y) for point in gdf.geometry])  # 提取空间坐标
y = gdf["Y"].values.reshape((-1, 1))                                # 响应变量
X = gdf["X"].values.reshape((-1, 1))                                # 解释变量

📐 说明:将 GeoDataFrame 中的值提取为模型所需的 NumPy 数组格式。

模型自动化调优

# ===== 3. 带宽选择 + 模型拟合 =====
print("正在选择最优带宽,请稍候...")
selector = Sel_BW(coords, y, X)         # 初始化带宽选择器
bw = selector.search()                  # 自动寻找最优带宽
print(f"选定的最优带宽为:{bw}")

model = GWR(coords, y, X, bw)           # 初始化 GWR 模型
results = model.fit()                   # 拟合模型

⚙️ 说明

  • 带宽控制了“局部”的范围,是 GWR 的核心参数;
  • 自动选择带宽能让模型自适应当前数据分布;
  • 模型拟合后,会得到每个点上的局部系数、残差、局部 R² 等。

模型结果输出

print("\n======= GWR 模型结果汇总 =======")
print(results.summary())  # 打印模型整体统计结果

🧾 说明:输出的内容包括 AIC、残差平方和、R²、参数均值等关键指标。

# ===== 4. 保存结果到 GeoJSON,用于地图展示 =====
gdf["GWR_coef_X"] = results.params[:, 0]       # 每个点的局部系数
gdf["GWR_resid"] = results.resid_response      # 每个点的残差
gdf["local_R2"] = results.localR2              # 每个点的局部 R²
gdf.to_file("gwr_result.geojson", driver="GeoJSON")
print("\n📍 局部系数结果已保存为 'gwr_result.geojson'。")

🗺️ 说明:GeoJSON 文件可用于 QGISArcGIS 或 Python 中可视化,适合做地图渲染。

# ===== 5. 保存模型统计摘要为 CSV 文件(调用封装的函数)=====
save_gwr_summary(results, model, filename_prefix="bike_gwr")

📊 说明:这个函数会自动导出两个 CSV 文件:

  • bike_gwr_model_summary.csv:模型整体诊断指标;
  • bike_gwr_parameter_summary.csv:解释变量的系数分布统计(均值、标准差、最大/最小值等)。

📌 注意事项

  • 数据要转换为投影坐标系(如 EPSG:3857),以正确计算距离;
  • 坐标、变量需清洗成数值型;
  • 推荐封装函数保存模型摘要结果,便于后期分析。

📈 模型输出解读

在完成模型训练后,我们得到了以下关键输出:

🟡 局部回归系数(GWR_coef_X)

每个点上,该因子对骑行量的回归系数,可视化后形成“空间影响图”:

  • 正系数:该因子促进骑行
  • 负系数:该因子抑制骑行
  • 越大说明作用越强

🔵 局部 R²(local_R2)

说明 GWR 模型在某一地区拟合的好坏:

  • 高值:解释力强,变量在此有效;
  • 低值:说明可能有其他重要变量未纳入。

🔴 残差分布(GWR_resid)

揭示模型预测误差,辅助识别系统性低估或高估区域。

📊 模型摘要自动输出

我们使用封装函数 save_gwr_summary() 自动保存:
封装包名称为gwr_tools.py

代码如下:

# gwr_tools.py
import pandas as pd
import numpy as np

def save_gwr_summary(results, model, filename_prefix='gwr'):
    """
    保存 GWR 模型结果摘要为两个 CSV 文件:
    1. {prefix}_model_summary.csv  - 模型整体指标
    2. {prefix}_parameter_summary.csv - 各变量参数统计
    """
    summary_dict = {}

    # 模型诊断与整体指标
    summary_dict["RSS"] = results.RSS
    summary_dict["trace(S)"] = results.tr_S
    summary_dict["DoF (n - trace(S))"] = results.n - results.tr_S
    summary_dict["sigma"] = np.sqrt(results.RSS / (results.n - results.tr_S))  # ✅ 用公式替代
    summary_dict["log_likelihood"] = results.llf
    summary_dict["AIC"] = results.aic
    summary_dict["AICc"] = results.aicc
    summary_dict["BIC"] = results.bic
    summary_dict["R2"] = results.R2
    summary_dict["Adj_R2"] = results.adj_R2

    # 写入整体模型信息文件
    summary_df = pd.DataFrame(list(summary_dict.items()), columns=["Metric", "Value"])
    summary_df.to_csv(f"{filename_prefix}_model_summary.csv", index=False, encoding="utf-8-sig")

    # 各变量参数统计
    param_stats = []
    var_names = [f"X{i}" for i in range(results.params.shape[1])]
    for i, name in enumerate(var_names):
        param_stats.append({
            "Variable": name,
            "Mean": np.round(results.params[:, i].mean(), 6),
            "Std": np.round(results.params[:, i].std(), 6),
            "Min": np.round(results.params[:, i].min(), 6),
            "Median": np.round(np.median(results.params[:, i]), 6),
            "Max": np.round(results.params[:, i].max(), 6)
        })

    param_df = pd.DataFrame(param_stats)
    param_df.to_csv(f"{filename_prefix}_parameter_summary.csv", index=False, encoding="utf-8-sig")

    print(f"\n✅ 模型统计结果已保存:")
    print(f" - {filename_prefix}_model_summary.csv")
    print(f" - {filename_prefix}_parameter_summary.csv")
  • bike_gwr_model_summary.csv:模型整体指标(AIC、R² 等)
  • bike_gwr_parameter_summary.csv:每个变量的空间系数统计(均值、标准差等)

📊 GWR 模型输出结果详细解读

在完成地理加权回归(GWR)模型拟合后,我们得到了系统输出的一系列统计指标和参数估计。下面对这些结果进行详细拆解与分析,帮助理解 GWR 模型的实际表现。

✅ 1. 模型诊断指标(Diagnostic Information)

Residual sum of squares (RSS):     3036.221
Effective number of parameters:     89.542
Degree of freedom:                8706.458
Sigma estimate:                      0.591
Log-likelihood:                  -7802.904
AIC:                             15786.891
AICc:                            15788.796
BIC:                             16428.113
R²:                                  0.025
Adjusted R²:                         0.015
指标含义解释
RSS模型残差平方和。越小代表预测越准确
trace(S)模型复杂度,代表自由度消耗程度
DoF有效自由度,样本数减去 trace(S)
Sigma残差标准差的估计,衡量误差的平均波动
Log-likelihood越大表示模型越好;用于与其他模型对比
AIC/AICc/BIC模型选择准则,越小越好
R² / Adj R²模型拟合优度,表示解释变量解释了多少响应变量的变化;值越高越好(当前偏低)

📌 本例解读

  • 模型拟合能力偏弱(R² 仅为 2.5%),可能说明只有一个变量 X 不足以解释 Y 的空间变化;
  • AIC/AICc 在不同带宽下可用于模型优选;
  • trace(S) = 89.5 表示模型参数空间自由度中等。

✅ 2. GWR 局部参数估计统计(Summary Statistics)

Variable     Mean     Std     Min     Median     Max
-----------------------------------------------------
X0           2.413    0.069   2.135   2.418      2.581
X1          -0.000    0.000  -0.001  -0.000      0.001
项目含义
X0截距项,在空间上略有变化,说明整体基准值有轻微区域差异
X1主解释变量系数,其均值接近 0,说明对因变量整体影响极弱
Std空间变异程度。数值越大,说明该变量在不同地点作用差异大
Min/Max空间作用范围(负值表负向影响,正值为正向影响)

📌 本例解读

  • X1 的系数分布在 [-0.001, 0.001] 范围内,基本接近 0;
  • 暗示该变量(如人口密度或道路密度)在解释骑行量上的影响极其微弱;
  • 改进方法—后续加入更多影响因素,如道路类型、可达性、设施密度等。

✅ 3. 空间显著性与可信度(判断变量在哪些区域“真正有效”)

Adj. alpha (95%): 0.001
Adj. critical t value (95%): 3.260

🔍 这是什么意思?

地理加权回归(GWR)是对每个点进行局部回归,因此它为每个点生成了一组回归系数。但这并不意味着每个点的系数都是“显著有效”的。

为了判断某个点上的回归结果是否“统计显著”,GWR 提供了两个关键值:

项目含义
Adj. alpha (95%) = 0.001调整后的显著性水平,等价于 0.1% 的显著性要求,控制多重比较误差
Adj. critical t value (95%) = 3.260t 值的临界值。只有当 t > 3.260,才认为该点上的系数“统计显著”

🎯 实用意义:

  • 可以绘制一张“显著性空间图”,只高亮那些满足 |t| > 3.260 的点;
  • 这将帮助回答一个重要的城市规划问题:

👉 某个变量(如人口密度)到底在哪些地区真正有用,在哪些地区可以忽略?

比如:如果人口密度只在核心城区显著,而在郊区不显著,那么郊区规划就应该考虑其他因子。

✅ 总体评价与建议

📉 本模型结果表明:当前单变量 GWR 模型解释力偏弱,但也揭示了以下方向:

  • ✅ 验证了空间异质性的存在(系数在空间上略有波动);
  • ⚠️ 当前变量解释力不强,建议扩展为多变量 GWR(MGWR);
  • 📌 可使用系数图、局部 R² 图进一步辅助城市规划决策。

本案例展示了 GWR 在城市规划中的核心优势:量化空间异质性。它让我们更清楚地看见:

  • 哪些区域影响因素更强?
  • 哪些地方模型拟合不好?是否遗漏了关键变量?
  • 是否需要分区域制定规划策略?

@原创声明:本教程由课题组内部教学使用,利用CSDN平台记录,不进行任何商业盈利。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值