信贷风险算法讲解

215 阅读5分钟

信用风险分析算法详解

算法概述

这个信用风险分析服务通过评估多个财务指标来计算客户的信用风险评分和等级。算法综合考虑了客户的逾期记录、提前还款行为、收入水平、贷款余额、利率和信用评分等因素。

输入参数

算法需要以下6个关键输入参数:

  • overdueTimes: 逾期次数
  • prepaymentTimes: 提前还款次数
  • incomeLevel: 收入水平(1-10级)
  • creditBalance: 贷款余额(元)
  • interestRate: 贷款利率(%)
  • creditScore: 信用评分(0-100分)

评分计算流程

1. 各指标标准化处理

每个指标被转换为0-100分的标准化分数:

  1. 逾期次数(overdueScore):

    • 公式: 100 - (overdueTimes * 10)
    • 说明: 每次逾期扣10分,基础分100分
  2. 提前还款次数(prepaymentScore):

    • 公式: 50 + (prepaymentTimes * 2)
    • 说明: 每次提前还款加2分,基础分50分
  3. 收入水平(incomeScore):

    • 公式: incomeLevel * 10
    • 说明: 收入等级直接乘以10转换为分数(1级=10分,10级=100分)
  4. 贷款余额(balanceScore):

    • 公式: 100 - (creditBalance / 10000)
    • 说明: 每1万元贷款余额扣1分,基础分100分
  5. 贷款利率(rateScore):

    • 公式: 100 - (interestRate * 5)
    • 说明: 每1%利率扣5分,基础分100分
  6. 信用评分(creditScore):

    • 直接使用输入的0-100分信用评分

2. 分数范围限制

所有标准化分数被限制在0-100分范围内:

Math.max(0, Math.min(100, score))

3. 加权计算总分

各指标按以下权重计算加权总分:

指标权重
逾期次数25%
提前还款次数15%
收入水平15%
贷款余额15%
贷款利率10%
信用评分20%

总分计算公式:

totalScore = overdueScore*0.25 + prepaymentScore*0.15 + incomeScore*0.15 
           + balanceScore*0.15 + rateScore*0.1 + creditScore*0.2

4. 风险等级划分

根据总分确定风险等级:

分数范围风险等级风险程度
≥80A低风险
60-79B中风险
<60C高风险

算法特点

  1. 多维度评估: 综合考虑了还款行为、财务状况和信用历史
  2. 权重分配: 逾期记录和信用评分权重最高(25%和20%),反映其重要性
  3. 反向指标处理: 对贷款余额和利率这类"越低越好"的指标进行了反向计分
  4. 分数标准化: 所有指标统一转换为0-100分,便于比较和加权
  5. 边界控制: 确保各项分数在合理范围内

业务逻辑流程

  1. 检查输入参数完整性
  2. 计算各项指标分数
  3. 计算加权总分
  4. 确定风险等级
  5. 保存分析结果到数据库
  6. 返回分析结果

核心代码部分

// 声明这是一个Spring服务层的组件
@Service
public class CreditRiskService {

    // 自动注入数据访问层组件
    @Autowired
    private CreditRiskAnalysisDao creditRiskAnalysisDao;
    
    // 主方法:计算信用风险
    public CreditRiskAnalysis calculateRisk(CreditRiskAnalysis request) {
        /* 
         * 参数校验部分
         * 检查6个必要参数是否都已提供
         * 如果任一参数为null,抛出非法参数异常
         */
        if (request.getOverdueTimes() == null || request.getPrepaymentTimes() == null || 
            request.getIncomeLevel() == null || request.getCreditBalance() == null || 
            request.getInterestRate() == null || request.getCreditScore() == null) {
            throw new IllegalArgumentException("输入关键数据过少,需要提供全部6个关键数据");
        }
        
        // 调用私有方法计算风险评分(0-100分)
        int riskScore = calculateRiskScore(request);
        
        // 根据评分确定风险等级(A/B/C三级)
        String riskLevel = determineRiskLevel(riskScore);
        
        // 创建新的分析结果对象
        CreditRiskAnalysis analysis = new CreditRiskAnalysis();
        // 设置原始数据字段
        analysis.setOverdueTimes(request.getOverdueTimes());       // 逾期次数
        analysis.setPrepaymentTimes(request.getPrepaymentTimes()); // 提前还款次数
        analysis.setIncomeLevel(request.getIncomeLevel());        // 收入等级(1-10)
        analysis.setCreditBalance(request.getCreditBalance());    // 贷款余额(元)
        analysis.setInterestRate(request.getInterestRate());      // 贷款利率(%)
        analysis.setCreditScore(request.getCreditScore());        // 信用评分(0-100)
        // 设置计算结果字段
        analysis.setRiskLevel(riskLevel);    // 风险等级(A/B/C)
        analysis.setRiskScore(riskScore);    // 风险评分(0-100)
        // 设置时间字段
        analysis.setCreateTime(LocalDateTime.now()); // 记录创建时间

        // 将分析结果保存到MySQL数据库
        creditRiskAnalysisDao.insert(analysis);
        
        // 返回完整的分析结果对象
        return analysis;
    }
    
