去年接了个选址分析的活儿,一个做连锁餐饮的朋友丢给我几千个竞争对手门店的坐标点,让我帮忙看看哪些片区竞争已经白热化、哪些地方看着点不多但人流潜力不错。我当时的第一反应是画核密度图,但真正上手之后才发现,QGIS里的核密度分析(Kernel Density Estimation, KDE)远不是点点鼠标出张色斑图那么简单。参数怎么设、坐标系用什么、结果怎么读,每一环都有讲究,而且每一环都决定着你最终拿到的图是能支撑决策的,还是只能发朋友圈当个装饰。
这篇文章我就把自己在QGIS里做核密度分析的全过程、参数选择的逻辑、结果解读的方法,以及踩过的一些坑,完整地梳理一遍。无论你是刚接触QGIS的新手,还是已经用过一段时间但不太确定参数怎么调的进阶用户,应该都能从中找到能直接落地的内容。
1. 为什么是核密度分析:离散点与连续密度之间的距离
1.1 离散点数据的困惑:"密度"到底怎么算
手里有点数据,最直接的需求往往是:哪些区域点最多?最简单的做法是把研究区划分成网格,数每个网格里的点数,然后做一张分级着色图。这个方法不是不行,但问题也明显——网格的大小直接决定结果长相,网格大了全是一片色,网格小了又切得七零八落,而且网格之间的数值是跳变的,明明相邻的两个格子,可能一个算出来是峰值,另一个就是零。这种不连续性,在汇报给决策者看的时候,往往很难解释。
核密度分析解决的就是这个问题。它不再把空间切成一格一格的"投票箱",而是假设每个点都向周围施加一个"影响场",距离越近影响越大,距离越远影响越小,然后把这些影响场叠加起来,生成一个连续的密度表面(density surface)。在这个表面上,每一个位置都有一个估计密度值,不再有"某个格子里恰好没有点所以就是0"的尴尬情况。
1.2 从点集到表面的数学直觉
核密度估计的数学公式看起来不复杂,但如果只看公式,很难建立起直观感受。我自己习惯用一个比喻来理解:把每个点想象成往水面滴入的一滴墨水,墨滴会向四周扩散,靠近圆心的地方颜色深,越往外颜色越淡。如果多个墨滴落在一起,颜色就会叠加变深。最后你看到的水面就是一张"连续的颜色梯度图",深色处就是点最密集的区域。
实现这个"墨滴扩散"的数学函数,就是核函数(Kernel)。QGIS里默认用的是Quartic核(四次核),可以直接理解成一个扣过来的"碗"形:中心是1,往四周逐渐衰减到0,到了带宽(Bandwidth/Radius)边缘正好归零。除此之外还有高斯核,它不会在带宽边缘突然截断,而是有一条长长的尾巴,衰减更平滑。实际选择上,Quartic因为计算量小、效果稳定,是很多软件默认的选项。我做了很多次实验之后的感觉是:核函数的选择对最终结果的影响,远小于带宽选择的影响。所以在QGIS里,通常保持默认的Quartic就够用了,更多精力应该放在调带宽上。
1.3 三个关键参数:带宽、像元大小、权重
QGIS原生工具Heatmap (Kernel Density Estimation)里有几个核心参数,搞懂它们是整个分析的关键:
- 带宽(Radius):决定每个点的影响范围,也就是墨滴能扩散多远。这是最核心的参数,选错了结果天差地别。
- 像元大小(Pixel size):决定输出栅格的分辨率,类似于照片的清晰度。它不影响密度的空间形态,主要影响输出细腻度和计算速度。
- 权重字段(Weight field):如果点数据还附带数值属性,比如门店营业额、病例数、事故数量,可以把这个字段作为权重,让"大值点"在空间上施加更大影响。
2. 动手前必须解决的三个问题:坐标系、数据质量、底图
2.1 坐标系:经纬度坐标无法直接算带宽
这是新手最容易忽略、也是最致命的一步。QGIS的核密度工具在计算时,完全基于图层的坐标数值来判断"距离"。如果你的数据是WGS84经纬度坐标,坐标系是EPSG:4326,那么半径参数的单位是"度",而不是"米"。一个纬度大约对应111公里,但一个经度在赤道附近也约等于111公里,到高纬度地区就只有几十公里了。你如果直接拿经纬度数据去跑核密度,所谓的"500米半径"实际上会变成一个奇怪的"500度"范围,结果自然完全不对,形态还会在经度和纬度方向上有严重变形。
正确做法是,在分析之前把图层投影到合适的投影坐标系。中国地区通常可以选择UTM分区投影(比如CGCS2000 / UTM zone 49N、50N、51N),或者使用高斯-克吕格投影的地方坐标系。判断标准很简单:看图层属性里的CRS,只要单位是"米"而不是"度",基本就可以用了。
在QGIS里做投影转换并不复杂:
- 右键点图层,选择"导出"(Export)→"要素另存为"(Save Features As...)。
- 在"CRS"栏,选择一个合适的投影坐标系。
- 导出一个新文件,后续分析用新文件,不要在原图层上操作。
2.2 点数据清洗:重复点和离群点怎么处理
拿到手里几千个点,别急着跑分析,先做一次简单的数据体检。我用QGIS最常用的几个操作为:
- 重复点排查:多个记录可能共用同一个坐标(比如同一栋楼里的多个报告),这些重复点会在核密度分析中被当成多个独立点,形成局部"假热点"。排查方式可以用"处理工具箱"(Processing Toolbox)里的"点在多边形内计数"之类工具,也可以直接打开属性表排序,看有没有坐标完全一样的记录。
- 范围检查:把点图层叠加到行政边界或底图上,用肉眼检查有没有坐标飘到海里去、跑到城市范围外很远的异常点。离群点不多可以手工删掉,多了就要回到数据源头确认采集是否有问题。
- 点数量的合理性:核密度估计在点非常少的情况下(比如只有几十个点)其实很不可靠。我的经验是,少于100个点,画出来的结果更像"插值",而不是"密度",解读时要格外谨慎。
2.3 底图叠加:让结果有地理上下文
核密度分析的结果本质上是一张栅格色斑图,如果没有地理底图参照,看不出来哪里是哪里。QGIS加载底图最简单的方式是通过"XYZ Tiles"添加公开的在线底图:
- 在左侧图层面板里,找到"XYZ Tiles",右键选择"新建连接"。
- 输入一个名称和服务地址(比如OpenStreetMap的标准瓦片服务)。
- 添加完成后,把该图层拖到最底部作为底图。
国内用户如果访问国际底图服务速度不理想,也可以考虑加载天地图等公开底图服务。注意在正式汇报或公开发布时,按要求注明底图来源即可。
3. 在QGIS里跑一遍核密度:完整操作路径
3.1 找到工具与理解命名
QGIS的核密度分析工具在"处理工具箱"(Processing Toolbox)里,搜索Heatmap就能看到。不同版本里工具命名可能略有不同,大多数版本里显示为"Heatmap (Kernel Density Estimation)",中文界面里通常叫"热力图(核密度估计)"。
第一次用的时候,很多人会把它跟另一个工具混淆——在栅格分析(Raster Analysis)里有一个叫"栅格计算器"的,那是做格网统计的,不是核密度。看准工具名字里有Kernel Density Estimation字样,就是它。
3.2 参数面板逐项解读
双击这个工具,打开的对话框里需要设置的内容如下:
- 输入点图层(Input point layer):选择你已经投影好的点图层。
- 半径(Radius):这就是带宽,单位是当前图层坐标系的单位(既然我们已经做了投影,单位就是米)。默认值是"图层范围宽度的十分之一",但这个默认值通常不适合直接使用。具体怎么选,下一节详细说。
- 像元大小(Pixel size):默认值是输入图层范围除以某个值,通常够用。如果要更快出结果,可以适当调大(比如从10改成50),先看效果趋势;最终成图再调小。
- 核函数(Kernel shape):默认Quartic,保持默认即可。
- 权重字段(Weight field):如果有合适的数量字段,选上;没有就留空。
- 输出栅格(Output raster):这里一定要选择保存路径,建议用GeoTIFF格式,不要选"临时文件"——因为后面还要反复加载、调样式、裁剪,保存成正式文件更稳妥。
3.3 运行与产物说明
点击"运行"后,QGIS会自动把生成的结果加入图层。这一步通常很快,几千个点、一个合理像元大小,几秒到十几秒就能跑完。
输出的是一个单波段栅格,每个像元的值代表该位置的核密度估计值。这个值本身不是"点的个数",而是一个经过核函数加权后的密度度量,可近似理解为"单位面积上的点密度强度",但和单纯的"每平方公里的点数"并不完全相等,因为它还包含了核函数平滑的影响。这一点在结果解读时要清楚。
4. 带宽和像元大小不是拍脑袋,而是业务尺度的映射
4.1 带宽选择的三条实战原则
带宽是整个分析里最核心的参数。初学的时候,我习惯套用一些理论公式(比如Silverman提出的经验法则),后来发现,在真正的业务分析里,带宽应该首先服从"业务尺度",然后才是统计优化。
举个实际的例子:分析一个城市里餐饮门店的竞争格局,半径选500米和选3公里,得到的完全是两回事。500米半径时,热点只集中在商圈的几个核心位置;3公里半径时,整个天际线都被抹平了,密度高的片区都连成片。到底哪个对?取决于你要回答的问题——是想找一个"步行可达范围内的局部竞争强度",还是"以3公里辐射圈为单位的区域热度"。前者500米合理,后者3公里更合适。
我现在的习惯是遵循三个原则:
- 原则一:业务尺度优先。先问决策者要回答什么尺度的问题,再倒推带宽。做社区商业选址,带宽通常在300-800米;做区域宏观经济分析,带宽可能要到5公里以上。
- 原则二:多跑几组做比较。不要只跑一个半径就下结论。我会依次跑0.5倍、1.5倍、3倍于预估值的结果,放在一起对比。密度结果的相对分布形态如果稳定,说明结果可靠;如果变化剧烈,说明数据本身或者带宽选择还需要谨慎。
- 原则三:参考点的分布密度。如果平均点间距是500米,带宽设成200米显然是过小了,表面会充满"坑";如果平均点间距是500米,带宽设成3公里,表面又会过度平滑。一个粗略参考是带宽至少是平均点间距的3倍以上,但不能超过研究区尺度的1/5。这个经验值来自我多次对比实验的体会,不是统计教科书公式,但实用性强。
4.2 像元大小的取舍
像元大小对密度形态影响不大,主要影响细腻度和计算速度。但有一些经验可以分享:
- 像元大小不要比带宽小太多。如果带宽是800米,像元设成5米,输出栅格会非常精细,但相邻像元之间的密度值高度相关,这些精细感全是"假细节",而且文件体积暴大、渲染变慢。
- 一个比较合理的经验是:像元大小为带宽的1/30到1/20。带宽800米时,像元大小30-40米左右,效果通常就不错了。
- 如果只是快速探索,可以把像元设大一些,比如100米甚至200米,先把整个工作流跑顺,最后确定所有参数后再用最终像元大小出图。
4.3 权重字段的合理使用
在实际业务中,点往往不是"一对一"的,而是带数量的。比如交通事故数据里,每个点代表一个事故位置,但同一个路口可能有多次事故记录。这种情况下有两个处理思路:
- 思路一:先做"点聚合",把同一位置的多条记录合并成一条,用一个数量字段表示次数,再在核密度分析里选择这个字段作为权重。
- 思路二:保留每条记录,直接用"计数"型核密度。
两个思路的结果形态大体一致,但细节有差异。思路一会让权重大的位置在空间上突出得更加明显,思路二则可能因为多次重复出现在同一精确坐标而导致局部"尖峰"。我个人的偏好是思路一,因为更可控一些,也便于未来做敏感性验证。用QGIS实现点聚合的方式是"处理工具箱"里的"按位置连接属性"或直接使用"统计"工具,将重复坐标的记录按位置汇总、生成唯一标识字段。
5. 结果可视化:让密度表面变成能直接汇报的图
5.1 栅格样式调整
刚跑出来的核密度栅格在QGIS里默认是灰白色的,完全看不出信息量。需要手动调整样式:
- 右键图层,选择"属性"(Properties)→"符号系统"(Symbology)。
- 渲染类型选择"单波段伪彩色"(Singleband pseudocolor)。
- 配色方案选择"YlOrRd"(从黄色到橙红再到深红)这类渐变色。这种配色在汇报场景里最容易让人一眼抓住高密度区。
- 在"颜色渐变"(Interpolation)选项里,选择"线性"(Linear),通常就够用。
- 模式(Mode)建议选"分位数"(Quantile),让颜色分布更平均;如果你关心的是绝对高值区域,可以用"等间距"(Equal Interval)。
- 对最小值的处理:在"最小/最大"设置里,可以把最小显示值稍微抬高一点,把低密度区设为透明,避免色斑盖满整张图。
5.2 用裁剪把热点限定在研究区内
核密度分析的边缘效应是一个绕不开的问题——靠近图层边界的地方,因为边界外的点不存在,估计值会偏低,形成一圈"密度塌陷"。这是因为核密度估计本质上是在每个位置统计周围窗口内的点,但到了研究区边缘,窗口有一部分落在研究区外,自然算不出密度来。
一个常用的处理是:用研究区的面图层(比如行政区边界)去裁剪密度栅格,把研究区以外的像素去掉。在QGIS里用"处理工具箱"里的"裁剪栅格"(Clip raster by mask layer)工具,掩膜图层选择边界面文件即可。这样不仅消除了边界外的视觉干扰,也让成品图更规范。
另一个我常用的进阶操作是:把栅格按照行政区统计平均密度,然后用"多边形密度图"的形式展示——把连续性降维成报告里更便于解释的结论。但需要注意,这个操作会丢掉空间细节,一般只作为补充材料。
5.3 输出与打印
最终汇报时,我通常会借助QGIS的"布局管理器"(Print Layout)出图:
- 在布局里添加地图项,选择当前视图范围或指定范围。
- 添加"图例"将核密度的颜色梯度图例放进去。
- 添加指北针、比例尺、标题和数据来源说明。
- 导出为PNG或PDF。
有一个小提醒:如果导出PNG,分辨率至少设置300dpi,否则在PPT里拉伸会糊。另外,图例里默认会显示各种完整数值段,可以把颜色条上的数值改成业务语义更强的描述,比如"高密度区、中密度区、低密度区",或者标注具体的驱动因素。
6. 实战中反复踩过的坑:从参数到解释的边界
6.1 坐标系错误带来的"蝴蝶形"结果
我在一次分析路网事故数据时,拿到手的是经纬度数据,图省事没做投影,直接设了一个估计的米制半径跑核密度。结果密度图在经度方向拉得特别长,形态像一只压扁的蝴蝶。刚开始我还以为是数据本身的问题,排查了很久才发现是坐标系的问题——带宽参数给的数值被当成"度"来用,自然就全错了。
这个错误最坑的地方在于:它不会报错,也不会有红黄警告。你在图层面板的CRS信息里看到的依然显示是WGS84,但跑出来的单位却是完全混乱的。所以我的建议是:拿到任何点数据,第一步就确认CRS,确认不是米制单位就直接做投影转换。这个习惯已经刻进我的工作流里了。
6.2 重复点与"假热点"
还有一种非常常见的坑:数据里大量重复的坐标。我遇到过一批外卖商户的数据,同一个商场里几十个商户,他们的坐标因为采集原因都指向商场的同一中心点。跑核密度后,那个商场就成了一个异常突出的红色尖峰,看着像"竞争极端的中心",实际上是数据重复造成的假象。
处理方式前面提过,比较有效的方案是先用"按位置汇总"把重复点聚合,或者给每个点加一个小的随机偏移(注意不能改变分布趋势),也可以直接用权重字段方案。但更保险的做法是:在结果解读阶段,把假热点区域切出来,叠加上矢量点看看是否存在大量重复,做好标注,而不是直接照着结果做业务决策。
6.3 结果解释的边界:密度高不等于"应该选址"
这是我想强调的最后一个点,也是很多人容易犯的认知错误。核密度分析描述的是"现有事件的分布强度",它回答的问题只是"哪里密度高"。至于这个密度背后意味着什么——是竞争激烈、是基础设施完善、还是一块蓝海市场——必须要结合业务背景来判断。
比如一个分析外卖门店热力图的场景里,高密度区可能意味着两个完全相反的结论:
- 如果高密度区代表"竞争者扎堆",那是一个需要规避的红海;
- 但高密度区同时也可能代表"这一个片区的外卖需求确实旺盛,基础设施成熟",那么新店挤进去也能分到一杯羹。
最近的一次帮朋友做选址时,我最终给的建议就没有选择密度最高的商业中心,而是选在了两个热点中间一个中等密度、但周边住宅覆盖良好的位置。那个位置恰好是"邻居"密度中等、需求韧性较好的过渡带。这说明了同一个密度结果,叠加不同的业务假设,可以得出完全不同的决策。
核密度分析不会替你回答"该怎么办",它只把空间分布呈现给你。关键决策还是要结合道路网络、消费人群画像、租金水平等其他维度才能站得住脚。
6.4 性能与批处理技巧
当点数量非常大(十几万甚至上百万)时,QGIS原生工具的核密度计算速度会明显下降。我的经验是两个办法:
- 方法一:在探索阶段,先把点图层按照空间随机抽稀到20%-30%,快速调好参数,再用全量数据出最终图。
- 方法二:使用QGIS的图形化建模器(Graphical Model Builder),把投影转换、核密度、裁剪、样式调整串成一个模型,以后数据更新了,直接一键重跑,不用每次手动重复点鼠标。
我第一次做这个流程时,参数反复改了七八次,每次都要重复投影、跑密度、裁剪、调色、导出。把这些步骤录成一个模型之后,后续换一批数据只要重新运行,几分钟就出完整成果了。这点在项目交付阶段尤其省时间。
最后再分享一个操作习惯:任何核密度分析项目,我都会同时保存一份"参数说明文档",把用的坐标系、带宽值、像元大小、核函数类型、数据来源记录下来。这不仅是溯源需要,也是下次数据更新后保持同口径重跑的前提——否则换了个人、换了台电脑,参数对不上,结果就没法比较了。这个文档写完,通常项目都还没结束,等回头复盘时就发现,它比那次分析本身还有用。