催收评分卡(三)迁徙率模型

关注公众号“ 番茄风控大数据”,获取更多数据分析与风控大数据的实用干货。

在这里插入图片描述

  本文主要介绍迁徙率模型和还款率模型,至于失联模型,其实也不难做,难点是在于每家公司对失联客户的定义,主要是需要把多长失时间内失联的客户定义为目标客群,这个多长时间一般会定义为一天或者三天或者七天。只要把这个定义好了,就很好办了,有需要可以私下找我。

  接下来的文章着重介绍下迁徙率模型。为了解释方便,我以下文章介绍到的都是把迁徙率模型统一叫叫催收卡了。

  一般说的迁徙率模式是一种为了计算资产坏账回收状态和不同状态下的流动资产的流动指标,仅仅反映当下的状态,不具有预测性。

  我们本次需要开发的迁徙率预测模型,跟平时在催收部门所使用的迁徙模型叫法相同,但是算法却很不一样。在催收部门里,一般所所用的迁徙率的模型,指的是M0到M1,M1到M2,M2到M3等这些不同状态之间的迁徙的概率。比如M0-到M1的迁徙率计算公式是:分子是在处于M1这个状态下的在贷余额,分母是处于上一期处于M0的在贷余额,分组是前一期这批客户的在贷余额。所以在计算迁徙率算出来,可以表示资产不同时期的迁徙的情况。

  迁徙率是个非常重要的指标,能反应当前催收状态的坏账回收情况。比如下表:

