美文网首页
信贷风控实战(七)——群组划分or聚类

信贷风控实战(七)——群组划分or聚类

作者: 老羊_肖恩 | 来源:发表于2023-02-23 22:46 被阅读0次

      信贷风控领域还有一个比较重要的环节,就是群组划分。一方面可以对客群进行一定的粗筛,另一方面也可以用来对已有的欺诈样本进行欺诈类别发现,以识别出不同的欺诈行为表现。在信贷风控实践中,我们可以使用聚类算法进行简单的群组划分,另外如果基于知识图谱或者复杂关系网络,我们还可以使用社区发现算法基于图进行一些群组的划分。常用的聚类算法有很多种,可以分别适用于不同数据分布情况下的聚类,这里主要介绍两种比较常用的聚类算法:k-Means和DBSCAN。

    聚类算法

    k-Means

      k-Means是一个比较经典的无监督聚类算法,该算法以最小化平方误差和为目标,在选定k的基础上,将样本点分发到指定的聚类中心上。下面简单的介绍一下k-Means算法的基本过程:

    1. 指定需要划分成的聚类个数k, 和最大迭代次数。
    2. 在样本空间中,随机选择k个样本点作为初始的聚类中心,然后计算样本空间中每个样本点与每个聚类中心的距离(在不同的场景下可以选择不同的距离度量方式,如欧氏距离,曼哈顿距离等)。将每个样本点划分到离它最近的聚类中心上,完成一次迭代。
    3. 求出每个聚类的质心,并将该质心作为新的聚类中心,然后迭代执行步骤2。当达到指定的迭代次数,或者质心的变化所引起的SSE的变化小于指定阈值时,即可停止迭代。
    4. 返回聚类结果。

      通过以上计算过程,我们可以发现k-Means聚类算法存在如下几个问题:

    1. 聚类中心的个数k怎么选取,选取多少合适?
    2. 随机初始化k个质心会导致算法结果的不稳定。
    3. k-Means算法在聚类的时候以质心为聚类参考,仅对“球形”分布的样本有效,对于一些分布比较奇特的样本,聚类效果较差。

      k-Means聚类算法中k的选择,一般有elbow方法和purity方法。下面我们以elbow方法为例展示k的选择过程。
    导入数据

    # 引入依赖包
    import numpy as np
    import pandas as pd
    from matplotlib import pyplot as plt
    from sklearn.cluster import KMeans
    
    # 数据导入
    data = pd.read_csv('Acard.txt')
    data.head()
    
    obs_mth bad_ind uid td_score    jxl_score   mj_score    rh_score    zzc_score   zcx_score   person_info finance_info    credit_info act_info
    0   2018-10-31  0.0 A10000005   0.675349    0.144072    0.186899    0.483640    0.928328    0.369644    -0.322581   0.023810    0.00    0.217949
    1   2018-07-31  0.0 A1000002    0.825269    0.398688    0.139396    0.843725    0.605194    0.406122    -0.128677   0.023810    0.00    0.423077
    2   2018-09-30  0.0 A1000011    0.315406    0.629745    0.535854    0.197392    0.614416    0.320731    0.062660    0.023810    0.10    0.448718
    3   2018-07-31  0.0 A10000481   0.002386    0.609360    0.366081    0.342243    0.870006    0.288692    0.078853    0.071429    0.05    0.179487
    4   2018-07-31  0.0 A1000069    0.406310    0.405352    0.783015    0.563953    0.715454    0.512554    -0.261014   0.023810    0.00    0.423077
    

    查看数据状况

    data.describe()
    
    bad_ind td_score    jxl_score   mj_score    rh_score    zzc_score   zcx_score   person_info finance_info    credit_info act_info
    count   95806.000000    95806.000000    95806.000000    95806.000000    95806.000000    95806.000000    95806.000000    95806.000000    95806.000000    95806.000000    95806.000000
    mean    0.018767    0.499739    0.499338    0.501640    0.498407    0.500627    0.499672    -0.078229   0.036763    0.063626    0.236197
    std 0.135702    0.288349    0.288850    0.288679    0.287797    0.289067    0.289137    0.156859    0.039687    0.143098    0.157132
    min 0.000000    0.000005    0.000013    0.000007    0.000005    0.000012    0.000010    -0.322581   0.023810    0.000000    0.076923
    25% 0.000000    0.250104    0.249045    0.250517    0.250115    0.249501    0.248318    -0.261014   0.023810    0.000000    0.076923
    50% 0.000000    0.500719    0.499795    0.503048    0.497466    0.501688    0.499130    -0.053718   0.023810    0.000000    0.205128
    75% 0.000000    0.747984    0.748646    0.752032    0.747188    0.750986    0.750683    0.078853    0.023810    0.060000    0.346154
    max 1.000000    0.999999    0.999985    0.999993    0.999986    0.999998    0.999987    0.078853    1.023810    1.000000    1.089744
    

      通过describe观察,我们发现这些数据都是经过特殊处理的数据,不同特征之间不存在明显的量纲问题,因此无需进行归一化。这里需要注意的是,如果各特征之间存在明显的量纲差异,一定要归一化,一定要归一化!!!

    Elbow方法选k

    # 选择特征列
    features = data[['td_score', 'jxl_score', 'mj_score',
           'rh_score', 'zzc_score', 'zcx_score', 'person_info', 'finance_info',
           'credit_info', 'act_info']]
    
    # 使用手肘法选取最优K值
    sse = {}
    for k in range(1, 10):
        kmeans = KMeans(n_clusters=k).fit(features)
        features["clusters"] = kmeans.labels_
        sse[k] = kmeans.inertia_ 
        
    plt.figure()
    plt.plot(list(sse.keys()), list(sse.values()))
    plt.xlabel("Number of cluster")
    plt.ylabel("SSE")
    plt.show()
    

      通过观察我们发现,在k为2和4的时候,SSE的变化最大,这里我们选择k为4进行k-Means聚类。

    ##此处选择四个簇
    model=KMeans(n_clusters=4) 
    model.fit(features)
    
    predicted_label = model.predict(features)
    features['clusters'] = predicted_label
    features
    

    聚类结果如下:


      由于随机初始化k个质心会导致算法结果的不稳定。其实上面的算法,多执行几次的话就会发现我们得到的SSE的图是不一样的,因此在初始化k个聚类中心的时候也有一些方式,比如:选取距离尽量远的K个样本点作为中心点:随机选取第一个样本C1作为第一个中心点,遍历所有样本选取离C1最远的样本C2为第二个中心点,以此类推,选出K个初始中心点。针对k-Means存在的第三个问题,通常需要使用其他的算法来解决,比如我们接下来要介绍的DBSCAN。

    DBSCAN

      DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法。与k-Means聚类方法不同,它将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域划分为簇,并可在噪声的空间数据中发现任意形状的聚类。因此DBSCAN除了能实现聚类外,还能顺带把异常检测的事儿给做了,所有不能划分到某个簇中的数据都可以认为是异常数据。在简单介绍DBSCAN算法的实现过程之前,先介绍几个跟DBSCAN相关的概念:
      \epsilon领域:指的是样本点为中心,半径为半径\epsilon划定的范围区域。领域半径\epsilon是我们在调用这个算法的时候需要输入的入参之一,\epsilon用来指示当前样本的领域大小。
      最小点数MinPts:最小点数用来评估某个样本点\epsilon领域的密度,如果一个样本点的\epsilon领域中的样本点数小于MinPts,则证明其密度比较系数。最小点数MinPts也是算法的输入参数之一。
      核心点:如果一个样本点的\epsilon领域内的样本点数不小于最小点数MinPts,则称之为核心点。
      边界点:不属于核心点但在某个核心点的\epsilon领域内的点叫做边界点。
      噪声点:既不属于核心点也不属于边界点的点称之为是噪声点。
      密度直达:如果P为核心点,Q在P的\epsilon邻域内,那么称P到Q密度直达。任何核心点到其自身密度直达,密度直达不具有对称性,如果P到Q密度直达,那么Q到P不一定密度直达,因为Q不不一定为核心点。
      密度可达:如果存在核心点P1,P2,P2,P3,…,Pn,且P1到P2密度直达,P2到P3密度直达,……,P(n-1)到Pn密度直达,Pn到Q密度直达,则P1到Q密度可达。密度可达也不具有对称性,因为密度直达不具有对称性。
      密度相连:如果存在核心点S,使得S到P和Q都密度可达,则P和Q密度相连。密度相连具有对称性,如果P和Q密度相连,那么Q和P也一定密度相连。密度相连的两个点属于同一个聚类簇。
      非密度相连:如果两个点不属于密度相连关系,则两个点非密度相连。非密度相连的两个点属于不同的聚类簇,或者其中存在噪声点。
    在介绍完上述概念之后,我们正式介绍DBSCAN算法的流程:

    1. 从数据集中任意选取一个数据对象点p
    2. 如果对于\epsilon领域和最小点数MinPts,所选取的数据对象点p为核心点,则从样本空间中找出所有从p密度可达的数据对象点,形成一个簇;
    3. 如果选取的数据对象点p是边界点,进入下一轮,重新选择另一个数据样本点;
    4. 重复步骤2和3,直到所有样本点都被处理。

    代码实现如下:
    导入数据

    # 引入依赖包
    import numpy as np
    import pandas as pd
    from matplotlib import pyplot as plt
    from sklearn.cluster import DBSCAN
    
    # 数据导入
    data = pd.read_csv('Acard.txt')
    data.head()
    
        obs_mth bad_ind uid td_score    jxl_score   mj_score    rh_score    zzc_score   zcx_score   person_info finance_info    credit_info act_info
    0   2018-10-31  0.0 A10000005   0.675349    0.144072    0.186899    0.483640    0.928328    0.369644    -0.322581   0.023810    0.00    0.217949
    1   2018-07-31  0.0 A1000002    0.825269    0.398688    0.139396    0.843725    0.605194    0.406122    -0.128677   0.023810    0.00    0.423077
    2   2018-09-30  0.0 A1000011    0.315406    0.629745    0.535854    0.197392    0.614416    0.320731    0.062660    0.023810    0.10    0.448718
    3   2018-07-31  0.0 A10000481   0.002386    0.609360    0.366081    0.342243    0.870006    0.288692    0.078853    0.071429    0.05    0.179487
    4   2018-07-31  0.0 A1000069    0.406310    0.405352    0.783015    0.563953    0.715454    0.512554    -0.261014   0.023810    0.00    0.423077
    

    DBSCAN聚类

    # 选择特征列
    features = data[['td_score', 'jxl_score', 'mj_score',
           'rh_score', 'zzc_score', 'zcx_score', 'person_info', 'finance_info',
           'credit_info', 'act_info']]
    
    # 指定入参
    clustering = DBSCAN(eps=0.5, min_samples=5).fit(features)
    
    features['clusters'] = clustering.labels_
    features.head()
    
        td_score    jxl_score   mj_score    rh_score    zzc_score   zcx_score   person_info finance_info    credit_info act_info    clusters
    0   0.675349    0.144072    0.186899    0.483640    0.928328    0.369644    -0.322581   0.023810    0.00    0.217949    0
    1   0.825269    0.398688    0.139396    0.843725    0.605194    0.406122    -0.128677   0.023810    0.00    0.423077    0
    2   0.315406    0.629745    0.535854    0.197392    0.614416    0.320731    0.062660    0.023810    0.10    0.448718    0
    3   0.002386    0.609360    0.366081    0.342243    0.870006    0.288692    0.078853    0.071429    0.05    0.179487    0
    4   0.406310    0.405352    0.783015    0.563953    0.715454    0.512554    -0.261014   0.023810    0.00    0.423077    0
    

      与k-Means不同,DBSCAN作为一种基于密度的聚类算法,其最终生成的簇的数量并不是在算法执行的时候认为设定的,而是根据输入的邻域半径和邻域中最小样本数决定的。因此使用DBSCAN前需要充分了解当前数据,这样才能设定合理的密度条件,以达到正确的聚类目标。相比较K-Means中K值得设定,DBSCAN得参数调整相对较复杂,需要对领域半径\epsilon和最小样本数MinPts 同时进行联合调参。
    DBSCAN,因此关于DBSCAN有如下问题需要注意:

    1. 样本集的密度不均匀、聚类间距差相差很大时,DBSCAN得聚类质量较差。
    2. 样本集较大时,算法收敛时间较长,此时可以对搜索最近邻时建立的 KD 树来加速选最近点的性能。
    3. 需要对距离阈值\epsilon和邻域样本数阈值MinPts进行联合调参,不同的参数组合对聚类效果有较大影响。

    总结一下

    1. 与k-Means方法相比,DBSCAN不需要事先知道要形成的簇类的数量。
    2. 与k-Means方法相比,DBSCAN可以发现任意形状的簇类。
    3. DBSCAN能够识别出样本点中的噪声点。
    4. 如果数据集中存在不同密度的簇或者嵌套簇,则DBSCAN 算法无法处理。

    信贷风控实战系列

    信贷风控实战(一)——建模流程总览
    信贷风控实战(二)——策略生成及规则挖掘
    信贷风控实战(三)——评分卡建模之逻辑回归
    信贷风控实战(四)——评分卡建模之XGBoost
    信贷风控实战(五)——特征工程
    信贷风控实战(六)——异常检测
    信贷风控实战(七)——群组划分or聚类

    相关文章

      网友评论

          本文标题:信贷风控实战(七)——群组划分or聚类

          本文链接:https://www.haomeiwen.com/subject/gzklkdtx.html