银行零售与信贷AI实战:从RFM模型到信贷算法的代码全解
信贷审批的核心:还款能力评估
信贷审批的本质不是"批不批",而是"这个人还得起多少"。传统审批依赖信贷员经验判断,主观性强、效率低、标准不统一。AI化改造的第一步,是把还款能力评估从"拍脑袋"变成"算得清"。
还款能力评估的核心逻辑链条:月收入 → 扣除刚性支出 → 可支配收入 → 匹配月供上限 → 反推授信额度。
可支配月收入 = 税后月收入 - 月租金/房贷 - 月社保公积金 - 月最低生活支出
月供上限 = 可支配月收入 × 债务收入比(DTI)阈值
授信额度 = 月供上限 × 年金现值系数(期限, 定价利率)
核心观点:授信额度不是拍出来的,是算出来的。还款能力的量化评估是信贷AI的基石。
以一笔典型消费贷为例:客户税后月收入1.8万元,已有房贷月供5,000元,社保公积金扣除1,200元,最低生活支出3,500元。银行设定DTI阈值为50%,则:
- 可支配月收入 = 18,000 - 5,000 - 1,200 - 3,500 = 8,300元
- 月供上限 = 8,300 × 50% = 4,150元
- 若定价年利率5.2%、期限3年(36期),年金现值系数≈33.23
- 授信额度 ≈ 4,150 × 33.23 ≈ 137,904元
这个计算过程完全可编码、可审计,是信贷审批智能化的起点。
技术要点总结:还款能力评估将主观判断转化为五步量化公式,其中DTI阈值和年金现值系数是两个关键参数,前者由风控策略决定,后者由利率和期限决定。
等额本息算法:从公式到代码
等额本息是零售信贷最主流的还款方式。理解其数学本质,是从业者做利率定价、提前还款测算、违约成本分析的前提。
公式推导
设贷款本金为 $P$,月利率为 $r$(年利率除以12),还款期数为 $n$,每月还款额为 $M$。
第1期末欠款:$P(1+r) - M$
第2期末欠款:$P(1+r)^2 - M(1+r) - M$
第$k$期末欠款:$P(1+r)^k - M[(1+r)^{k-1} + (1+r)^{k-2} + \cdots + 1]$
到第$n$期末欠款应为0:
$$P(1+r)^n - M \cdot \frac{(1+r)^n - 1}{r} = 0$$
解得每月还款额:
$$M = \frac{P \cdot r \cdot (1+r)^n}{(1+r)^n - 1}$$
核心观点:等额本息的月供公式本质上是一个年金等式——所有月供折现到贷款发放日,等于贷款本金。
代码实现
def calc_equal_installment(principal, annual_rate, months):
"""
等额本息月供计算
principal: 贷款本金
annual_rate: 年利率(如0.052表示5.2%)
months: 还款期数
"""
r = annual_rate / 12 # 月利率
if r == 0:
return principal / months # 零利率时直接均分
monthly_payment = (principal * r * (1 + r) ** months) / ((1 + r) ** months - 1)
return monthly_payment
def amortization_schedule(principal, annual_rate, months):
"""
生成完整还款计划表
返回每期的本金、利息、剩余本金
"""
r = annual_rate / 12
monthly_payment = calc_equal_installment(principal, annual_rate, months)
balance = principal
schedule = []
for period in range(1, months + 1):
interest = balance * r # 当期利息 = 剩余本金 × 月利率
principal_paid = monthly_payment - interest # 当期还本 = 月供 - 利息
balance -= principal_paid # 剩余本金递减
schedule.append({
'期数': period,
'月供': round(monthly_payment, 2),
'本金': round(principal_paid, 2),
'利息': round(interest, 2),
'剩余本金': round(max(balance, 0), 2)
})
return schedule
# 示例:50万消费贷,年利率5.2%,36期
result = amortization_schedule(500000, 0.052, 36)
print(f"月供: {result[0]['月供']}元")
print(f"第1期 利息:{result[0]['利息']} 本金:{result[0]['本金']}")
print(f"总利息: {sum(r['利息'] for r in result):.2f}元")
提前还款测算
def prepayment_savings(principal, annual_rate, months, prepay_month, prepay_amount):
"""
提前还款节省的利息
prepay_month: 提前还款所在期数
prepay_amount: 提前还款金额(额外还本)
"""
schedule = amortization_schedule(principal, annual_rate, months)
# 原计划总利息
total_interest_original = sum(r['利息'] for r in schedule)
# 提前还款后剩余本金减少,重新计算后续月供
balance_at_prepay = schedule[prepay_month - 1]['剩余本金'] - prepay_amount
remaining_months = months - prepay_month
# 后续新月供
new_monthly = calc_equal_installment(balance_at_prepay, annual_rate, remaining_months)
new_schedule = amortization_schedule(balance_at_prepay, annual_rate, remaining_months)
total_interest_new = sum(r['利息'] for r in schedule[:prepay_month]) + \
sum(r['利息'] for r in new_schedule)
savings = total_interest_original - total_interest_new
return round(savings, 2)
# 示例:第12期提前还5万
saving = prepayment_savings(500000, 0.052, 36, 12, 50000)
print(f"提前还款节省利息: {saving}元")
核心观点:等额本息前期利息占比高、本金占比低,提前还款的利息节省随时间递减——第1期提前还效果最大,最后几期几乎没有意义。
技术要点总结:等额本息算法的核心是一个几何级数求导得到的月供公式,编码时注意零利率边界条件。还款计划表揭示了"前息后本"的资金结构,是利率定价和提前还款测算的基础。
信用评分模型:决策自动化的引擎
信用评分模型将多维度风险特征压缩为一个分数,驱动审批自动化。当评分超过阈值(如88分),系统自动通过一定额度内的贷款申请,无需人工介入。
评分卡建模流程
原始特征 → WOE编码 → 逻辑回归 → 概率映射 → 标准分(300-850)
WOE(证据权重) 把每个特征分箱后的好坏比转化为对数似然比:
$$WOE_i = \ln\left(\frac{Good_i / Good_{total}}{Bad_i / Bad_{total}}\right)$$
IV值衡量特征的区分能力:
$$IV = \sum_{i} (Good_i/Good_{total} - Bad_i/Bad_{total}) \times WOE_i$$
IV > 0.3 为强特征,0.1-0.3 为中等,< 0.02 可剔除。
代码实现
import numpy as np
def calc_woe_iv(df, feature, target):
"""
计算特征的WOE和IV值
df: 数据框, feature: 特征列名, target: 标签列(1=坏, 0=好)
"""
total_good = (df[target] == 0).sum()
total_bad = (df[target] == 1).sum()
woe_dict = {
}
iv = 0.0
for bucket in df[feature].unique():
n_good = ((df[feature] == bucket) & (df[target] == 0)).sum()
n_bad = ((df[feature] == bucket) & (df[target] == 1)).sum()
# 防止除零,加平滑因子
ratio_good = (n_good + 0.5) / total_good
ratio_bad = (n_bad + 0.5) / total_bad
woe = np.log(ratio_good / ratio_bad)
woe_dict[bucket] = woe
iv += (ratio_good - ratio_bad) * woe
return woe_dict, iv
def score_from_probability(prob_bad, base_score=650, pdo=50):
"""
将违约概率映射为标准信用分
base_score: 基准分(违约概率1:1时对应分数)
pdo: 翻倍比(违约概率翻倍,分数变化量)
"""
factor = pdo / np.log(2)
offset = base_score - factor * np.log(1) # ln(1) for 1:1 odds
odds = (1 - prob_bad) / prob_bad # 好坏比
score = offset + factor * np.log(odds)
return round(score)
def auto_approve(score, threshold=88, max_amount=500000):
"""
自动审批决策
score: 信用评分(0-100制,非标准分)
threshold: 自动通过阈值
max_amount: 自动通过最大额度
"""
if score >= threshold:
# 高分客户,自动通过,额度根据评分线性映射
approved_amount = max_amount * (score / 100)
return {
'决策': '自动通过', '额度': round(approved_amount), '人工复核': False}
elif score >= 60:
return {
'决策': '人工审核', '额度': None, '人工复核': True}
else:
return {
'决策': '拒绝', '额度': 0, '人工复核': False}
# 示例:88分客户,自动通过
result = auto_approve(88)
print(f"审批结果: {result['决策']}, 额度: {result['额度']}元")
核心观点:信用评分88分自动通过50万,本质是将风险量化后的决策前置——当模型置信度足够高时,人工介入反而增加操作风险。
技术要点总结:信用评分卡的核心是WOE编码+逻辑回归,用IV值筛选特征,用PDO参数将概率映射为直观分数。自动审批的关键不是模型多么复杂,而是阈值设定要匹配业务的风险偏好。
RFM模型+AI:客户分层的工程化实现
RFM模型是零售银行客户分层最经典的方法论框架,通过三个维度量化客户价值:
- R(Recency):最近交易距今时间,越小越活跃
- F(Frequency):一段时间内交易次数,越大越黏性高
- M(Monetary):一段时间内交易金额,越大越贡献高
传统RFM的局限与AI增强
传统做法是按每个维度二分(高于均值=1,低于均值=0),形成8个组。但这有三个问题:阈值选择过于粗暴、三个维度等权忽略业务差异、无法发现非线性分层模式。
AI增强方向:用K-Means聚类替代硬分箱,用特征加权嵌入业务先验,用轮廓系数自动确定最优分组数。
代码实现
import numpy as np
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
def compute_rfm(transactions, customer_id_col='customer_id',
date_col='date', amount_col='amount', reference_date=None):
"""
从交易流水计算RFM指标
transactions: 交易流水DataFrame
reference_date: 参照日期(默认取最大交易日期+1天)
"""
if reference_date is None:
reference_date = transactions[date_col].max() + pd.Timedelta(days=1)
rfm = transactions.groupby(customer_id_col).agg(
Recency=(date_col, lambda x: (reference_date - x.max()).days),
Frequency=(date_col, 'count'),
Monetary=(amount_col, 'sum')
).reset_cache()
return rfm
def rfm_cluster(rfm_df, n_clusters=5, weights=None):
"""
基于K-Means的RFM客户分层
weights: 业务权重 [R, F, M],默认等权
"""
features = rfm_df[['Recency', 'Frequency', 'Monetary']].copy()
# 标准化
scaler = StandardScaler()
features_scaled = scaler.fit_transform(features)
# 应用业务权重
if weights:
features_scaled = features_scaled * np.array(weights)
# 聚类
kmeans = KMeans(n_clusters=n_clusters, random_state=42, n_init=10)
rfm_df['Cluster'] = kmeans.fit_predict(features_scaled)
# 为每个簇生成业务标签
cluster_stats = rfm_df.groupby('Cluster')[['Recency', 'Frequency', 'Monetary']].mean()
labels = {
}
for idx, row in cluster_stats.iterrows():
if row['Recency'] < cluster_stats['Recency'].median() and \
row['Monetary'] > cluster_stats['Monetary'].median():
labels[idx] = '高价值活跃'
elif row['Frequency'] > cluster_stats['Frequency'].median():
labels[idx] = '高频低值'
elif row['Recency'] > cluster_stats['Recency'].median():
labels[idx] = '流失预警'
else:
labels[idx] = '潜力培养'
rfm_df['分层标签'] = rfm_df['Cluster'].map(labels)
return rfm_df, cluster_stats
def silhouette_score_optimal(rfm_df, k_range=range(3, 9)):
"""
用轮廓系数自动选择最优聚类数
"""
from sklearn.metrics import silhouette_score
scaler = StandardScaler()
features = scaler.fit_transform(
rfm_df[['Recency', 'Frequency', 'Monetary']]
)
scores = {
}
for k in k_range:
km = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = km.fit_predict(features)
scores[k] = silhouette_score(features, labels)
best_k = max(scores, key=scores.get)
return best_k, scores
# 业务权重示例:银行场景M(资产)更重要
# weights = [0.8, 1.0, 1.5] # R权重0.8, F权重1.0, M权重1.5
核心观点:RFM+K-Means不是简单替换分箱方法,而是让分层结果由数据形状驱动——轮廓系数自动选k,特征权重嵌入业务先验,两者结合实现"数据说话、业务导向"。
技术要点总结:RFM工程化的关键三步——从交易流水聚合指标、StandardScaler+权重加权做特征工程、K-Means聚类+轮廓系数自动分层。银行场景下Monetary维度权重应提高,因为AUM是核心北极星指标。
零售营销智能化:精准推荐与AUM提升实战
客户分层只是手段,目标是精准营销和AUM提升。将分层结果与推荐引擎联动,形成"分层-推荐-触达-反馈"闭环。
分层驱动的差异化策略
| 分层标签 | 核心策略 | 推荐产品 | 触达渠道 | AUM目标 |
|---|---|---|---|---|
| 高价值活跃 | 留存+升档 | 私行理财、家族信托 | 专属客户经理 | 维稳为主 |
| 高频低值 | 促净值提升 | 基金定投、大额存单 | APP弹窗+短信 | 提升30% |
| 潜力培养 | 激活+交叉销售 | 信用卡、消费贷 | APP内推荐位 | 提升50% |
| 流失预警 | 召回+挽留 | 高息存款、专属权益 | 电话+微信 | 止跌回稳 |
基于协同过滤的产品推荐
def item_based_recommend(customer_segment, product_matrix, top_n=3):
"""
基于物品相似度的产品推荐
customer_segment: 客户分层标签
product_matrix: 产品-特征矩阵(产品×特征)
top_n: 推荐产品数
"""
from sklearn.metrics.pairwise import cosine_similarity
# 计算产品间相似度
sim_matrix = cosine_similarity(product_matrix)
# 根据客户分层获取种子产品(该分层客户持有率最高的产品)
segment_products = segment_seed_products[customer_segment]
scores = {
}
for seed in segment_products:
seed_idx = product_index[seed]
for j, prod in enumerate(product_index.keys()):
if prod not in segment_products:
scores[prod] = scores.get(prod, 0) + sim_matrix[seed_idx][j]
# 排序取TopN
recommended = sorted(scores.items(), key=lambda x: x[1], reverse=True)[:top_n]
return recommended
def aum_uplift_estimate(current_aum, segment, treatment_effect):
"""
AUM提升预估
treatment_effect: 各分层的实验效应(增量)
"""
expected_uplift = current_aum * treatment_effect.get(segment, 0)
return round(expected_uplift, 2)
# 各分层预估增量效应(基于历史A/B测试)
segment_effects = {
'高价值活跃': 0.03, # 3%提稳
'高频低值': 0.30, # 30%提升
'潜力培养': 0.50, # 50%提升
'流失预警': -0.10 # 止跌10%
}
核心观点:AUM提升不是对所有人做同样的事,而是对不同分层做不同的事——潜力客户拉净值,高频客户促大额,流失客户先稳住。
技术要点总结:零售营销智能化的关键是分层-推荐-触达的三位一体。分层决定"说什么",推荐决定"推什么",触达决定"怎么说"。AUM提升效果必须用A/B实验验证,不能只看组内前后对比。
财富管理AI:资产配置到退休规划
马科维茨均值-方差模型
资产配置的经典框架是马科维茨模型,在给定风险水平下最大化预期收益:
$$\max_{w} \quad \mu^T w \quad s.t. \quad w^T \Sigma w \leq \sigma^2_{target}, \quad \mathbf{1}^T w = 1, \quad w \geq 0$$
其中 $\mu$ 为收益向量,$\Sigma$ 为协方差矩阵,$w$ 为权重向量。
import numpy as np
from scipy.optimize import minimize
def portfolio_optimize(expected_returns, cov_matrix, target_risk=None,
target_return=None):
"""
均值-方差资产配置优化
expected_returns: 各资产预期收益率
cov_matrix: 收益率协方差矩阵
target_risk: 目标风险(波动率), 与target_return二选一
"""
n = len(expected_returns)
def portfolio_volatility(w):
return np.sqrt(w @ cov_matrix @ w)
def portfolio_return(w):
return w @ expected_returns
constraints = [{
'type': 'eq', 'fun': lambda w: np.sum(w) - 1}]
bounds = [(0, 1)] * n # 不允许卖空
if target_risk is not None:
# 给定风险水平下最大化收益
constraints.append({
'type': 'ineq',
'fun': lambda w: target_risk - portfolio_volatility(w)
})
objective = lambda w: -portfolio_return(w)
else:
# 最小化风险
objective = lambda w: portfolio_volatility(w)
if target_return is not None:
constraints.append({
'type': 'eq',
'fun': lambda w: portfolio_return(w) - target_return
})
result = minimize(objective, np.ones(n) / n, method='SLSQP',
bounds=bounds, constraints=constraints)
return result.x
# 示例:股债商三类资产配置
returns = np.array([0.08, 0.04, 0.05]) # 股票/债券/商品预期收益
cov = np.array([
[0.04, 0.005, 0.01],
[0.005, 0.01, 0.003],
[0.01, 0.003, 0.02]
])
weights = portfolio_optimize(returns, cov, target_risk=0.10)
print(f"最优配置: 股票{weights[0]:.1%}, 债券{weights[1]:.1%}, 商品{weights[2]:.1%}")
退休规划模型
def retirement_projection(current_age, retire_age, current_savings,
monthly_contribution, annual_return,
inflation_rate, monthly_expense_at_retire):
"""
退休规划测算
返回退休时的累计资产和可维持年限
"""
months_to_retire = (retire_age - current_age) * 12
r = annual_return / 12
inf = inflation_rate / 12
# 累计退休金:复利增长 + 定投
savings_at_retire = current_savings * (1 + r) ** months_to_retire + \
monthly_contribution * ((1 + r) ** months_to_retire - 1) / r
# 退休后月支出(考虑通胀)
real_monthly_expense = monthly_expense_at_retire * (1 + inf) ** months_to_retire
# 计算可维持年限
balance = savings_at_retire
months_sustained = 0
while balance > 0 and months_sustained < 12 * 50:
balance = balance * (1 + r) - real_monthly_expense
months_sustained += 1
return {
'退休时累计资产': round(savings_at_retire, 0),
'退休后月支出': round(real_monthly_expense, 0),
'可维持年限': round(months_sustained / 12, 1)
}
# 示例:35岁客户,60岁退休
proj = retirement_projection(
current_age=35, retire_age=60,
current_savings=300000,
monthly_contribution=8000,
annual_return=0.06,
inflation_rate=0.03,
monthly_expense_at_retire=8000
)
print(proj)
核心观点:财富管理AI不是替客户做决策,而是把模糊的"够不够养老"变成可量化的"按当前方案可维持X年"——可视化比预测更重要。
技术要点总结:资产配置的核心是均值-方差优化,退休规划的核心是复利累积+通胀折现的双向计算。两者结合,从"最优配置比例"到"退休可维持年限",形成完整的财富管理决策链。
总结:从算法到业务闭环
| 业务场景 | 核心算法 | 关键输出 | 业务价值 |
|---|---|---|---|
| 还款能力评估 | DTI+年金现值 | 授信额度 | 审批标准化 |
| 等额本息计算 | 年金公式推导 | 月供/还款计划 | 利率定价基础 |
| 信用评分 | WOE+逻辑回归 | 标准分→自动审批 | 88分秒批50万 |
| 客户分层 | RFM+K-Means | 分层标签 | 差异化经营 |
| 精准推荐 | 协同过滤+分层 | 产品TopN | AUM提升30-50% |
| 资产配置 | 均值-方差优化 | 配置权重 | 风险可控收益最大化 |
| 退休规划 | 复利+通胀模型 | 可维持年限 | 长期财务安全感 |
核心观点:银行零售AI不是单点算法的堆砌,而是从"评估-定价-审批-分层-营销-配置-规划"的完整业务闭环。每个算法服务于一个业务节点,节点之间通过数据和特征相互连接,最终实现"获客-活客-留客-升值"的全生命周期经营。
七个算法形成三条业务主线:信贷线(还款评估→等额本息→信用评分→自动审批)、零售线(RFM分层→精准推荐→AUM提升)、财富线(资产配置→退休规划→长期陪伴)。三条线的数据底座是统一的客户画像和交易流水,这正是银行做AI的天然优势——数据完整、业务闭环、场景明确。