在这里插入图片描述
  (关于迁徙率模型还可参考下我之前的文章:催收小词典

  1.如果你们公司还没有一张催收评分卡,我是非常建议你开发一张迁徙率模型评分卡的。前期就可以做精准催收,做温馨提醒。有些同学说,温馨提醒,我们公司是全体客户都发催收短信的,这个就免了吧。

  是,对于财大气粗的公司,不在乎每个月所发送的催收短信的费用。但是对于这些客户,难道不应该对某些重点客群加大催收的力度,除了催收短信外,不能使用ivr语音,或者力度再加猛点,使用人工提醒吗?你可以分成不同的对照组,把模型分出来的不同风险等级的客户,应用不同的策略,观察下使用的效果。要知道,有些公司的客群数量非常庞大,做催收精准,能进一步地提升催收效果,催回更多的逾期金额。

2.迁徙率模型的定义
  迁徙率模型的重点在于定义合作状态间的迁徙,在我公司内部,当起初没有一张催收评分卡的时候,我把上期公司业务的迁徙状态为M0和DPD1-4天的客户定义为好样本,把本期DPD4+以上的客户定义为坏样本。

  这里是有一些坑的,你在梳理客户状态的时候,是需要按照客户的dua-day的状态,把客户的还款计划表(list)和实际还款清单(payment_record)列出来的。比如对于A客户,还款日为每个月的1日。假如我们截取的客户5月跟6月的状态,那在5月1日至于6月1日,这段期间,如果客户没有逾期或者逾期在1-4天的情况下,我会考虑把A客户当成我们的建模样本,然后在6月1日到7月1日,这个观察期内,我会把客户是否逾期当成我的建模的考察的重要的目标变量。如果A客户逾期了,那他就是坏客户,如果不逾期就是好客户。

3.难点、重点与易错点
  难点:对于某些时间观测点的客户,因为需要观测期需要有一个完整的pieod,所以在建模的时间窗口的选择上除了,常用的观察期、表现期还需要加上缓冲期,以保障客群能凑成一个完整的pierod。

重点:
  因为这里是有区分观察期是非逾期和DPD1-4天的客户才属于建模样本,所以在这点在讲是因为需要把已经逾期的客户进行排除在外。因为我们此次建模只是预测从MO到DPD5+以上的客户,其他的客群我们是不做考察范围内的。

易错点:
  催收评分卡的难道,也是我躺过最大的坑,就是非常容易用Y预测Y。何为Y预测Y,通俗点说就是非常容易用逾期的客户将他当下的表现的数据再去预测当下的行为。造成这种错误的原因是你在模型定义的时候,没有把控好模型的定义。

4.模型各项验证指标
  模型参数的选择,首先应用的是传统的选择模型参数的方式,用的是IV值,在上一条中,如果你犯了我之前提到的用Y去预测Y的话,很抱歉,你将会出现某些变量的IV值异常大,有些已经突破1了。虽然在催收评分卡里有些变量的IV值确实比较高,但是iv值超过1的变量值,进入模型,肯定会拉升整个模型的精准度,你可能用一个变量做出来的ks值就能达到0.7。

  ks值达到0.7好吗?不是说IV值越大越好吗?其实不然。
  一个有区分能力的模型,其实KS值在0.3-0.6是比较理想的,如果达到0.7/ 0.8,等于模型已经将绝大多数的好或者坏客户在某个区间就分割开来了,之后的区间的客户将会有一个断崖式的切割,其实这样的模型出来是非常畸形的。KS值,很多书籍都有提到最少不能少于多少,然而最大值却很少有书籍有明确提及到,在此明确表示,KS并不是真的越大就越好。

数据清洗/数据治理

  1.数据清洗是一个非常修炼身心的过程,途中你除了需要把所有的数据整业务合到一张宽表里。而这种宽表中所有的字段,是你理解完业务后,细心整理出来的所有适合建模的数据。

  这里主要介绍下两大在催收模型中,最常用到的表。一个是payment表,一个是colletion表。(不同公司对这些表的叫法可能都不太一样).

  翻译成中文就是还款记录信息表与催收记录信息表。还款记录表主要记录了客户各种还款的数据,不过在我们公司里一般会把时间切片相同的还款记录,整合在一起,还款的金额是同个时间切片内的进还行叠加,最后一次还款的时间来覆盖之前的还款记录。

2.还款记录表(payment)
  先介绍还款记录表,还款记录表是一张记录客户,什么时间,通过什么方式还了多少钱的数据表格。

  通常这张表不是单独用,需要跟客户的还款计划表一起结合起来使用。比如列出该客户的所有的还款的计划账单,并且跟我们每期的还款记录表拼接,就可以判断,客户每个期数内是否有正常还款。

  我了解到有一些公司在做还款记录表的时候,会对某些内容进行修改,从而会影响后续的还款状态的逾期判断。比如一个坏账的客户,会将其坏账之后还款时间标记上(这个逻辑不要问我为什么)。

  从而你在判断他在这一期是否逾期的时候,不能单独利用还款时间(value_day)这个字段单独判断,还需要结合还款的金额跟理应还款金额进行作差比较。而且知道有些公司里,在算当前的期的时候,本金跟管理费还是分开来算的,所以在做这个判断的时候,最好是用还款的金额跟理应还款的本金的作差,这样算出来的结果似乎更偏向合理些,因为到了真正需要客户还款的时候,常常会发现将客户的管理费、利息统统豁免,所以用这种方式去计算是最好的。

  理清楚需要前面的这些逻辑后,其实你还需要将还款计划表进行转置,关于转置在SAS里是非常容易实现的,使用proc transpose就 可以了,在python里同样使用transpose(x)实现。工具真的不是最重要的,毕竟工具自己买本书或者上网找点资料自己看看也就行了,

  思路跟逻辑才是最关键的。只有好的思路,不管策略也好、模型数据也好、政策也好,才能真正把风控落实到实地。

  最后给大家看一下还款记录表长什么样子:

  字段太多了,整个屏幕都放不下,大概意思就是存放了客户还款的记录跟状态,不过这里会涉及到本金跟管理费的知识,还有账期跟账单的知识,单单看这个表还是有些看不懂。
3.催收记录表(colletion)
  接着介绍催收数据表。催收记录表,记录着我们催收人员与客户之间数据的联系,有着跟催收的相关的信息,比如PTP、KPTP、BP…关于对这催收的信息不太熟知的童鞋,请戳这里:催收小词典
   关于催收记录表,最后做成催收数据时候,也是需要类似还款记录那样,展开成一期一期的形式。

4.关于外部第三方数据表
  目前一些第三方数据源,仍是会从不同的渠道或者时间切片进行组合,比如百融的多头,聚信立的校验数据,极光的用户标签等数据。
在这里插入图片描述

  但是结合目前贷后的各种数据维度表现来看,外部第三方的数据都没有自家的客户的行为数据好用。毕竟自己的行为数据是最真实的。

5.衍生表
  衍生的数据,除了根据时间切片,只要脑洞够大,可以结合业务做成各种各样的数据,下面主要介绍三种最常用也非常好用的变量。

DPD
  这个变量理应不能叫衍生的变量,他也应该叫基础变量。但它其实是应该是由还款计划表和还款记录表一起来共同判断的。只要在dual_day之前,没有还款本金,都是DPD的时间。

  所以对于具体的DPD,需要有两个判断的条件,并且涉及的业务表格有3个表。

Kptprate
  这个变量主要有反应客户实际还款比例的,计算公式是kptp/ptp。单单用ptp的变量,比较容易造成催收员为了完成业绩故意下P的行为,再上kptp的一起来计算客户的实际还款比例,较好得控制了主观的数据干扰。

Period_percent
  已还期数占比的占比,这个变量整理出来也很有含义,我在做完这个变量的分组后,会发现这个变量的woe值是一个V形的走势。整理好的woe的曲线走势:

在这里插入图片描述
  大家可以先思考下,为什么在这个曲线符合真实的业务场景吗?这个变量的曲线最后输出为什么是一个V字行的曲线。

干货分享,直接上部分代码:
  下面直接上代码,大家直接在sas里直接运行这段代码,直接处理数据,有需要源数据的,请在后台留下微信,官微会发给大家。

DATA TMP.LIST_LOS;
SET DLOAN;
IF DUE_DAY=&DUE_DAY_NEED;
IF STS='ACTV';
 
LOAN_NO2=INPUT(LOAN_NO,$30.);
KEEP LOAN_TYPE LOAN_NO2 ORIG_PRCP TNR CHARGEOFF_REVERSAL_DATE STSDUE_DAY;
 
RENAME LOAN_NO2=LOAN_NO;
RENAME ORIG_PRCP=LOAN_AMOUNT;
RENAME TNR=TENOR;
RENAME CHARGEOFF_REVERSAL_DATE=CO_Date;
RENAME STS=STATUS;
RUN;
 
 
DATA TMP.LIST_NEW(KEEP=LOAN_TYPELOAN_NO LOAN_AMOUNT TENOR CO_Date STATUS DUE_DAY);
%let _EFIERR_ = 0; /* set the ERROR detection macro variable */                                     
    infile"C:\DRF_PLAGMMD_LOCAL_&WORKDAY..csv"  delimiter = ','MISSOVERDSDlrecl=32767firstobs=2 ;
       informatREPORT_DATE yymmdd10.;
       informatSTATUS $4.;
       informatBRANCH_CODE $4.;
       informatLOAN_TYPE $4.;
       informatLOAN_NO $30.;
       informatCUSTOMER_ID $19.;
       informatCOMMENCE_DATE yymmdd10.;
       informatFIRST_DUE_DATE yymmdd10.;
       informatMATURITY_DATE yymmdd10.;
       informatLAST_PAYMENT_DATE yymmdd10.;
       informatPAYMENT_METHOD $10.;
       informatLOAN_AMOUNT Best12.;
       informatINSTALMENT_AMT_1 Best12.;
       informatTENOR Best12.;
       informatTOTAL_AMOUNT_PAID Best12.;
       informatINTEREST_RATE_1 $10.;
       informatOD_INTEREST_RATE $10.;
       informatTOTAL_INTEREST_AMT Best12.;
       informatTOTAL_INTEREST_ACC Best12.;
       informatTOTAL_UPFRONT Best12.;
       informatTOTAL_OD_INT_PAID Best12.;
       informatDUE_DAY 3.;
       informatBUSINESS_MODE $10.;
       informatOS_AT_SETTLE Best12.;
       informatREFINANCE_BRANCH $8.;
       informatREFINANCE_LOAN_TYPE $8.;
       informatREFINANCE_LOAN_NO $19.;
       informatOD_DAYS 4.;
       informatNEXT_DUE_DATE yymmdd10.;
       informatOS_PRINCIPAL Best12.;
       informatTOTAL_INTEREST_PAID Best12.;
       informatTOTAL_PRINCIPAL_PAID Best12.;
       informatAPR $10.;
       informatFIRST_PAYMENT_DATE yymmdd10.;
       informatVENDOR_CODE $25.;
       informatLOAN_PURPOSE $100.;
       informatTOTAL_MGT_FEE Best12.;
       informatACC_MGT_FEE Best12.;
       informatPAID_MGT_FEE Best12.;
       informatENR Best12.;
       informatLOAN_BALANCE Best12.;
       informatCHARGEOFF_AMOUNT Best12.;
       informatCHARGEOFF_PRINCIPAL Best12.;
       informatCHARGEOFF_INTEREST Best12.;
       informatCHARGEOFF_MANAGEMENT_FEE Best12.;
       informatCHARGE_OFF_DATE yymmdd10.;   
       formatREPORT_DATE yymmdd10.;
       formatSTATUS $4.;
       formatBRANCH_CODE $4.;
       formatLOAN_TYPE  $4.;
       formatLOAN_NO $30.;
       formatCUSTOMER_ID $19.;
       formatCOMMENCE_DATE yymmdd10.;
       formatFIRST_DUE_DATE yymmdd10.;
       formatMATURITY_DATE yymmdd10.;
       formatLAST_PAYMENT_DATE yymmdd10.;
       formatPAYMENT_METHOD $10.;
       formatLOAN_AMOUNT Best12.;
       formatINSTALMENT_AMT_1 Best12.;
       formatTENOR Best12.;
       formatTOTAL_AMOUNT_PAID Best12.;
       formatINTEREST_RATE_1 $10.;
       formatOD_INTEREST_RATE $10.;
       formatTOTAL_INTEREST_AMT Best12.;
       formatTOTAL_INTEREST_ACC Best12.;
       formatTOTAL_UPFRONT Best12.;
       formatTOTAL_OD_INT_PAID Best12.;
       formatDUE_DAY 3.;
       formatBUSINESS_MODE $10.;
       formatOS_AT_SETTLE Best12.;
       formatREFINANCE_BRANCH $8.;
       formatREFINANCE_LOAN_TYPE $8.;
       formatREFINANCE_LOAN_NO $19.;
       formatOD_DAYS 4.;
       formatNEXT_DUE_DATE yymmdd10.;
       formatOS_PRINCIPAL Best12.;
       formatTOTAL_INTEREST_PAID Best12.;
       formatTOTAL_PRINCIPAL_PAID Best12.;
       formatAPR $10.;
       formatFIRST_PAYMENT_DATE yymmdd10.;
       formatVENDOR_CODE $25.;
       formatLOAN_PURPOSE $100.;
       formatTOTAL_MGT_FEE Best12.;
       formatACC_MGT_FEE Best12.;
       formatPAID_MGT_FEE Best12.;
       formatENR Best12.;
       formatLOAN_BALANCE Best12.;
       formatCHARGEOFF_AMOUNT Best12.;
       formatCHARGEOFF_PRINCIPAL Best12.;
       formatCHARGEOFF_INTEREST Best12.;
       formatCHARGEOFF_MANAGEMENT_FEE Best12.;
       formatCHARGE_OFF_DATE yymmdd10.;
      
 
    input                                                              
        REPORT_DATE
       STATUS
       BRANCH_CODE
       LOAN_TYPE
       LOAN_NO
       CUSTOMER_ID
       COMMENCE_DATE
       FIRST_DUE_DATE
       MATURITY_DATE
       LAST_PAYMENT_DATE
       PAYMENT_METHOD
        LOAN_AMOUNT
       INSTALMENT_AMT_1
       TENOR
       TOTAL_AMOUNT_PAID
        INTEREST_RATE_1
       OD_INTEREST_RATE
       TOTAL_INTEREST_AMT
       TOTAL_INTEREST_ACC
       TOTAL_UPFRONT
       TOTAL_OD_INT_PAID
       DUE_DAY
       BUSINESS_MODE
       OS_AT_SETTLE
       REFINANCE_BRANCH
       REFINANCE_LOAN_TYPE
       REFINANCE_LOAN_NO
       OD_DAYS
       NEXT_DUE_DATE
       OS_PRINCIPAL
       TOTAL_INTEREST_PAID
       TOTAL_PRINCIPAL_PAID
       APR
       FIRST_PAYMENT_DATE
       VENDOR_CODE
       LOAN_PURPOSE
       TOTAL_MGT_FEE
       ACC_MGT_FEE
       PAID_MGT_FEE
       ENR
       LOAN_BALANCE
       CHARGEOFF_AMOUNT
       CHARGEOFF_PRINCIPAL
       CHARGEOFF_INTEREST
       CHARGEOFF_MANAGEMENT_FEE
       CHARGE_OFF_DATE
     
    ;
 
    if _ERROR_ thencall symputx('_EFIERR_',1);  /* set ERROR detection macro variable */
 
    IF DUE_DAY=&DUE_DAY_NEED;
      IF STATUS IN ('NL','DQ');
 
      IF SUBSTR(LOAN_TYPE,1,1)IN ('1');
      IF LOAN_TYPE NOT IN('1201','1202','1204');
 
      RENAME  CHARGE_OFF_DATE=CO_Date;
RUN;
data tmp.list_new(rename=LOAN_TYPE_new=LOAN_TYPE);
set tmp.list_new;
LOAN_TYPE_NEW=input(LOAN_TYPE,4.);
DROP LOAN_TYPE;
run;
DATA TMP.LIST;
SET TMP.LIST_LOS  TMP.LIST_NEW;
RUN;
 
 
DATA TMP.COLLECT_RECORD;
SET dloan_message;
*IFLOAN_MESSAGE_TYPE='TEL';
IF CREATE_DATE>=&Begin_Date;
IF CREATE_DATE<='04APR2019'D;
 
IF LOAN_MESSAGE_CODE IN ('PTP','RTP','CRFP','L/M');
LOAN_NO2=INPUT(LOAN_NO,$30.);
KEEP LOAN_NO2     LOAN_MESSAGE_CODE CREATE_USER_ID    CREATE_DATE PTP_AMOUNT  PTP_DATE;
RENAME LOAN_NO2=LOAN_NO;
RUN;
 
 
procimport  out=dc.COLLECT_RECORD_NEW
 datafile="C:\COLLECT_RECORD_NEW.CSV"
 dbms=csv
 replace ;
 run;

DATA TMP.COLLECT_RECORD_NEW;
SET DC.COLLECT_RECORD_NEW;
IF CREATE_DATE >=&Begin_Date;
IF CREATE_DATE<=&CURRENT_DATE;
KEEP LOAN_NO      LOAN_MESSAGE_CODE CREATE_USER_ID    CREATE_DATE PTP_AMOUNT  PTP_DATE;
RUN;
 
 
data tmp.COLLECT_RECORD(rename=PTP_AMOUNT_new=PTP_AMOUNT);
set tmp.COLLECT_RECORD;
PTP_AMOUNT_NEW=input(PTP_AMOUNT,4.);
DROP PTP_AMOUNT;
run;
 
DATA TMP.COLLECT_RECORD_ALL;
SET TMP.COLLECT_RECORD TMP.COLLECT_RECORD_NEW;
RUN;
 
DATA TMP.PAYMENT;
  SET Dpayment_record;
  IF PERIOD=0THENDELETE;
  IF DUE_DATE >=&Begin_Date;
  LOAN_NO2=INPUT(LOAN_NO,$30.);
 IF SETTLE_PRINCIPAL=.THEN SETTLE_PRINCIPAL=0;
  IF SETTLE_INTEREST=.THEN SETTLE_INTEREST=0;
  IF SETTLE_FEE_AMOUNT=.THEN SETTLE_FEE_AMOUNT=0;
 
  KEEP LOAN_TYPE LOAN_NO2 PERIODDUE_DATE ACTUAL_DUE_DATE PRINCIPAL_AMOUNT INTEREST_AMOUNT FEE_AMOUNT VALUE_DATE SETTLE_PRINCIPALSETTLE_INTEREST SETTLE_FEE_AMOUNT;
  RENAME LOAN_NO2=LOAN_NO;
RUN;

proc import  out=DC.PAYMENT_CQ
 datafile="C:\share\MIS\MIS_DATA_SOURCE\New_s\PAYMENT_CQ.CSV"
 dbms=csv
 replace ;
 run;
 
DATA TMP.PAYMENT_NEW;
SET DC.PAYMENT_CQ;
IF CITY_CODE='1001';
IF DUE_DATE >=&Begin_Date ;
IF SETTLE_PRINCIPAL=.THEN SETTLE_PRINCIPAL=0;
IF SETTLE_INTEREST=.THEN SETTLE_INTEREST=0;
IF SETTLE_FEE_AMOUNT=.THEN SETTLE_FEE_AMOUNT=0;
KEEP LOAN_TYPE LOAN_NO PERIOD DUE_DATEACTUAL_DUE_DATE  PRINCIPAL_AMOUNTINTEREST_AMOUNT FEE_AMOUNT VALUE_DATE SETTLE_PRINCIPAL SETTLE_INTERESTSETTLE_FEE_AMOUNT;
RUN;
 
DATA TMP.PAYMENT_PLAN;
SET TMP.PAYMENT TMP.PAYMENT_NEW;
RUN;

PROCSORTDATA =TMP.PAYMENT_PLAN; BYLOAN_NO; RUN;
PROCSORTDATA =TMP.LIST; BY LOAN_NO; RUN;
 
DATA TMP.PAYMENT_PLAN1;
      MERGE TMP.PAYMENT_PLAN(IN=A) TMP.LIST(IN=B) ;
        BY LOAN_NO;
        IF B;        
RUN;
DATA TMP.PAYMENT_PLAN2;
SET TMP.PAYMENT_PLAN1;
KEEP LOAN_NO PERIOD DUE_DATE;
RUN;
 
PROCSORTDATA =TMP.PAYMENT_PLAN2; BYLOAN_NO PERIOD; RUN;
 
PROCTRANSPOSEDATA=TMP.PAYMENT_PLAN2 OUT=TMP.PAYMENT_PERIOD;
BY LOAN_NO;
ID PERIOD;
VAR DUE_DATE;
RUN;
 
DATA TMP.PAYMENT_LAST;
SET TMP.PAYMENT_PLAN1;
IF CO_Date^=.AND  DUE_DATE >= CO_Date  THENDELETE;
IF DUE_DATE<=&CURRENT_DATE1;
RUN;

PROCSORTDATA =TMP.PAYMENT_LAST; BYLOAN_NO PERIOD; RUN;
 
DATA TMP.PAYMENT_LAST1;
      SET TMP.PAYMENT_LAST;
        BY LOAN_NO PERIOD;
        IF LAST.LOAN_NO;
RUN;
 
DATA TMP.PAYMENT_LAST2;
SET TMP.PAYMENT_LAST1;
RENAME PERIOD=LAST_PERIOD;
RENAME DUE_DATE=LAST_DUE_DATE;
RUN;
DATA TMP.PAYMENT_NEED;
SET TMP.PAYMENT_LAST;
IF CO_Date^=.AND VALUE_DATE>=CO_Date THENDO;
        SETTLE_PRINCIPAL=0;
        SETTLE_INTEREST=0;
        SETTLE_FEE_AMOUNT=0;
        SETTLE_OD_INTEREST=0;
     END; 
RUN;
DATA TMP.PAY_PERIOD;
SET TMP.PAYMENT_NEED;
IFSUM(-SETTLE_PRINCIPAL,PRINCIPAL_AMOUNT)<0.01;
RUN;
 
PROCSORTDATA =TMP.PAY_PERIOD; BYLOAN_NO PERIOD; RUN;
 
DATA TMP.PAY_PERIOD1;
      SET TMP.PAY_PERIOD;
        BY LOAN_NO PERIOD;
        IF LAST.LOAN_NO;
     
RUN;
 
DATA TMP.PAY_PERIOD2;
SET TMP.PAY_PERIOD1;
KEEP LOAN_NO PERIOD;
RENAME PERIOD=PAY_PERIOD;
 
RUN;
PROC SORTDATA =TMP.COLLECT_RECORD_ALL; BYLOAN_NO; RUN;
PROC SORTDATA =TMP.LIST; BY LOAN_NO; RUN;
PROC SORTDATA =TMP.PAYMENT_PERIOD; BYLOAN_NO; RUN;
PROCS  ORTDATA =TMP.PAYMENT_LAST2; BYLOAN_NO; RUN;
 
DATA TMP.PAYMENT_ALL1;
      MERGE TMP.COLLECT_RECORD_ALL(IN=A) TMP.LIST(IN=B) TMP.PAYMENT_PERIOD (IN=C) TMP.PAYMENT_LAST2(IN=D);
        BY LOAN_NO; 
        IF B;        
RUN;

  十年职场生涯,这个长期混迹在风控界和科技界,摸爬滚打的大叔,曾经就职于全国最大的固网运营商平台、国内最大的ERP软件公司和一家老牌的互金公司,如果你想了解他,欢迎加他一起学习一起聊!(暗号:fanqie666+个人名字)。
在这里插入图片描述

  • 4
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值