
简介这份机器学习保险风险预测资源包聚焦神经网络与支持向量机两类算法面向保险行业数据分析师、机器学习爱好者及需要风险量化建模的从业者解决高维数据下客户风险识别与保费策略优化问题。资源总共7个文件包含3个Python脚本分别承担数据预处理、SVM模型构建、神经网络模型构建3个CSV数据文件提供训练集、测试集与预测结果另有1个说明文档压缩包整体约37.1MB结构紧凑可直接运行。目前已有48人学习适合作为从理论到实战的完整参考。借助来自保诚公司的真实保险数据读者能系统走通数据清洗、特征标准化、模型调参与效果评估全流程还能通过混淆矩阵、精确率、召回率与F1分数等指标量化两类算法的预测表现从而理解模型在实际业务中的可靠性与适用性并进一步迁移到客户细分、欺诈检测等应用方向。1. 保险风险预测实战神经网络SVM双分类器一份能直接跑通的风险评估资源拿到一份保险风险预测的机器学习资源第一反应不是看代码多漂亮而是想确认三件事数据能不能打开、预处理要不要重写、两个模型能不能直接出结果。这份资源的定位很明确——基于某保险机构公开的风险预测数据用SVM和神经网络两套算法做二分类风险预测附带完整的预处理脚本、训练脚本和测试集预测脚本。数据形态是典型的保险竞赛结构train.csv带标签、application_test.csv待预测、predict.csv是提交格式。它适合两类人一是想快速跑通一个保险风控基线、再往上叠特征和模型的新手二是想用现成代码做对照实验、评估SVM与MLP在非平衡数据上表现的选手。下面按数据、预处理、两套模型、踩坑点、融合调优的顺序拆开讲。2. 数据与预处理先把训练表、测试表和提交格式对齐再谈建模2.1 数据文件的角色与字段结构打开压缩包后核心数据是train.csv和application_test.csv。train.csv的每一行对应一条保险申请记录最后一列是TARGET标签取值为0或1其中1表示该记录被判定为风险样本。application_test.csv则没有TARGET这是留给你预测的对象predict.csv就是最终的输出模板要求逐行给出风险概率或类别。这几个文件的关系比表面看起来更讲究train.csv里的ID字段必须和application_test.csv的ID一一对应预测完成后按ID对齐写回predict.csv顺序不能乱。常见翻车点在于pandas读取后索引会被重置很多人直接把预测结果按行号写进CSV结果提交时发现ID错位。文件结构可以这样理解文件角色关键注意点train.csv训练与验证数据包含TARGET标签正负样本极不平衡application_test.csv待预测数据无TARGET特征必须沿用训练集预处理逻辑predict.csv提交模板第一列为ID第二列为预测结果顺序不能变preprocess.py清洗与特征工程决定模型能否直接跑通2.2 缺失值处理按列性质分流不要一把梭填充保险数据集有个特征字段极多缺失率天差地别。有的列缺失率不到5%有的超过60%。我一般不会对所有列填充同样的值而是把列拆成数值型和类别型两批处理。import pandas as pd import numpy as np train pd.read_csv(train.csv) test pd.read_csv(application_test.csv) def preprocess(df): df df.copy() num_cols df.select_dtypes(include[int64, float64]).columns cat_cols df.select_dtypes(include[object]).columns # 数值列按缺失率决定填充方式 for c in num_cols: if df[c].isnull().mean() 0.5: df[c] df[c].fillna(df[c].median()) else: df[c] df[c].fillna(0) # 类别列统一填充占位符避免模型把NaN当特殊值 for c in cat_cols: df[c] df[c].fillna(UNKNOWN) return df train preprocess(train) test preprocess(test)逻辑说明数值列的缺失率超过50%时中位数比0更接近真实分布适合做兜底缺失率低的时候填0既保留“缺失”信息又不引入过多噪声。类别列填UNKNOWN是为了让OneHot编码能生成一个独立的“缺失分支”让模型自己学习这个分支的权重。注意train和test必须共用同一套预处理逻辑否则特征对齐会出问题。2.3 特征工程从字段名中挖出可用的结构化信息保险风险数据最典型的特点是大量字段是“标记型”的比如以FLAG开头的列、以DAY开头的列、以AMT开头的列。这些列单看意义有限但聚合起来信息量不小。我一般会做三类特征# 1. 金额类字段聚合增加稳健的统计特征 amt_cols [c for c in train.columns if c.startswith(AMT)] df[AMT_SUM] df[amt_cols].sum(axis1) df[AMT_MEAN] df[amt_cols].mean(axis1) # 2. 标记类字段计数反映“涉及多少种产品/渠道” flag_cols [c for c in train.columns if c.startswith(FLAG)] df[FLAG_COUNT] df[flag_cols].sum(axis1) # 3. 去除方差几乎为0的常数列降低无用信息 from sklearn.feature_selection import VarianceThreshold sel VarianceThreshold(threshold0.01) X_new sel.fit_transform(df)逻辑说明AMT类求和把多个金额维度折成一个总支出水平对风险评估很有指示性FLAG计数反映客户涉及的产品或渠道广度。VarianceThreshold过滤掉99%以上样本取值相同的列这类列对模型不仅无益还会稀释有效特征权重。做特征工程时要注意所有构造逻辑必须在train和test上同步执行不能用train的统计量去填充test否则会造成数据泄漏。3. SVM做风险分类线性核走通第一版基线别一上来就上RBF3.1 为什么第一版选SVM在这个数据集上SVM的优势在于对高维特征的处理能力。保险数据经过预处理和OneHot编码后维度经常冲到几千甚至几万这种场景下带核的SVC不现实但线性SVM能很快跑出一个可用的基线。另一个理由是样本不平衡严重SVM的class_weight参数可以直接调整。不过必须提醒一下sklearn的SVC在样本量上到几十万后rbf核的拟合耗时是指数级增长的一个晚上跑不完非常正常。我一般用两种方式规避一是直接用LinearSVC训练全量数据本质是带L2惩罚的线性分类器在大样本下收敛很快二是如果坚持用rbf核就做分层下采样把训练样本压到一两万让kernel在可接受时间内跑完。3.2 训练脚本采样、标准化、训练一条龙from sklearn.svm import LinearSVC from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.metrics import roc_auc_score, classification_report X train.drop(columns[TARGET]) y train[TARGET] X_train, X_val, y_train, y_val train_test_split( X, y, test_size0.2, stratifyy, random_state42 ) scaler StandardScaler().fit(X_train) X_train_s scaler.transform(X_train) X_val_s scaler.transform(X_val) model LinearSVC( class_weightbalanced, C1.0, max_iter1000, random_state42 ) model.fit(X_train_s, y_train) y_pred model.decision_function(X_val_s) y_pred_cls (y_pred 0).astype(int) print(fAUC: {roc_auc_score(y_val, y_pred):.4f}) print(classification_report(y_val, y_pred_cls))逻辑说明先用stratify分层采样保证验证集里正负样本比例与训练集一致否则AUC会虚高或失真。标准化这一步对SVM几乎是必须的因为SVM的间隔计算依赖样本间的距离特征尺度差距过大会直接扭曲超平面位置。决策函数输出的是样本到超平面的距离符号代表类别想用概率值的话后面可以接Platt校准。参数说明C是误分类惩罚项C越大对错分的惩罚越重1.0是常用起步值class_weightbalanced让少数类的惩罚权重反比于频率对正样本占比很低的保险数据尤其重要max_iter设1000是给线性求解器一个收敛上限出现警告时可以往上调。3.3 结果解读核心指标不是准确率保险风险预测的准确率没有参考价值因为正样本占比可能只有几个百分点全预测为0也能拿到95%以上的accuracy。真正要盯的是AUC、召回率、F1这三项。AUC反映排序能力决定高风险客户的命中率上限召回率衡量正样本中有多少被识别出来F1在正负样本极不平衡时比accuracy可靠得多。第一版线性SVM的AUC一般落在一个中规中矩的范围别急着调参先把它作为基准再叠加非线性模型找增量。4. 神经网络预测多层感知机吃下非线性交互早停是标配4.1 为什么在SVM之后上MLP线性SVM本质上只能学特征间的线性组合保险风险数据里常见的情况是年龄与产品类型的交互、收入与历史次数的组合线性模型很难直接表达。多层感知机MLP的优势在于隐藏层可以自动学习特征组合和非线性关系。这个场景用sklearn自带的MLPClassifier就够了不需要引入深度学习框架因为数据规模中等、特征维度可控MLP在几分钟内就能迭代完。4.2 训练脚本MLP结构、早停与验证集from sklearn.neural_network import MLPClassifier mlp MLPClassifier( hidden_layer_sizes(128, 64), activationrelu, solveradam, alpha1e-4, batch_size256, learning_rate_init1e-3, max_iter300, early_stoppingTrue, validation_fraction0.1, n_iter_no_change10, random_state42 ) mlp.fit(X_train_s, y_train) y_pred_nn mlp.predict_proba(X_val)[:, 1] print(fNN AUC: {roc_auc_score(y_val, y_pred_nn):.4f})逻辑说明标准化后的X_train_s直接喂给MLP不需要额外处理类别变量。hidden_layer_sizes设置为(128, 64)即第一层128个神经元、第二层64个这个容量对保险数据是够用的再往上叠容易过拟合。early_stoppingTrue让模型在验证集loss连续n_iter_no_change轮不再下降时提前终止等于把epoch数交给验证集说了算而不是死板地跑满max_iter。参数说明activationrelu是目前MLP的默认首选梯度消失风险比tanh低solveradam适应性梯度下降在中小数据集上收敛稳定alpha是L2正则系数1e-4属于中规中矩batch_size256在样本量大时可以加快收敛validation_fraction0.1是从训练集里再切10%做早停验证注意这个与前面手动切出的X_val不冲突前者管训练过程后者管最终评估。4.3 输出概率的使用方式MLP的predict_proba直接给出P(y1)这对后续做阈值调整和模型融合很友好。阈值默认0.5但风险预测场景正样本太少阈值通常要下调到0.2甚至0.1才可能覆盖更多正样本。阈值的选择要结合业务代价漏掉一个高风险客户比误伤一个低风险客户代价更大时就选低阈值。实际操作中我习惯按AUC排序后取验证集上F1最高的阈值作为最终判定线。5. 避坑指南从数据翻车到模型翻车的四段实录5.1 现象SVC跑了一个小时还在训练训练集才几万行原因sklearn的SVC在kernelrbf时计算复杂度是样本量的平方量级即使只有几万行核矩阵的求解也会把时间拉到小时级。很多人把SVM默认当作万能分类器直接套样本量一大就跑不动。解决先看样本量。超过两三万行优先换LinearSVC非要rbf核就用train_test_split分出1万行左右作为训练子集配合class_weightbalanced训练一个近似模型。从效果看线性核的AUC损失通常不大但训练时间能缩短两个数量级。5.2 现象模型预测结果全是0AUC直接报错或逼近0.5原因正样本占比极低时模型倾向于把所有样本都预测为负类decision_function全部为负predict_proba全部小于阈值导致输出全0。另一个可能原因是预处理时把特征列顺序搞乱了OneHot编码后训练集和测试集列不一致模型等于在噪声上推理。解决训练时给分类器加class_weightbalanced或者对训练集做SMOTE过采样。同时检查train和test在预处理后的列名列表是否完全一致不一致就按列名对齐再训练。5.3 现象提交predict.csv后分数很低报ID错位原因预测时直接把result数组按行号写进文件忽略了test的原始顺序可能与索引不一致。pandas在合并或过滤后索引会跳变直接reset_index会破坏ID对应关系。解决读取application_test.csv时保留ID列预测后拼成DataFrame再按ID排序写回。sub pd.DataFrame({ ID: test[ID].values, TARGET: y_pred_nn }) sub.to_csv(predict.csv, indexFalse)逻辑说明用.values获取原始数组而不是沿用索引保证ID和预测值一一对应。这是最容易踩的坑也是最容易检查的坑。5.4 现象早停不生效验证集AUC越来越差但模型还在跑原因MLPClassifier的early_stopping监控的是验证集的loss不是AUC。loss下降但不代表AUC同步上升尤其在样本不平衡时loss被多数类主导AUC可能已经在恶化。看起来“早停失效”其实是监控指标选错了。解决不看loss曲线改用手动切分的X_val在每轮迭代后计算AUC或者训练完成后用AUC选择最佳epoch。简单做法是把max_iter调大配合n_iter_no_change10让模型在loss稳定后自动停然后接受AUC可能略低于峰值的现实。6. 进阶用法双模型输出融合与概率校准SVM和MLP学到的决策边界差异很大把它们的结果做简单的线性融合往往能在AUC上带来稳定的小幅提升。融合的第一步是把两者输出拉到同一个量纲上SVM的decision_function是距离值范围可以任意大MLP的predict_proba在0到1之间。直接相加没有意义先让SVM的距离过一层逻辑回归、做一次Platt缩放转成概率后再和MLP的概率按权重相加。from sklearn.calibration import CalibratedClassifierCV from sklearn.svm import LinearSVC svm_cal CalibratedClassifierCV( LinearSVC(class_weightbalanced), methodsigmoid, cv5 ) svm_cal.fit(X_train_s, y_train) svm_proba svm_cal.predict_proba(X_val_s)[:, 1] blend 0.5 * svm_proba 0.5 * y_pred_nn print(fBlend AUC: {roc_auc_score(y_val, blend):.4f})逻辑说明CalibratedClassifierCV把SVM的原始距离通过Sigmod函数映射到概率空间相当于置信度对齐。cv5表示用五折交叉验证做校准避免同一个数据既训练又校准而产生的过拟合。融合权重0.5/0.5是最稳妥的起点如果知道某个模型在当前特征下更强可以往强模型方向偏。融合后如果还想再提高可以做阈值微调在验证集上遍历0到1间的阈值取F1或业务成本最低的阈值点。要注意阈值确定后只能在固定的融合输出上使用换一次数据或模型就要重算不能用旧阈值套新模型。概率校准这一步让我想起组装这套资源时的教训——最初直接拿SVM的decision_function和NN的predict_proba做加权融合效果反而变差问题就出在量纲不匹配上。从那以后我拿到任何多模型体系第一件事都是先把输出统一到概率空间再谈融合权重。这份资源的价值在于SVM和MLP的代码基线都能直接跑你把数据预处理和特征工程搭顺了剩下的就是在融合和阈值的空间里找增量。希望帮到你。本文还有配套的精品资源点击获取