ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

犯罪预测综述:数据、模型与评估的完整链路

犯罪预测综述:数据、模型与评估的完整链路 简介《基于机器学习的犯罪预测综述》是由何巍博士发表于《科学技术与工程》2019年第19卷第36期的学术论文PDF面向机器学习研究者、公安情报分析人员及智慧警务从业者系统梳理了利用监督学习、非监督学习等算法进行犯罪预测的方法体系与现实意义。包体为单个PDF文件约2.38MB含摘要、关键词、图表和参考文献结构完整。已有339人学习。读者可从综述中获得对犯罪预测研究现状的系统性认识传统犯罪预防策略依赖经验性宏观分析、缺乏实证支撑而机器学习为处理海量高维犯罪数据、识别犯罪模式并构建预警系统提供了可行路径文中还介绍了支持向量机、K近邻、决策树等典型算法的适用场景讨论了提高犯罪预测精度的可能方向并对国内外研究进展做了对比可作为该领域科研选题、理论引证与课题申报的重要参考文献。1. 犯罪预测综述数据、模型与评估的完整地貌基于机器学习的犯罪预测是机器学习项目里最容易被外表误导的一类问题。一个模型把某片区今晚发生盗窃的概率标成 0.87准确率做到 80% 以上但真把巡逻力量调过去之后辖区整体犯罪率并没有如期下降。问题不在算法而在预测目标和干预目标之间隔着一道数据与评估的鸿沟。这篇综述的视角就是把「数据组织、标签定义、模型选型、评估回路、落地排错」这条链路逐个拆开讲清楚每一步的取舍与代价。适合正在做城市风险预警、公共安全数据分析预研或以时空数据为课题的研究生和工程师阅读。2. 数据与标签设计犯罪预测的「输入」决定了模型上限许多综述把大量篇幅花在模型对比上但决定预测效果上限的往往是建模之前的两件事时空单元的切分方式和标签的定义口径。犯罪事件天然稀疏、分布极不均匀、且与周边环境强相关数据组织得不对后面换什么机器学习算法都补不回来。2.1 空间网格与时间窗口两个必须先定的参数犯罪预测的第一步是把连续的城市空间和连续的时间切成离散单元。常见做法有三种按行政辖区如派出所辖区、警区划分、按等距经纬度网格划分、按路网或社区多边形划分。行政辖区数据好解释但粒度太粗路网边界符合人的认知但工程量大大多数项目最终会选等距网格因为它的空间分辨率稳定且更容易和人口、POI、天气等栅格型特征对齐。网格边长怎么定直接决定样本量和稀疏度。我一般用 0.01 度纬度约 1.1 公里作为市区默认值商业中心区域缩到 500 米近郊放到 2 公里。网格太细大量格子整月无事件正样本占比掉到千分之一以下网格太粗所有事件都挤进同一个格子模型学不到空间区分度。时间窗口分两段回溯窗口决定特征里能看到多久的历史预测周期决定标签的跨度。预测未来 24 小时和未来 7 天使用的回溯尺度完全不同——短周期看近 3 到 7 天的计数突变长周期看 30 天以上的趋势和小周期节律。城市区域网格边长预测周期正样本占比经验值市中心商业区300–500 米24–72 小时5%–15%一般城区0.01 度约 1km24 小时–7 天2%–8%近郊/工业区1.5–2 公里7 天0.5%–3%提示不同犯罪类型要分开调这两个参数。街头扒窃、盗窃电动车属于短周期高流动性事件适合 500 米网格加 24 小时预测入室盗窃、诈骗则往往围绕固定目标网格放大到 1 公里、预测周期放到 7 天更稳。2.2 标签构造的三种常见口径二分类、计数回归、风险排序把事件聚合到「网格 × 时间片」之后标签有三种构造口径对应三种不同的业务诉求。二分类最常见未来预测周期内该网格是否发生至少一起目标犯罪。计数回归直接预测发生次数但犯罪次数在大多数网格里是 0回归模型很容易全部预测成接近 0 的小数业务上没法用。风险排序把每个网格的输出变成风险分数再按分数取 Top-K 个网格进行资源调度这是实际项目里最可用的口径——因为巡逻力量本来就是有限的模型不需要判断每个网格的绝对风险只需要把风险从高到低排对。下面用一段示意代码说明「网格化 时间窗聚合」的基本流程。实际项目中crime_df通常来自开放数据平台字段包含发生时间、经纬度、案件类型。import pandas as pd # crime_df 至少包含 occur_time(发生时间), lat, lng, crime_type # step 是网格边长单位是度0.01 度纬度约 1.1 公里 def make_grid(lat, lng, step0.01): return (int(lat // step), int(lng // step)) crime_df[grid] [ make_grid(la, ln) for la, ln in zip(crime_df[lat], crime_df[lng]) ] # 只保留目标犯罪类型避免标签被无关案件污染 target crime_df[crime_df[crime_type].isin([burglary, robbery])].copy() target[date] target[occur_time].dt.date # 标签口径未来 label_horizon 天内该网格是否发生案件 label_horizon 7 grid_dates target.groupby([grid]).apply( lambda g: pd.Series( (g[date].values[:, None] g[date].values[None, :] pd.Timedelta(dayslabel_horizon)).any(axis1) ) ).reset_index(namelabel)这段代码的核心逻辑是先把经纬度映射成网格 ID再按网格分组判断每个日期往后label_horizon天内是否存在目标案件结果作为监督信号。要说明的是真实项目不会这样全量展开因为网格 × 天数会膨胀到几百万行更高效的做法是用 pandas 的shift和rolling在聚合后的计数序列上直接构造标签。但标签口径的三种选择是通用的建议在没有想清楚业务需求前不要直接写模型代码。2.3 数据来源与公开数据集进模型之前先做三件事公开犯罪数据集主要来自城市开放数据平台芝加哥、旧金山的开放数据都有多年粒度到案件级的记录字段通常包含案件类型、发生时间、经纬度、是否逮捕等。拿到数据之后不要直接训练先做三件事清洗时间戳、校准坐标、去重。开放数据里经常出现同一起案件被多个警员重复上报、坐标落在河中央、时间格式混合等脏数据这些会直接制造假样本。外部特征方面天气降水、温度、节假日、POI 密度、地铁站点距离、灯光指数都是常见增强项。以盗窃类犯罪为例降水与夜间盗窃数量在部分城市呈现负相关而节假日前后商业区扒窃明显上升。特征是模型的上限来源光靠历史犯罪计数做特征模型本质上只是在做热力图的平滑外推。注意犯罪预测的特征管道建设工作量通常占整个项目 60% 以上。数据管道没稳定之前不要急着调模型参数——我在项目里见过太多团队把时间花在换模型上最后发现是上游日期字段送错了一个时区。3. 三大建模路线选型从统计基线到时空深度学习综述里并列介绍的三类方法落地顺序正好反着来。先做统计基线再用树模型拿到稳定收益最后在数据量足够时考虑深度学习。跳过基线直接上复杂模型是犯罪预测项目里最常见的资源浪费。3.1 统计与核密度方法先建一条不能输的底线核密度估计KDE是犯罪预测最传统的做法用历史案件坐标生成平滑热力图热力高的区域就是未来高风险区。它的本质是「历史重复性假设」——过去案发多的地方未来继续多发。这个方法不需要任何特征工程一周内就能上线而且解释成本极低。KDE 在犯罪预测中的价值是当基线而非最终方案。它的短板很明显不会利用时间节律、天气等外部信号对新型犯罪模式和人口流动带来的结构变化基本无感。如果一套机器学习模型连 KDE 热力图的精度都超不过那说明特征或标签方向有问题而不是模型不够先进。3.2 树模型路线LightGBM 是性价比最高的起点在犯罪预测的稀疏、高维、非线性数据上梯度提升树是当前性价比最高的选择。它不需要对特征做标准化能自动处理缺失值对犯罪计数这种偏态分布数据远比线性模型稳定。特征一般这样构造目标网格过去 7/14/30 天的案件计数、周围 8 个网格的历史热度、星期几与节假日标志、天气特征、该网格的人口与 POI 密度。下面是一个 LightGBM 最小训练配置可以作为第一个可跑通实验的起点。import lightgbm as lgb # X_train: 特征矩阵每行是一个网格在某天的历史特征 # y_train: 标签1 表示未来 label_horizon 天内该网格发生目标案件 train_data lgb.Dataset(X_train, labely_train) params { objective: binary, metric: auc, learning_rate: 0.05, max_depth: 3, num_leaves: 15, min_data_in_leaf: 50, feature_fraction: 0.8, bagging_fraction: 0.8, bagging_freq: 1, verbosity: -1, } model lgb.train(params, train_data, num_boost_round300)参数说明max_depth限制树深防止模型在稀疏标签上学到孤立模式num_leaves是 LightGBM 的主要复杂度控制项犯罪预测场景取值 15 到 31 就够盲目加大只会过拟合min_data_in_leaf是防过拟合的关键正样本极少时把它设到 50 以上能避免叶子节点只覆盖个位数样本feature_fraction和bagging_fraction是列采样与行采样配合bagging_freq1每轮做一次 Bagging能明显提升泛化。3.3 深度学习路线CNN 与 GNN 的适用边界深度模型在犯罪预测综述里通常有两类把网格区域做成规则的图像张量用 CNN 捕捉空间邻接模式或者把辖区看作图结构用 GNN 建模非规则拓扑关系。这两条路线在论文里指标漂亮但落到自己的数据上要冷静看三个前提。第一样本量是否足够大。CNN 需要把「网格 × 历史通道」堆成三维张量一个中等城市网格数千个、回溯 30 天就有十万级样本这勉强够用但如果是县级数据网格几百个深度学习不如树模型。第二时空联合模式是否真实存在。GNN 建模邻里传播效应前提是犯罪确实存在空间扩散。如果数据显示各网格独立性强图的邻接矩阵只会引入噪声。第三训练稳定性。时空数据存在强自相关深度模型训练时的验证集波动远大于表格数据需要更精细的早停与正则化工程成本高一截。提示想入门的读者建议先跟着《机器学习》周志华补一遍偏差方差与模型评估的理论底座再回来看犯罪预测里的稀疏标签问题会少走很多弯路。4. 评估指标里最骗人的是准确率PAI、Precisionk 与滚动回测综述里的评估章节往往最容易被跳读而它恰恰是犯罪预测项目翻车的重灾区。犯罪数据极端不平衡准确率没有任何参考价值——一个永远预测「不发生」的模型在正样本占比 1% 的数据上能拿到 99% 准确率。真正要盯的是排序能力和命中覆盖。4.1 四类核心指标与各自的偏科Precisionk 是最直观的模型把网格按风险分数排序取前 k 个网格看其中有多少个真的发生了案件。这个指标直接对应巡逻资源分配如果每天只能覆盖 30 个网格就看 Top-30 的命中率。PAIPrediction Accuracy Index预测准确指数是犯罪预测特有的指标定义是「模型预测的高风险区域内实际发生的案件占比」除以「高风险区域面积占比」。它回答的问题是用 XX% 的巡逻资源兜住了 YY% 的案件。PAI 2 意味着模型圈定的 10% 区域覆盖了 20% 的案件是随机覆盖效率的两倍。指标回答的问题优点主要陷阱准确率整体预测对了几成直观稀疏标签下完全失真PrecisionkTop-k 网格命中率贴近资源调度k 的取值依赖业务预算PAI资源效率倍数犯罪预测专属、可对比对网格边界敏感AUC排序能力与阈值无关对 Top-k 业务场景偏乐观4.2 滚动回测不让未来数据穿越犯罪预测是时间序列问题随机切分训练集和测试集等于作弊——模型会从测试期附近的历史里学到本不该看见的信息。正确做法是按时间滚动切分。sklearn 的TimeSeriesSplit可以直接用它保证验证集的时刻永远晚于训练集。import pandas as pd from sklearn.model_selection import TimeSeriesSplit # X, y 必须按日期排好序每行是一个网格在某天的样本 tss TimeSeriesSplit(n_splits3) for train_idx, val_idx in tss.split(X): X_train, X_val X.iloc[train_idx], X.iloc[val_idx] y_train, y_val y.iloc[train_idx], y.iloc[val_idx] # 每次都在更早的数据上训练在更晚的数据上验证这里的关键是n_splits不能拍脑袋定。我一般按需求定预测周期 7 天就至少留 3 到 4 个互相不重叠的验证段每个验证段长度不小于预测周期的两倍避免偶然波动主导指标。4.3 与随机基线对比没有基线的精度没有意义另一个必须做的是随机基线。假设辖区有 1000 个网格巡逻力量每天覆盖 50 个即便随机抽都能覆盖约 5% 的案件。模型算出来的 PAI 必须明显高于这个随机水平才有价值。我的经验是模型 PAI 至少要到随机基线的 1.5 到 2 倍以上才值得进入试点阶段低于这个数优先怀疑特征或标签构造问题而不是继续调参。5. 犯罪预测的五个常见坑数据泄露、稀疏标签与空间自相关5.1 数据泄露时间穿越的危机现象测试集指标异常高AUC 超过 0.95Precisionk 接近满分但上线后预测效果崩盘。原因特征构造时用了未来信息。最常见的翻车点是滚动统计没有做对齐——比如用「当天 24 小时完整计数」作为当天预测特征但真实场景里预测发生在当天凌晨当天的数据根本不存在。另一种是数据清洗时把未来事件并入了历史表。解决所有窗口统计一律用shift把标签时间轴向后平移确保特征只依赖预测时刻之前的数据。写一个断言检查随机抽取 100 条测试样本确认每条样本的所有特征时间戳都早于标签事件时间。5.2 稀疏标签负样本压倒正样本现象模型准确率 99.2%看起来漂亮但 Precisionk 和随机基线几乎一样。原因正样本占比常年低于 2%模型学到的其实是「永远预测负样本」的捷径。准确率在这种情况下毫无信息量损失函数也被海量负样本主导。解决先看正样本占比低于 5% 就要调整。做法有几种按网格分层负采样减少零事件网格的数量给正样本加权scale_pos_weight按负样本数除以正样本数设置或者干脆放弃二分类改成风险排序任务用排序损失训练避免类别不平衡直接冲击分类边界。5.3 空间自相关相邻网格的数据并不独立现象交叉验证指标不错换一个城区测试模型效果断崖式下跌。原因犯罪的时空聚集性让相邻网格的样本高度相似随机划分训练集和测试集时测试集里混着训练集邻近网格的「同款样本」模型其实在记忆热点区域而不是学习犯罪机制。解决验证集按空间块划分——把城市按片区切开训练集用 A、B 区验证集用 C 区。如果换区之后指标塌了说明模型学到的只是「历史多发区域继续多发」外部特征没有起到作用需要重新审视特征设计。5.4 稀有犯罪类型直接退化成零预测现象模型对抢劫、入室盗窃这类低频但严重的犯罪类型输出永远是低概率Top-k 里几乎从不出现。原因目标犯罪占全部案件比例低聚合到网格后进一步稀释正样本可能一年只有几十条模型没有足够的信号去学习。解决不要把所有类型塞进同一个二分类模型。把高频类型盗窃、扒窃和低频类型分开建模低频类型改用更长预测周期30 天、更大网格聚合样本或者转成排序任务而不是二分类。此类模型做出来是概率很低的风险分但排序相对有意义。5.5 偏见与公平性不只是社会责任更是技术正确性现象模型反复对某几个区域给出最高风险分警力越投越多这些区域的报案记录也越来越多模型分数进一步上升形成正反馈循环。原因历史犯罪数据里天然含着执法偏差——警力部署越密集的区域案件被发现和记录的概率越高模型学习到的是「执法记录密度」而非「犯罪真实分布」。解决加入人口、警力分布作为校准变量把犯罪计数除以该区域人口或网格面积得到犯罪率再做标签同时在评估阶段审视模型高亮区域是否与历史警力投入区域高度重合。这类问题不用上升到伦理层面讨论单从数据质量角度也必须在建模时处理——否则模型只是在复读执法资源的存量分布而不是给出新增的预测信息。6. 从预测到干预验证模型价值的最后一步一个犯罪预测模型真正产生业务价值不是因为它预测得准而是因为它让有限资源产生了更多威慑。这需要把模型的排序结果交给决策方再观察干预后的实际案件变化。6.1 用 SHAP 做归因让模型不再是一个黑匣子树模型做好之后第一步用 SHAP 做特征归因。这一步的价值不是发论文而是让使用方信任模型的判断。import shap explainer shap.TreeExplainer(model) shap_values explainer.shap_values(X_test) # summary plot 能看到每个特征对风险的贡献方向和强度 shap.summary_plot(shap_values, X_test, feature_namesfeature_names)SHAP 能直观回答「为什么这个网格本周风险高」——是因为近 7 天周边案件激增还是因为节假日效应叠加了 POI 密度。没有这一步业务方很难把模型输出当作调度依据。6.2 用「预测-干预-再预测」闭环做仿真验证模型验证的最后一步不是指标报告而是干预仿真。做法是把预测出的 Top-k 网格标记为「干预区域」模拟警力覆盖后案件被压制的情景在下一轮训练中把干预区域的历史案件计数下调或标记为已处理再重新训练模型观察 PAI 的变化。如果模型输出的热点区域在被干预后仍是热点说明模型依赖的特征没有捕捉到可干预因素预测结果对业务没有指导意义。我最早做这个方向的实验就是在标签构造上栽了跟头——第一次跑出 0.91 的 AUC兴奋了不到一周就被验证集打回原形最后定位到滚动窗口没有对齐。后来养成一个习惯每次跑实验之前先检查三件事——特征时间戳是否严格早于标签窗口、验证集是否按时间切分、指标是否对比过随机基线。先把数据管线和评估闭环搭好再谈提升模型精度。这套流程在犯罪预测里尤其重要因为每一个错误的预测背后都是真实的资源错配。希望帮到你。本文还有配套的精品资源点击获取
返回列表