基于多维特征融合的互联网贷款客户聚类与风险预警实战

发布时间:2026/10/27 15:41:57
基于多维特征融合的互联网贷款客户聚类与风险预警实战 互联网贷款这个方向这两年做毕设的同学明显多了起来。原因也不难理解一方面消费金融、助贷机构积累了海量用户行为数据另一方面传统评分卡模型在应对多头借贷、用途漂移这些场景时越来越吃力大家自然就想到了用无监督学习去做客户分层再叠加风险预警。我这次拿到的题目是“基于多维特征融合的互联网贷款客户聚类与风险预警研究”同时还要兼顾“基于数据挖掘的互联网贷款用途与风险定价可视化研究”这条线。说白了就是要把一堆原始借贷流水、用户画像、还款记录通过特征工程揉成有业务含义的维度再用聚类把客户分成几类人最后落到风险预警和定价可视化上。这套东西适合正在做计算机、数据科学方向毕设的本科生和研究生也适合刚入行做风控策略、想补一补无监督方法落地细节的朋友。下面我按自己实际跑项目的顺序把整体设计、特征处理、聚类实现、风险预警和可视化几个环节拆开讲中间会穿插不少踩坑记录。1. 项目整体设计与技术路线拆解1.1 为什么选“多维特征融合聚类”而不是直接上监督模型很多同学第一反应是风险预警不就是二分类吗直接上XGBoost、LightGBM不香吗我一开始也这么想但实际动手就发现问题了。互联网贷款场景里坏样本占比通常极低可能千分之几而且“坏”的定义本身有滞后性——你今天看到的逾期是三个月前甚至半年前放出去的款。如果一上来就做有监督标签噪声会把你带偏模型学到的可能只是“这批人当时刚好没还上”而不是真正的风险结构。聚类的好处在于它不依赖标签先把人群按行为、负债、用途等维度自然分开你再去观察每一类的逾期率、复借率、额度使用率风险画像就出来了。这其实和业务里常说的“客群分层”是一个思路只不过以前靠专家规则切现在用算法切。多维特征融合则是为了解决单一维度切不干净的问题——只看负债率会把高收入高负债的人误杀只看还款行为又抓不住那些刚借还没到还款期的新客。把行为、负债、用途、稳定性几个维度拼起来聚类出来的簇才有业务解释力。1.2 技术路线总览与模块划分整个项目我拆成了五块数据获取与清洗、多维特征工程、聚类建模、风险预警规则与模型、可视化与定价展示。数据这块毕设通常拿不到真实机构的全量数据常见做法是用公开的Lending Club数据集或者自己按业务逻辑模拟生成一份带时间戳的借贷流水。我建议两者结合用公开数据跑通流程再用模拟数据补充“用途”这类公开数据里缺失或粗糙的字段。特征工程是重头戏我会把原始字段分成四类维度用户基础画像年龄、职业、收入区间、负债与额度维度负债收入比、额度使用率、多头借贷次数、行为维度近6个月查询次数、还款准时率、复借间隔、用途维度消费、经营、教育、医疗等标签的分布。聚类用层次聚类和K-Means做对比层次聚类负责看树状图找合理簇数K-Means负责大规模跑。风险预警部分我用聚类结果做特征再叠加规则引擎输出预警等级。可视化用Pyecharts或Plotly做交互看板把用途分布和风险定价的关系展示出来。1.3 方案选型背后的几个关键取舍第一个取舍是聚类算法选型。K-Means快、好解释但对非球形簇和异常值敏感层次聚类不需要预设簇数还能出树状图但复杂度高几万条数据就有点吃力GMM高斯混合模型能给出软分配适合处理“一个人同时像两类客户”的情况。我最后是层次聚类定簇数、K-Means做主力、GMM做补充验证这样既保证了效率又能交叉验证簇的稳定性。第二个取舍是特征融合方式。早期特征直接拼接量纲差异巨大收入是几万查询次数是个位数聚类会被大数值主导。所以必须做标准化我用的StandardScaler对偏态严重的字段先做log变换。另外类别型字段比如职业、用途不能简单one-hot维度爆炸不说还会稀释距离。我的做法是先用目标编码或频率编码压成数值再进聚类。第三个取舍是风险预警的落地形式。纯模型输出一个概率业务方看不懂也不敢用。所以我设计成“聚类簇标签规则阈值概率分”三层结构簇标签给出人群定位规则阈值卡住硬性红线概率分做排序。这样既保留了可解释性又兼顾了排序能力。2. 多维特征工程的核心细节与实操要点2.1 原始字段梳理与业务含义映射拿到数据第一步不是写代码是拿张纸把字段和业务含义对一遍。以常见的借贷流水为例原始表里通常有用户ID、申请时间、放款金额、期限、利率、还款状态、逾期天数、职业、收入、借款用途、历史借款次数等。这些字段不能直接进模型得先想清楚每个字段背后代表什么风险信号。比如“历史借款次数”高可能是忠诚用户也可能是多头借贷的以贷养贷得结合“近3个月查询次数”一起看。“借款用途”如果是经营理论上还款来源是经营现金流但经营波动大如果是医疗或教育属于刚性支出违约意愿可能低但还款能力受限。这些业务判断决定了你后面怎么构造交叉特征。我一般会建一张字段映射表左边原始字段右边衍生方向中间标注风险逻辑这样后面写特征函数时不会乱。原始字段衍生方向风险逻辑历史借款次数复借频率、多头指数高频复借可能以贷养贷近3月查询次数查询强度短期密集查询是资金紧张信号负债收入比负债压力超过50%还款压力显著上升借款用途用途风险权重经营类波动大消费类相对稳定还款准时率行为稳定性历史准时率高未来违约概率低2.2 缺失值与异常值的处理策略互联网贷款数据脏是常态。缺失值分两种一种是真缺失比如用户没填收入另一种是业务缺失比如新客没有历史还款记录。这两种不能一样处理。真缺失我一般用中位数或模型预测填充业务缺失我会单独造一个“新客标识”字段让聚类自己去学新客的行为模式。异常值更要小心。比如收入填了999999或者逾期天数出现负数这些明显是录入错误。我的做法是先做分位数截断把超过99.5%分位和低于0.5%分位的值拉回边界而不是直接删除因为删除可能丢掉极端风险样本。另外像“负债收入比”这种比值字段分母为0的情况要单独处理我一般把分母为0的置为一个很大的值表示“无收入但有负债”这本身就是高风险信号。注意异常值处理一定要在特征工程阶段记录清楚后面写论文或答辩时老师很可能会问“你删了多少数据、依据是什么”有记录才答得上来。2.3 多维特征的构造与融合方法特征融合不是简单拼表而是有层次地组织。我把特征分成四个block每个block内部先做归一化再给block一个权重最后拼接。权重怎么定可以用业务经验也可以用随机森林看特征重要性反推。我实测下来负债维度和行为维度权重给高一点画像维度权重低一点聚类效果更符合业务预期。具体构造上举几个我常用的衍生特征额度使用率 已用额度 / 总授信额度反映资金饥渴程度。查询密度 近3月查询次数 / 账户账龄月数避免新老客不可比。还款波动率 近6次还款金额的标准差 / 均值衡量还款能力稳定性。用途集中度 某一用途借款笔数 / 总借款笔数用途越集中行为越可预测。这些特征构造完用StandardScaler标准化偏态字段先np.log1p再标准化。类别字段用频率编码比如职业出现频率频率本身也是一种信息——某些职业集中出现可能代表特定客群。2.4 特征筛选与降维的取舍特征不是越多越好。我一开始堆了60多个特征聚类结果一团糟簇之间区分度很低。后来用方差过滤去掉低方差特征再用相关性矩阵去掉高度共线的比如“近3月查询次数”和“近6月查询次数”相关性0.9以上留一个就行。最后保留30个左右核心特征。降维方面PCA可以用但解释性会变差。我的折中方案是聚类前用PCA降到10维左右跑一版看效果如果簇的轮廓系数明显提升就用否则还是用原始特征方便后面解释每个簇的含义。毕竟毕设答辩时你得说清楚“第一类客户为什么是高危”用PCA降维后很难讲清楚每个主成分的业务含义。3. 聚类建模的完整实操过程3.1 数据标准化与距离度量选择聚类对距离非常敏感。我用的StandardScaler但这里有个细节如果某些特征本身是重尾分布标准化后仍然会被极端值影响。所以对金额类、次数类字段我先做log1p变换再标准化。距离度量上K-Means默认欧氏距离适合连续数值如果类别特征多可以考虑Gower距离但sklearn原生不支持得自己实现或换用其他库。我这次类别特征已经编码成数值所以还是用欧氏距离。代码上标准化和聚类的主流程大概是这样import numpy as np import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.cluster import KMeans, AgglomerativeClustering from sklearn.mixture import GaussianMixture from sklearn.metrics import silhouette_score # 假设 features 是已经构造好的特征矩阵 features df[feature_cols].copy() # 对偏态字段做log变换 skewed_cols [loan_amount, query_3m, debt_ratio] for col in skewed_cols: features[col] np.log1p(features[col]) scaler StandardScaler() X_scaled scaler.fit_transform(features) # 层次聚类看树状图先跑一个样本 agg AgglomerativeClustering(n_clustersNone, distance_threshold0) agg.fit(X_scaled[:2000])3.2 层次聚类定簇数树状图怎么读层次聚类最大的价值是帮你定簇数。我用scipy的dendrogram画树状图观察在哪个高度切一刀簇之间距离最大。实际操作中我不会只看树状图还会结合轮廓系数和业务解释。比如树状图显示切3刀比较自然但轮廓系数在4簇时最高这时候我会两个都跑看哪个簇的业务画像更清晰。from scipy.cluster.hierarchy import dendrogram, linkage import matplotlib.pyplot as plt linked linkage(X_scaled[:2000], methodward) plt.figure(figsize(12, 6)) dendrogram(linked, truncate_modelastp, p30) plt.title(Hierarchical Clustering Dendrogram) plt.show()读树状图有个经验看垂直线的长度越长说明合并的两个簇差异越大。一般选在长垂直线之后切。我这次数据切4簇时树状图显示前三簇合并得很晚说明这三簇区分明显第四簇是后面分出来的小簇业务上对应“高负债新客”虽然样本少但风险高值得单独保留。3.3 K-Means实战k值选择与初始化优化K-Means的k值选择我用肘部法加轮廓系数双验证。肘部法看SSE下降拐点轮廓系数看簇的紧密度和分离度。实测下来k4时轮廓系数0.42k5时0.39k3时0.38所以选4。但这里有个坑K-Means对初始中心敏感我设置了n_init10让算法跑10次取最优避免陷入局部最优。inertia [] sil_scores [] K_range range(2, 9) for k in K_range: kmeans KMeans(n_clustersk, n_init10, random_state42) labels kmeans.fit_predict(X_scaled) inertia.append(kmeans.inertia_) sil_scores.append(silhouette_score(X_scaled, labels)) # 画肘部图和轮廓系数图 fig, ax1 plt.subplots(figsize(10, 5)) ax1.plot(K_range, inertia, bo-) ax1.set_xlabel(k) ax1.set_ylabel(Inertia) ax2 ax1.twinx() ax2.plot(K_range, sil_scores, ro-) ax2.set_ylabel(Silhouette Score) plt.show()3.4 GMM软聚类做补充验证GMM的好处是给出概率一个人可以同时属于多个簇概率最高的那个作为主簇。我用GMM跑了一版发现大部分样本主簇和K-Means一致但有约8%的样本在两个簇之间概率接近这部分人往往是“边界客户”风险特征不明显业务上可以单独标记出来做人工复核。这其实是一个很有价值的发现毕设里可以作为一个创新点写。gmm GaussianMixture(n_components4, covariance_typefull, random_state42) gmm_labels gmm.fit_predict(X_scaled) proba gmm.predict_proba(X_scaled) max_proba proba.max(axis1) # 概率低于0.6的标记为边界客户 boundary_mask max_proba 0.63.5 聚类结果解读与簇画像跑完聚类最重要的一步是解读每个簇。我一般算每个簇在各特征上的均值和整体均值对比找出显著高或低的特征。比如簇0的负债收入比均值0.65远高于整体0.35查询密度也高那这个簇就是“高负债高查询”人群风险等级高。簇1的还款准时率0.98额度使用率0.2属于优质客户。簇2用途集中在经营负债中等属于“经营型客户”风险中等但受行业波动影响。簇3是新客历史记录少画像模糊需要观察期。簇编号人群标签负债收入比查询密度还款准时率风险等级0高负债高查询0.65高0.82高1优质稳定0.22低0.98低2经营型0.45中0.91中3新客观察0.38中无待定4. 风险预警与定价可视化的落地实现4.1 从聚类簇到风险预警规则聚类本身不直接输出风险得把簇标签和业务指标结合。我的做法是先算每个簇的历史逾期率如果有标签的话没有标签就用专家规则给每个簇打分。比如簇0逾期率8%簇1是1%簇2是3%簇3未知。然后设定预警阈值逾期率超过5%的簇触发红色预警3%-5%黄色低于3%绿色。这样每个新客户进来先归到某个簇再看簇的预警等级秒级输出结果。规则引擎我用的是简单的if-else加配置表方便业务调整。配置表长这样risk_rules { cluster_0: {level: red, threshold: 0.05, action: 人工复核}, cluster_1: {level: green, threshold: 0.03, action: 自动通过}, cluster_2: {level: yellow, threshold: 0.05, action: 降额}, cluster_3: {level: yellow, threshold: 0.05, action: 观察期} }4.2 风险预警模型的特征补充与训练如果数据有标签可以在聚类特征基础上再训一个轻量级模型比如逻辑回归或决策树输出违约概率。我这次用逻辑回归因为可解释性强系数能直接看特征影响方向。特征就是聚类簇的one-hot编码加上原始核心特征。训练时注意样本不平衡我用class_weightbalanced自动调权。from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split # cluster_labels 是聚类结果one-hot编码 cluster_dummies pd.get_dummies(cluster_labels, prefixcluster) X_final pd.concat([features.reset_index(dropTrue), cluster_dummies], axis1) y df[is_default] X_train, X_test, y_train, y_test train_test_split(X_final, y, test_size0.3, random_state42) lr LogisticRegression(class_weightbalanced, max_iter1000) lr.fit(X_train, y_train)4.3 用途与风险定价的可视化设计可视化这块我做了三个图用途分布堆叠图、风险定价热力图、客户簇雷达图。用途分布用Pyecharts的堆叠柱状图横轴是用途类别纵轴是人数不同颜色代表风险等级一眼能看出哪个用途高危人群多。风险定价热力图横轴是风险等级纵轴是利率区间颜色深浅代表放款量能看出高风险是否对应高利率。雷达图展示每个簇在负债、行为、用途、稳定性四个维度的得分方便对比。from pyecharts import options as opts from pyecharts.charts import Bar # 用途分布堆叠图 purpose_risk df.groupby([purpose, risk_level]).size().unstack(fill_value0) bar Bar() bar.add_xaxis(purpose_risk.index.tolist()) for level in purpose_risk.columns: bar.add_yaxis(level, purpose_risk[level].tolist(), stackstack1) bar.set_global_opts(title_optsopts.TitleOpts(title用途与风险等级分布)) bar.render(purpose_risk.html)4.4 定价策略与风险溢价的联动定价不是简单的高风险高利率还得考虑市场竞争和客户接受度。我的做法是先按风险等级定基准利率红色预警上浮30%黄色上浮15%绿色基准。然后看每个簇的利率弹性如果某簇对利率敏感上浮太多会流失那就用降额代替加息。这部分我用模拟数据做了敏感性分析发现高负债簇对利率不敏感对额度敏感所以对这类客户降额比加息更有效。这个结论在毕设里可以作为策略建议写进去。5. 常见问题与排查技巧实录5.1 聚类结果不稳定怎么办这是最常见的问题。同一份数据换个随机种子簇的编号和边界就变了。排查思路先看特征是否标准化到位量纲差异大会导致距离计算失真再看是否有异常值没处理一个极端值能把整个簇拉偏最后看k值是否合理k太大簇会碎片化k太小又分不开。我的经验是如果轮廓系数低于0.3基本可以判定聚类效果不行得回去改特征。5.2 簇的业务解释性差怎么调整有时候算法跑出来的簇统计上区分明显但业务上说不通。比如按收入分出了高、中、低三簇但风险没差异。这时候要检查特征里是不是业务信号太弱或者权重给错了。我的调整方法是把业务最关心的特征比如负债收入比、查询密度单独拎出来看它们在簇间的分布如果分布均匀说明这个特征没起作用要么重新构造要么提高权重。5.3 可视化图表在答辩时怎么讲答辩时老师最烦看到一堆花哨但没结论的图。我的建议是每张图配一句话结论。比如用途分布图结论是“经营类用途在高风险簇中占比最高达42%”热力图结论是“高风险客户平均利率比低风险高8个百分点风险溢价基本覆盖预期损失”。这样老师一听就知道你懂业务不是只跑了个算法。5.4 常见报错与快速排查表报错信息可能原因解决方法ConvergenceWarningK-Means迭代不够增加max_iter检查特征尺度NaN in input缺失值未处理填充或删除检查log变换前是否有0Silhouette Score negative簇重叠严重减少k检查特征相关性MemoryError数据量太大采样或使用MiniBatchKMeansGMM singular covariance某簇样本太少减少n_components或增加正则5.5 毕设答辩高频问题预判根据我带过的经验老师最爱问这几个为什么选这个k值聚类结果怎么验证风险预警的阈值怎么定有没有考虑样本不平衡你的创新点在哪提前准备好答案尤其是k值选择一定要有肘部图和轮廓系数图佐证。创新点可以落在“多维特征融合方式”或“GMM边界客户识别”上比单纯跑个K-Means有说服力。6. 实操心得与后续扩展方向6.1 几个让我少走弯路的小技巧第一特征工程阶段一定要写特征字典每个特征的计算逻辑、业务含义、处理方式都记下来后面写论文直接复制省大量时间。第二聚类前先抽样跑比如抽5000条看效果调好了再全量跑不然每次等半小时很痛苦。第三随机种子固定住random_state42保证结果可复现答辩时老师让你现场跑也不慌。第四可视化用HTML交互图答辩时鼠标悬停能看数值比静态图加分。6.2 这个项目还能怎么扩展如果时间充裕可以往两个方向扩一是引入时间维度做动态聚类比如按月滚动聚类看客户簇的迁移路径这能捕捉“客户从优质变高危”的过程预警价值更大。二是把定价做成优化问题在风险约束下最大化收益用线性规划或遗传算法求解这样就从“描述性分析”升级到“决策优化”毕设档次直接上一个台阶。6.3 数据合规与伦理的注意事项做金融相关毕设数据合规必须提。用公开数据集要注明来源模拟数据要说明生成逻辑不能声称是真实机构数据。另外聚类结果可能涉及用户分组论文里要避免出现可识别个人身份的信息所有展示用脱敏后的聚合数据。这不仅是学术规范也是从业者的基本素养。6.4 我对这个方向的一点个人体会我自己跑下来最大的感受是聚类在风控里不是万能的它更像一把“分拣刀”帮你把人群切开但切开之后怎么定风险、怎么定价还是得靠业务理解和规则设计。算法能告诉你“这群人不一样”但“不一样意味着什么风险”得你自己去解读。所以做这个毕设别只盯着代码和调参多花点时间看业务逻辑答辩时才能讲出深度。另外特征工程真的占了我70%的时间但也是最出成果的地方一个好的衍生特征比换个高级算法管用得多。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询