本篇要講述的是台中 OSM 建築數量 2018→2025 增長 392%,但其中有多少是真實建設、多少是社群回填?本篇提出一個可量化、可控制修正強度的 λ 偏差修正指數。

關於 OSM 其中的 392% 增長,有多少是真的?

先來檢視台中市 OSM 數據 8 年的原始增長:

年份 OSM 建築物總數 設施 商店 休閒
2018 16,926 1,015 408 30
2019 12,771 1,207 466 32
2020 16,117 1,520 541 39
2021 18,500 1,599 534 47
2022 24,973 1,640 590 49
2023 41,055 1,762 647 57
2024 47,584 1,874 690 59
2025 50,208 1,921 705 61

採樣點 500m 範圍內的「平均建築數量」更為顯著——從 2018 年的 27.6 棟,增至 2025 年的 136 棟,+392.1%

然而其中一個問題隨之而來:

台中市真的在 8 年內新建了比原有存量多 4 倍的建築嗎?

答案顯然是否定的。即便是開發最密集的城市,10 年內新建建築數量也不會超過存量的 1 倍。這 392% 中,相當大一部分其實是「OSM 社群志願者持續將既有建築數位化補登」,也就是「歷史回填」(backfilling)效應。


量化「回填效應」:社群貢獻量代理變數

若某城市/地區 2018 年 OSM 共有 1 萬個元素(建築 + 設施 + 商店 + 休閒),2025 年增至 5 萬,則社群整體活躍度約提升 5 倍。建築數的增長,有相當一部分是被這個系統性的「社群更積極補登」推高的。

我們在這邊定義「社群貢獻量代理」C_t

C_t = building_count_t + amenity_count_t + shop_count_t + leisure_count_t

將所有有測量目標的標籤加總,作為志願者整體投入程度的代理變數

# osm/bias_correction.py:37-54
def compute_total_elements(osm_metrics: pd.DataFrame) -> pd.Series:
    """
    計算每年 OSM 快照的「總元素數」(社群貢獻量代理)。
    """
    count_cols = [c for c in ["building_count", "amenity_count", "shop_count", "leisure_count"]
                  if c in osm_metrics.columns]
    osm_metrics = osm_metrics.copy()
    osm_metrics["total_elements"] = osm_metrics[count_cols].sum(axis=1)
    return osm_metrics.groupby("year")["total_elements"].mean()

台中 8 年的 C_t(每採樣點 500m 範圍內均值):

年份 C_t(總元素均值)
2018 34.6
2021 57.1
2025 146.4

C_2025 / C_2018 ≈ 4.23,社群貢獻量翻了逾四倍

核心假設:社群貢獻量增長與真實建設增長是兩個獨立過程。OSM 元素總數的增長是兩者的疊加,而研究者真正關心的是後者。


修正公式

定義第 t 年的「校正後增長指數」:

G_t_corr = (N_t / N_0) × (C_0 / C_t)^λ

各符號意義:

符號 意義
N_t / N_0 原始增長率(基準年 N_0 = 2018)
(C_0 / C_t) 社群貢獻量的衰減倒數(C 愈大,此因子愈小)
λ ∈ [0, 1] 修正強度,由分析者根據研究假設設定

三種直覺解讀:

  • λ = 0:完全不修正 → G_corr = N_t / N_0,還原為原始指數
  • λ = 1:完全比例修正 → 假設所有 OSM 元素增長均來自社群活躍度提升
  • λ = 0.5:中度修正,假設增長中一半來自真實建設、一半來自社群回填
# osm/bias_correction.py:80-97
v0 = series[base_year]
c0 = community_proxy[base_year]

for year in sorted(series.index):
    v_t = series[year]
    c_t = community_proxy.get(year, c0)

    raw_growth = v_t / v0 if v0 > 0 else np.nan

    # 社群貢獻量修正因子 = (C_t0 / C_t)^λ
    if c0 > 0 and c_t > 0:
        correction_factor = (c0 / c_t) ** lambda_
    else:
        correction_factor = 1.0

    corrected_growth = raw_growth * correction_factor

將 λ 套用至台中數據

採用建議值 λ = 0.5:

年份 建築均值 原始增長 修正因子 (C_0/C_t)^0.5 修正後增長
2018 27.6 +0.0% 1.000 +0.0%
2019 31.0 +12.3% 0.943 +5.9%
2020 34.8 +26.1% 0.901 +13.6%
2021 47.6 +72.5% 0.778 +34.2%
2022 67.8 +145.7% 0.692 +70.0%
2023 109.8 +297.8% 0.582 +131.1%
2024 131.3 +375.7% 0.508 +141.7%
2025 136.0 +392.8% 0.486 +139.6%

392% 被壓縮至 140%,較接近一個快速發展城市的合理增速範圍。

原始指數顯示「8 年新增了 4 倍建築」,修正後顯示「8 年新增了 1.4 倍建築」——後者更符合人類認知與官方建照數據的數量級。


λ 靈敏度分析

λ 是無法從資料本身唯一決定的參數,因此靈敏度分析是不可省略的步驟——它能讓讀者清楚看見「不同假設下結論差距有多大」。

# osm/bias_correction.py:111-143
def sensitivity_analysis(series, community_proxy, base_year=BASE_YEAR, lambdas=None):
    if lambdas is None:
        lambdas = [0.0, 0.25, 0.5, 0.75, 1.0]
    final_year = sorted(series.index)[-1]
    rows = []
    for lam in lambdas:
        df = bias_correction_index(series, community_proxy, base_year, lam)
        final_row = df[df["year"] == final_year].iloc[0]
        rows.append({
            "lambda": lam,
            "corrected_growth_index": final_row["corrected_growth_index"],
            "implied_real_growth_pct": (final_row["corrected_growth_index"] - 1) * 100,
        })
    return pd.DataFrame(rows)

台中 2018→2025 建築增長在不同 λ 值下的結果:

λ 修正後增長
0.00 +393%(不修正)
0.25 +234%
0.50 +140%(中度修正,建議值)
0.75 +73%
1.00 +17%(完全比例修正)

只是在這情況下,下列兩種解讀都不合適:

  • λ = 0 派:「OSM 增長即真實建設增長」→ 4 倍增長,呈現泡沫式擴張
  • λ = 1 派:「OSM 增長完全等比例反映社群活躍度」→ 17%,幾乎零成長

兩者皆不準確,真實情況必然介於兩者之間,靈敏度分析的價值在於:明確告知讀者「結論在 λ ∈ [0.25, 0.75] 範圍內均成立」,比直接拋出單一數字嚴謹得多。


後面我們將繼續講解關於 λ 值得其他參考計算方式,這本篇中著墨在城市 OSM 數據跟志願者貢獻偏之間的關係計算。

無標籤

關注作者:

新增評論