    /**
     * 私有方法:计算风险评分
     * 使用加权算法计算综合评分
     * @param request 包含各项指标的对象
     * @return 0-100分的风险评分
     */
    private int calculateRiskScore(CreditRiskAnalysis request) {
        // 配置各指标的权重系数(总和为1)
        double overdueWeight = 0.25;    // 逾期次数权重25%
        double prepaymentWeight = 0.15; // 提前还款权重15%
        double incomeWeight = 0.15;     // 收入水平权重15%
        double balanceWeight = 0.15;    // 贷款余额权重15%
        double rateWeight = 0.1;        // 利率权重10%
        double scoreWeight = 0.2;       // 信用评分权重20%
        
        /* 
         * 指标标准化处理:
         * 将各指标转换为0-100分的标准分
         */
        // 逾期次数:每次逾期扣10分,基础分100分
        double overdueScore = 100 - (request.getOverdueTimes() * 10); 
        // 提前还款:每次加2分,基础分50分
        double prepaymentScore = 50 + (request.getPrepaymentTimes() * 2); 
        // 收入水平:1-10级转换为10-100分
        double incomeScore = request.getIncomeLevel() * 10; 
        // 贷款余额:每1万元扣1分(反向指标)
        double balanceScore = 100 - (request.getCreditBalance().doubleValue() / 10000); 
        // 贷款利率:每1%扣5分(反向指标)
        double rateScore = 100 - (request.getInterestRate().doubleValue() * 5);   
        // 信用评分:直接使用0-100分
        double creditScore = request.getCreditScore(); 
        
        /* 
         * 分数范围限制:
         * 确保各指标分数在0-100分之间
         */
        overdueScore = Math.max(0, Math.min(100, overdueScore));
        prepaymentScore = Math.max(0, Math.min(100, prepaymentScore));
        incomeScore = Math.max(0, Math.min(100, incomeScore));
        balanceScore = Math.max(0, Math.min(100, balanceScore));
        rateScore = Math.max(0, Math.min(100, rateScore));
        creditScore = Math.max(0, Math.min(100, creditScore));
        
        // 计算加权总分
        double totalScore = overdueScore * overdueWeight + 
                          prepaymentScore * prepaymentWeight + 
                          incomeScore * incomeWeight + 
                          balanceScore * balanceWeight + 
                          rateScore * rateWeight + 
                          creditScore * scoreWeight;
        
        // 四舍五入取整后返回
        return (int) Math.round(totalScore);
    }

    /**
     * 私有方法:确定风险等级
     * @param score 风险评分(0-100)
     * @return 风险等级(A/B/C)
     */
    private String determineRiskLevel(int score) {
        // A级:80分及以上(低风险)
        if (score >= 80) {
            return "A";
        }
        // B级:60-79分(中风险)
        else if (score >= 60) {
            return "B";
        } 
        // C级:60分以下(高风险)
        else {
            return "C";
        }
    }
}

使用建议

  1. 确保输入所有6个关键参数
  2. 收入水平应预先标准化为1-10级
  3. 信用评分应为0-100分的标准化值
  4. 可根据业务需求调整权重参数
  5. 定期评估和调整评分标准以适应市场变化