精华内容
下载资源
问答
  • 随着金融产品不断创新,商业银行交易操作变得日益复杂,由于交易风险引发商业银行安全事故频出。目前,商业银行主要从规章制度上规范交易操作步骤以及使用信息系统对当天交易产生票据进行复核做到事后监督,而对...
  • 以某互联网金融平台用户交易数据为对象,通过分析其中借贷逾期违约传播行为,提出通过传播特征构建模型算法识别互联网金融平台风险用户。在构建基于阈值传播和随机传播SIS和SIR模型基础上,将模型转换...
  • 交易的识别与分类方法—DeepEye。 本文通过系统分析A股市场上现 有的九类程序化交易类型,构建了程序化交易特征指标体系。同 时,首次尝试将深度学习人工智能技术用于程序化交易的识别和分 类,不仅使 DeepEye 整体...
  • 电子商务交易信用风险研究,徐铭蔚,张晗,本文在了解国外电子商务信用风险识别理论研究现状、电子商务信用风险理论以及神经网络基本理论基础上,对电子商务信用风险进行
  •  因为案例背景中有说道,因为风控系统会基于对交易的风险判断而失败掉很多高危交易,这些交易因为被失败了往往没有了标签,而这部分数据又极其重要。所以这里我们可以相信既然系统都判断你是高危交易了,我就直接...

      

    默认无标签的都是黑样本。


            因为案例背景中有说道,因为风控系统会基于对交易的风险判断而失败掉很多高危交易,这些交易因为被失败了往往没有了标签,而这部分数据又极其重要。所以这里我们可以相信既然系统都判断你是高危交易了,我就直接认为你是风险交易好了。相信蚂蚁金服线上风险评估系统,没毛病吧,哈哈。

            加上这次共994731条数据,有标签的990006条(16847条有风险,973159条无风险),无标签的数据有4725。无标签认定为风险数据也说得过去。

            这次换用xgboost加交叉验证(kfold=5),得到混淆矩阵结果如下:


            可见对风险数据样本召回真的是爆表啊(高达0.788),但是这模型太过分了,显然是不行的,绝大多数交易都被认定成有风险的,如真实无风险的被判定为无风险的有408条,真实无风险的被判定为有风险点的则有292869条,如果这样,应用肯定无法正常进行交易了。。。但我们可以用此模型去标记无标签数据。宁可错杀一百,不愿放过一个。

            试了下,这样确实可以提升模型效果。








    展开全文
  • 赛题目的是根据历史交易数据识别当前交易是否为欺诈交易。举办方给出由一段时间内有正负标签样本支付行为样本和没有标签支付行为样本组成训练数据集和一段时间后某个时间范围内支付行为样本构成测试...

    赛题的目的是根据历史交易数据识别当前交易是否为欺诈交易。举办方给出由一段时间内有正负标签样本的支付行为样本和没有标签的支付行为样本组成的训练数据集和一段时间后的某个时间范围内的支付行为样本构成的测试数据集,希望选手们通过机器学习算法和对无标签数据的挖掘在训练集上训练出性能稳定时效性好的模型,能够在测试集上对交易的风险进行精准判断。

    赛题主页:https://dc.cloud.alipay.com/index#/topic/intro?id=4&from=alipay

    分析训练样本

    一共有994,731条训练数据,对于需要验证的标签,一共有三种,分别是0,1,-1。其中98.3%的用户的标签是0,1.21%的用户是1,0.48%的用户标签是-1。训练样本包含了62天的数据信息,时间区间从20170905到20171105,平均每天的记录规模是16000个。

    import pandas as pd
    import numpy as np
    from pandas import DataFrame,Series
    import matplotlib.pyplot as plt
    import sys
    
    import seaborn as sns
    #import lightgbm as lgb
    import gc
    import time
    from sklearn import preprocessing
    from sklearn.metrics import precision_recall_curve
    from sklearn.model_selection import train_test_split
    from sklearn.feature_selection import VarianceThreshold
    
    # 读取数据内容,并保存为dataframe格式
    data = pd.read_csv('./input/atec_anti_fraud_train.csv')
    data['id'] = data['id'].astype('category')
    data['label'] = data['label'].astype('category')
    # print(data.describe())
    # 查看样本的标签的分布情况
    fre = data.label.value_counts()
    # 观察每天的数据量
    date_info = data['date'].value_counts().sort_index()
    data.describe()
                   date             f1  ...           f296           f297
    count  9.947310e+05  994731.000000  ...  787146.000000  787146.000000
    mean   2.017098e+07       0.726283  ...      41.244121      99.023500
    std    6.011735e+01       0.651947  ...      45.658241      96.240483
    min    2.017090e+07       0.000000  ...       1.000000       1.000000
    25%    2.017092e+07       0.000000  ...       2.000000       2.000000
    50%    2.017101e+07       1.000000  ...      17.000000     115.000000
    75%    2.017102e+07       1.000000  ...      79.000000     194.000000
    max    2.017110e+07       2.000000  ...     280.000000     299.000000
    
    [8 rows x 298 columns]
    ----------------------------------------
    fre = data.label.value_counts()
     0    977884
     1     12122
    -1      4725
    Name: label, dtype: int64
    ----------------------------------------
    # print(date_info) # 平均每天的记录规模,从20170905到20171105
    # 20171029    15592
    # 20171030    16455
    # 20171031    16596
    # 20171101    17884
    # 20171102    17305
    # 20171103    16406
    # 20171104    15639
    # 20171105    15891
    # Name: date, Length: 62, dtype: int64
    

    标签为-1的样本的处理  

    -1是未知标签,因此在这个问题上,合理使用这些样本是一个加分关键点。

    1. 完全不考虑label为-1的情况(可以作为baseline)
    2. 将label为-1的全部标记为1,放入训练集。因为这些因为异常被中断的交易是蚂蚁风控系统认为风险比较大的交易,因此可能蕴含着异常交易的特征,可以用于补充label 1样本太少的问题。
    3. 使用机器学习算法对label为-1样本进行预测学习,将被大概率预测为1的样本标记为1,放入训练集中。

    第二种处理方式的效果要优于另外两种方式

    特征分析和选择 

    赛方一共提供了298个特征列,在使用全部的特征进行模型训练时,发现模型指标只能在0.30左右,陷入局部最优。因此需要对特征列进行分析,选择真正对结果有帮助的特征列。因为特征列的缺失情况不一,为避免缺失值填充对特征选择的影响,要特征选择。选择的主要依据有

    1. 特征的缺失率不能太大。若大部分样本都缺失,则特征无用。
    2. 训练集和测试集的特征分布一致,不能有太大的偏差。否则建立的模型不具备泛化能力。
    3. 标签在不同的特征值上的分布具有差异性
    4. 通过gdbt算法训练出的模型选择重要特征

    缺失率分析

    对所有的特征检查数据缺失,可以发现很多不同的但是序号连续的特征可能是互相关联的。比如f1-f4,都是三值函数,都没有缺失。f20-f23都缺失了207448条记录。有如下结论,缺失值为x的特征一定同时缺失,也就是说如果A列特征缺失x条,B列特征也缺失x条,那么一条记录中,A和B要么同时缺失,要么同时不缺失。

    # 检查特征的缺失情况,第一列是缺失数量,第二列是特征列数量
    data_lost=data.isnull().sum().reset_index(name='count')
    data_lost.columns=['feature','counts']
    lost_count=data_lost.groupby('counts',as_index='False').count()
    print(data.isnull().sum())
    id            0
    label         0
    date          0
    f1            0
    f2            0
    f3            0
    f4            0
    f5       199825
    f6            0
    ...
    f288     207585
    f289     207585
    f290     207585
    f291     207585
    f292     207585
    f293     207585
    f294     207585
    f295     207585
    f296     207585
    f297     207585
    Length: 300, dtype: int64
    
    #print(lost_count)
    #         feature
    # counts
    # 0            21
    # 919          48
    # 136021       69
    # 199825        1 # 缺失数量为199825的特征只有一个
    # 207448        6
    # 207585       24
    # 211036        4
    # 270515       78
    # 273904       14
    # 286285        5
    # 341661       14
    # 341887        4
    # 925781       12

    可以发现虽然一共有298个特征列,但是数据的缺失数量只有13个不同的值。可以看到有12个特征他们的缺失情况是925781,大部分的样本都没有数据。只有139个特征的缺失率是低于20%。对于这样的数据分布,我们尝试了不同的特征删除策略:删除缺失率大于20%,30%,40%,50%等等。

    在对测试集进行缺失值分析的时候,查看了测试集的特征。发现对于相同的特征,训练集和测试集的缺失情况不尽相同,因此对于缺失率相差比较大的特征列,最好也删除。否则训练集的特征对于测试集没有很好的适应能力。

    训练集和测试集的分布情况 

    正常的情况下,训练集和测试集的特征分布应该一致,这样根据训练集训练得到的模型才对测试集适用。一致的分布意味着,取值范围一致,概率密度核kde分布曲线类似。

    def plot_kde(train, test, col, values=True):
        fig, ax = plt.subplots(1, 4, figsize=(15, 5))
    
        sns.kdeplot(train[col][train['label'] == 0], color='g', ax=ax[0])
        sns.kdeplot(train[col][train['label'] == 1], color='r', ax=ax[0])
        sns.kdeplot(train[col][train['label'] == -1], color='y', ax=ax[0])
        sns.kdeplot(train[col], color='y', ax=ax[1])
    
        sns.kdeplot(test[col], color='b', ax=ax[2])
        sns.kdeplot(train[col], color='y', ax=ax[3])
        sns.kdeplot(test[col], color='b', ax=ax[3])
        plt.show()
        del train, col, test
        gc.collect()
    
    train_data = pd.read_csv('./input/atec_anti_fraud_train.csv')
    test_data = pd.read_csv('./input/atec_anti_fraud_test_b.csv')
    
    col_need = ['f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12', 'f13', 'f14', 'f15', 'f16',
                'f17', 'f18', 'f19', 'f20', 'f21',
                'f22', 'f23', 'f24', 'f25', 'f26', 'f27', 'f28', 'f29', 'f30', 'f31', 'f52', 'f53', 'f161', 'f162', 'f163',
                'f164', 'f165', 'f211',
                'f212', 'f213', 'f214', 'f215', 'f216', 'f217', 'f218', 'f219', 'f220', 'f221', 'f222', 'f223', 'f224',
                'f225', 'f226', 'f227',
                'f228', 'f229', 'f230', 'f231', 'f232', 'f233', 'f234', 'f235', 'f236', 'f237', 'f238', 'f239', 'f240',
                'f241', 'f242', 'f243',
                'f244', 'f245', 'f246', 'f247', 'f248', 'f249', 'f250', 'f251', 'f252', 'f253', 'f254', 'f255', 'f256',
                'f257', 'f258', 'f259',
                'f260', 'f261', 'f262', 'f263', 'f264', 'f265', 'f266', 'f267', 'f268', 'f269', 'f270', 'f271', 'f272',
                'f273', 'f274', 'f275',
                'f276', 'f277', 'f278', 'f279', 'f280', 'f281', 'f282', 'f283', 'f284', 'f285', 'f286', 'f287', 'f288',
                'f289', 'f290', 'f291',
                'f292', 'f293', 'f294', 'f295', 'f296', 'f297']
    
    for col in train_data.columns:
        if col != 'id' and col != 'label' and col in col_need:
            plot_kde(train_data, test_data, col)

    其中左图为训练集的分布kde,中图为测试集的kde,右图为训练集和测试集的合并在一起观察的情况: 

     

     

     

    记录

    "array must not contain infs or NaNs")
    ValueError: array must not contain infs or NaNs

    筛选具有辨识能力的特征 

    对于特定的特征,如果样本标签在各值上的分布没有明显的区别,那么这个特征对于最终的预测能起到的作用很小。相反,如果某个特征值上异常交易占比特别高,那么当新样本出现这个特征值时,系统就会引起警觉。常规的方式有

    1. 通过训练集特征与label的pearson相关性选择特征
    2. 通过观察异常交易在每个特征值上的占比情况选择特征

    以2为例,

    feat=['f1','f2','f3','f4']
    fig = plt.figure()
    fig.set(alpha=0.2)
    i=0
    for feature in feat:
        safe_user = data[data.label == 0][feature].value_counts()
        risk_user= data[data.label == 1][feature].value_counts()
        rate=risk_user.div(safe_user)
        plt.subplot2grid((2,2),(int(i/2),int(i%2)))
        rate.plot(kind='bar')
        i=i+1
        plt.title(feature + u"危险用户/安全用户")
    plt.show()

    以前四个特征为例,前四个特征是三值特征,即 每个特征的取值只有0,1,2三个值。检查label为0和1,与特征为0,1,2之间的关系.可以明确的发现对于前4个特征来说,当其为2时,危险交易数目/正常交易数目的比率明显高于其他两个值。尤其是f2特征,这个比率达到了0.25。

    f10的三个值占比都很平均,无法通过这个特征单一分析出交易是否是异常交易的概率,对标签不具有敏感性。在特征选择的时候,这样的特征最好删除。

    经过上面的三层分析,可以删掉很大的一部分特征了。在这里比赛中,主要使用了上面的方式进行特征的筛选,而使用随机森林以及GBDT的方式则略作涉猎,并没有系统的作为依据。

    #筛选之后剩下的需要使用的特征
    col_need=['f1', 'f2', 'f3', 'f4', 'f6', 'f7', 'f8', 'f9', 'f11',
           'f12', 'f13', 'f14', 'f15', 'f16', 'f17', 'f18', 'f19', 'f161',
           'f162', 'f163', 'f164', 'f165', 'f211', 'f212', 'f213', 'f214',
           'f215', 'f216', 'f217', 'f218', 'f219', 'f220', 'f221', 'f222',
           'f223', 'f224', 'f225', 'f226', 'f227', 'f228', 'f229', 'f230',
           'f231', 'f232', 'f233', 'f234', 'f235', 'f236', 'f237', 'f238',
           'f239', 'f240', 'f241', 'f242', 'f243', 'f244', 'f245', 'f246',
           'f247', 'f248', 'f249', 'f250', 'f251', 'f252', 'f253']
    
    #这个函数用于将其余的不需要的特征列删除
    def preprocess_likeo(df,col_need):
        num =0
        drop_cols=[]
        for col in df.columns:
            if(col not in col_need):    
                drop_cols.append(col)
                num= num +1
        df.drop(drop_cols,axis=1,inplace=True)
        print('drop ',num, " features in data set")
        return df

    缺失值的填充 

    在对每个特征进行分析,然后通过实验综合考量得到训练特征之前,我们还需要做特征处理。缺失值填充可以分为连续值的缺失值填充和离散值的缺失值填充。连续值的缺失值填充常见的有中值填充、众数填充、均值填充以及使用randomforest等机器学习算法进行填充。缺失值的填充也有众数填充,-1填充以及使用学习算法进行填充。

    1. 如何划分特征是连续值还是离散值。我们通过观察每个特征的分布情况,人为的划分,然后根据赛方反馈的结果进行调整。
    2. 用什么方法进行填充。在现阶段我们发现对于连续值,使用中值填充的方式优于均值填充。对于离散值,则是-1填充较好。
    将要用到的函数
    #添加每行数据的缺失值情况
    def lost_info(data):
        data_lost=data.isnull().sum().reset_index(name='count')
        data_lost.columns=['feature','counts']
        lost_count=data_lost.groupby('counts',as_index='False').count()
        print("there are ",lost_count.shape[0] ," different lost values in ",data.shape[1]," columns.")
        print("Add ",lost_count.shape[0]," cols behind the origin data...")
        col_len=lost_count.shape[0]
        lost_values=lost_count.index
        lost_info_data=pd.DataFrame()
        for i in np.arange(1,lost_count.shape[0]):
            lost_value=lost_values
            lost_cols_count=lost_count.loc[lost_value,"feature"]
            #same_index=np.array(data_lost[data_lost.counts==lost_value]['feature'])[0]
            same_index=data_lost[data_lost.counts==lost_value]['feature']
            post_fix=np.array(same_index)[0]
            data_lost_sample=data[same_index].isnull().sum(axis=1)/lost_cols_count
            lost_info_data["lost_"+str(lost_cols_count)+"_"+post_fix]=data_lost_sample
        data["sum"]=lost_info_data.sum(axis=1)
        data["isnull_count"]=data.isnull().sum(axis=1)
        #data=pd.concat([data,lost_info_data],axis=1)
        return data  
    
    #分别使用均值填充,插值填充和判定是否空值的方式填充连续型特征
    def mean_fillna(df,features):
        for feature in features:
            df[feature+'_mean']=df[feature].fillna(df[feature].mean())
        return df
    
    def interpolate_fillna(df,features):
        for feature in features:
            df[feature]=df[feature].interpolate()
        return df
            
    def isnan_fillna(df,features):
        for feature in features:
            df[feature+'_isnan']=df[feature]
            df.loc[(df[feature].isnull()),feature+'_isnan']=1
            df.loc[(df[feature].notnull()),feature+'_isnan']=0
        return df
    def median_fillna(df,features):
        for feature in features:
            df[feature+'_meadian']=df[feature].median()
        return df
    
    #连续特征的处理方式
    def continues_fillna(df,features):
        df=median_fillna(df,features)
        #df=interpolate_fillna(df,features)
        return df
    
    
    #使用-1填充离散型特征,并生成是否为空的特征列
    def category_fillna(df,category_cols):
        for category_col in category_cols:
            df[category_col].fillna(-1,inplace=True)
        return df
    
    #为train和test数据标记是否是离散值,当数据unquie唯一值个数超过threld的时候,则被认为是连续特征,否则是离散特征。
    #并且填充缺失值
    def set_cate_type_and_fillna(train_x,test,threld=80):
        #给离散列转换类型,得到离散值
        data_clo_unique_num=pd.DataFrame(train_x.apply(lambda x:len(x.unique())),columns=['unique'])
        for i in data_clo_unique_num.index:
            print(i," ",data_clo_unique_num.loc[i,'unique'])
        cate_cols=set(data_clo_unique_num[data_clo_unique_num['unique']<threld].index)
        cont_cols=set(train_x.columns)-cate_cols
        for i in cate_cols:
            train_x=train_x.astype('category')
            test=test.astype('category') 
        train_x=category_fillna(train_x,cate_cols)
        test=category_fillna(test,cate_cols)
        train_x=continues_fillna(train_x,cont_cols)
        test=continues_fillna(test,con_cols)
    
    print("the size of train set is "+str(train_x.shape[0])+", the size of test set is "+str(test.shape[0]))
    set_cate_type(train_x,test,10)
    
    # 在定义了上面的函数之后,下面将执行到模型训练之前的数据处理代码
    #重新加载一下数据,和分析阶段的数据名可能有区别
    train_x=pd.read_csv('input/atec_anti_fraud_train.csv')
    test = pd.read_csv('input/atec_anti_fraud_test_b.csv')
    
    train_x.sort_values(by='date',inplace=True)
    
    train_x.drop("id",axis=1,inplace=True)
    train_x.loc[train_x['label']==-1,'label']=1
    
    train_y=train_x["label"]
    train_x.drop("label",axis=1,inplace=True)
    
    test_id=test["id"].copy()
    test.drop("id",axis=1,inplace=True)
    
    train_size = len(train_x)
    all_data = train_x.append(test)
    all_data = preprocess_likeo(all_data,col_need)
    all_data = lost_info(all_data)
    
    train_x = all_data[:train_size]
    test = all_data[train_size:]
    
    print("the size of train set is "+str(train_x.shape[0])+", the size of test set is "+str(test.shape[0]))
    set_cate_type_and_fillna(train_x,test,80)

    特征工程结束!!!


    模型训练

    在完成了特征分析和处理之后,进入到了最复杂的过程,模型训练。实际上,上面的-1标签的处理、数据倾斜的处理、特征选择和缺失值填充也是模型训练的组成部分。在实际的工作中,先确定上面的部分,然后调节实验参数,得到较好的本地结果,上传系统得到评分,然后再修改特征部分,调节参数,...,一直循环这样的过程,不断分析本地结果和系统结果的得失。有时候会陷入局部最优,一直无法提升成绩。

    模型训练大致有四个步骤:

    1. 交叉验证集的生成
    2. 模型选择
    3. 参数优化
    4. 模型融合

    多模型融合可以使得结果获得0.02左右的提升。

    交叉验证集的生成

    按照时间排序之后,分成五份,依次取4份作为训练集一份作为测试集进行模型训练,如此交叉验证的结果优于随机选择的5折交叉验证。

    模型的选择

    Lightgbm是微软去年推出的很好用的机器学习竞赛算法。它的本质也是集成学习的算法,这个方法中可以通过参数选择使用随机森林、GBDT或者是Goss算法。相对于传统的sklearn中的集成算法,这个算法的优点在于:

    1. 传统集成算法对于CART树使用pre-sorted的算法。这是一个简单的解决方案,但是不易于优化。LightGBM 利用基于 histogram 的算法通过将连续特征(属性)值分段为 discrete bins 来加快训练的速度并减少内存的使用。
    2. 大部分决策树的学习算法通过level(depth)-wise策略生长树,而lightgbm使用Leaf-wise (Best-first) 的决策树生长策略。它将选取具有最大损失的叶节点来生长。 因此在叶子结点相同的时候,leaf-wise 算法可以比 level-wise算法减少更多的损失。
    3. 大多数机器学习工具都无法直接支持类别特征,一般需要把类别特征转化one-hotting特征,降低了空间和时间的效率。LightGBM优化了对类别特征的支持,可以直接输入类别特征,不需要额外操作。并在决策树算法上增加了类别特征的决策规则。

    在实践中,我们发现lightgbm算法可以达到xgboost相同的score,但是时间开销更少。同时,因为lightgbm可以同时训练GBDT模型和随机森林模型,因此简化了写代码的时间开销。通过实际训练对比,发现使用GBDT的score要略优于使用随机森林模型。

    LightGbm的训练参数有很多,主要的有叶子节点数num_leaves,叶子结点中含有的最少样本数min_child_samples,学习速率learning_rate以及训练循环次数num_boost_round。使用5折交叉验证,在最佳的情况下,score可以达到0.43。

    参数优化

    常用的参数优化方式有两种,第一种是使用基于网格搜索grid-search的方式;第二种是基于贝叶斯优化的参数搜索方式,已有的hyperopt包就是这样的最优参数搜索包。

    grid-search参数优化

    基于grid-search的参数优化的本质是给定需要调节的参数名称以及参数值,通过遍历这个参数空间,尝试每一种参数之间的搭配,选择score最高的参数值作为返回。sklearn.model_selection中提供了ParameterGrid方法,可以对给定的参数生成遍历之后的参数组合列表,将这样的参数传入算法中,依次训练即可得到参数空间中最优的参数值。

    hyperopt参数优化

    grid-search 是全空间扫描,所以比较慢。hyperopt是一种通过贝叶斯优化(贝叶斯优化简介)来调整参数的工具,对于像XGBoost这种参数比较多的算法,可以用它来获取比较好的参数值。

    hyperopt需要对每个参数指定搜索空间,而不是如grid-search中那样指定值,比如参数x在0-1区间内均匀取值,参数y在0-1之间对数取值。然后,可以指定参数优化的搜索算法,如随机搜索(对应是hyperopt.rand.suggest)和模拟退火(对应是hyperopt.anneal.suggest),TPE算法。

    模型融合

    模型融合就是将多个模型的结果重新整理归纳,得到一个更具有泛化能力和精度的最终模型。多模型融合算法可以比单一模型算法有极为明显的效果提升。

    将每个模型结果取均值得到最终的结果,这样的模型融合方式就是均值融合。这种简单的方式,实际效果很很好。通过融合多个成绩在0.40-0.43的lightgbm模型,最终的score可以达到0.4361。

    下面是模型训练部分的代码,封装了一些方法,在注释里面进行解释。

    #评价函数,可用于普通的sklearn包算法的结果分析,如GBDT
    def feval_spec(preds, train_data):
        from sklearn.metrics import roc_curve
        fpr, tpr, threshold = roc_curve(train_data, preds)
        tpr0001 = tpr[fpr <= 0.001].max()
        tpr001 = tpr[fpr <= 0.005].max()
        tpr005 = tpr[fpr <= 0.01].max()
        #tpr01 = tpr[fpr.values <= 0.01].max()
        tprcal = 0.4 * tpr0001 + 0.3 * tpr001 + 0.3 * tpr005
        return tprcal
    
    #用于lightgbm的评价函数
    def feval_spec_train(preds, train_data):
        from sklearn.metrics import roc_curve
        fpr, tpr, threshold = roc_curve(train_data.get_label(), preds)
        tpr0001 = tpr[fpr <= 0.001].max()
        tpr001 = tpr[fpr <= 0.005].max()
        tpr005 = tpr[fpr <= 0.01].max()
        #tpr01 = tpr[fpr.values <= 0.01].max()
        tprcal = 0.4 * tpr0001 + 0.3 * tpr001 + 0.3 * tpr005
        return 'spec_cal',tprcal,True
    
    #Kfolds将数据根据索引分为k份,可以用于生成第一层输出的时候,保证各折数据之间没有干扰
    # GroupSelect将Kfolds中的第i折数据索引作为预测集pre_set,其余的作为训练集train_set。
    # TrainSet针对训练数据的i折,得到训练数据和第二层的输入数据
    def Kfolds(x_index,k=5,seed=1):
        np.random.seed(seed)
        xL=np.array_split(np.random.choice(x_index,len(x_index),replace=False),k)
        return xL
    
    def GroupSelect(xL,i=0):
        xLc=xL.copy()
        pre_index=list(xLc.pop(i))
        train_index=sum([list(x) for x in xLc],[])
        return train_index,pre_index
    
    def TrainSet(x,y,xL,i=0):
        train_index,pre_index=GroupSelect(xL,i)
        train_x,pre_x=x.loc[train_index],x.loc[pre_index]
        train_y,pre_y=y.loc[train_index],y.loc[pre_index]
        return train_x,train_y,pre_x,pre_y
    
    #K折交叉验证,可用于sklearn传统机器学习算法
    def KflodsTrain(x,y,test,k=5,classifier=lgb.LGBMClassifier()):
        xL=Kfolds(np.array(x.index),k)
        #predict_proba=pd.DataFrame()
        test_predict_proba=pd.DataFrame()
        for i in range(k):
            print("begin the "+str(i)+" of "+str(k)+" kflods training...")
            train_x,train_y,pre_x,pre_y=TrainSet(x,y,xL,i)
            model=classifier.fit(train_x,train_y)
            predict_res=pd.Series(model.predict_proba(pre_x)[:, 1],index=pre_x.index)
            train_metric=feval_spec(model.predict_proba(train_x)[:,1],train_y)
            valid_metri=feval_spec(predict_res,pre_y)
            print("The ",i," times res: train set spe_val:",train_metric,", validation set sep_val: ",valid_metri)
            #predict_proba=pd.concat([predict_proba,predict_res])
            test_predict_proba=pd.Series(model.predict_proba(test)[:,1],index=test.index)
        #print("The output data of classifier: ",type(classifier), " is ready for stacking...")
        #print("the size  of data is ",predict_proba.shape[0])
        test_predict_proba_mean=test_predict_proba.mean(axis=1)
        return test_predict_proba_mean
    
    #K折交叉验证算法,用于lightgbm算法
    def KflodsTrain_light(x,y,test,k=5,lgb_params=None):
        if lgb_params==None:
            lgb_params = {
                'boosting_type': 'gbdt', 
                'objective': 'binary', 
                'nthread': -1, 
                'metric': 'auc',
                'num_leaves': 7,  # -1 means no limit
                'min_child_samples': 1000,  # Minimum number of data need in a child(min_data_in_leaf)  
            }
        xL=Kfolds(np.array(x.index),k)
        #predict_proba=pd.DataFrame()
        test_predict_proba=pd.DataFrame()
        for i in range(k):
            print("begin the "+str(i)+" of "+str(k)+" kflods training...")
            train_x,train_y,pre_x,pre_y=TrainSet(x,y,xL,i)
            xgtrain = lgb.Dataset(train_x,train_y)
            xgvalid = lgb.Dataset(pre_x,pre_y)
            evals_results={}
            bst1 = lgb.train(lgb_params,xgtrain,valid_sets=[xgtrain,xgvalid],valid_names=['train','valid'],evals_result=evals_results,
                        num_boost_round=200,early_stopping_rounds=30, verbose_eval=False,feval=feval_spec_train)        
            print('The ',i,' times running....')
            print('Best ite and score ',bst1.best_iteration,bst1.best_score)
            #predict_proba=pd.concat([predict_proba,predict_res])
            test_predict_proba=pd.Series(bst1.predict(test,num_iteration=bst1.best_iteration),index=test.index)
        #print("The output data of classifier: ",type(classifier), " is ready for stacking...")
        #print("the size  of data is ",predict_proba.shape[0])
        test_predict_proba_mean=test_predict_proba.mean(axis=1)
        return test_predict_proba_mean
    
    
    
    #设置lightgbm参数之后,调用上面的方法即可
    total_res=pd.DataFrame()
    total_res['id']=test_id
    lgb_params = {
                'boosting_type': 'gbdt', 
                'objective': 'binary', 
                'nthread': -1, 
                'metric': 'auc',
                'bagging_fraction':0.8,
                'feature_fraction':0.8,
                'num_leaves': 250,  # -1 means no limit
                'min_child_samples': 100,  # Minimum number of data need in a child(min_data_in_leaf)  
            }
    total_res["score"]=KflodsTrain_light(train_x,train_y,test,10,lgb_params)
    total_res.to_csv("submission_b_22.csv",index=False)

     

    参考:

    ATEC蚂蚁开发者大赛-支付风险识别-Rank7

    数据挖掘之支付风险异常识别

    ATEC学习赛想拿奖,这些你必须看&mdash;&mdash; ATEC相关问题汇总(3月获奖榜单颁布,持续更新)

    展开全文
  • 1、首先选出只带标签的数据(有风险和无风险的),进行分析,建立一个 recall rate 风险交易召回率较高的二分类模型。 2、接着在无标签的数据上应用此模型,打上标签,并与之前有标签的数据进行合并,形成最终完整...

            

    这一节开始建立模型,在建模之前,我们先梳理一下思路:

     

    思路:

     

    1、首先选出只带标签的数据(有风险和无风险的),进行分析,建立一个 recall rate 风险交易召回率较高的二分类模型。

    2、接着在无标签的数据上应用此模型,打上标签,并与之前有标签的数据进行合并,形成最终完整训练样本。

    3、将新的训练样本送入模型,得到最终模型。

    4、应用测试数据,得到结果。

     

    模型建立流程:

     

            因为id无重复,说明id可能是交易id,而不是账户id,可以不送入模型训练;同时交易时间也可以不送入训练,故利用选择属性算子将其两者过滤。之后将label列的角色设置为标签label,即告诉模型是否有风险的列为你要关心的结果。接着因为随机森林要求输入模型的数据是非空数值类型,故在之前的数据类型转换基础上还要做替换缺失值操作。

     

            在仅利用有标签数据进行预测,随机森林参数maxCategories=50,treeMaxDepth=7,treeNum=30时,结果如下,可以看到效果不逑行。

     

            可见当随机森林中树的深度比较小时,效果很差,原因主要是数据中特征太多(接近300个),决策树太浅会导致决策策略过于粗糙,故我们需要提高每颗决策树的深度。

    maxCategories=35,treeMaxDepth=6,treeNum=20:

     

    maxCategories=35,treeMaxDepth=14,treeNum=23

     

    maxCategories=35,treeMaxDepth=30,treeNum=23:

     

            可见单个决策树越深,效果越好,为了保证训练的速度,现在保持树深为15,增大随机森林中树的个数,发现效果也有变好

    maxCategories=32,treeMaxDepth=15,seed=7,treeNum=45:

     

    maxCategories=32,treeMaxDepth=30,seed=7,treeNum=100:

     

     

        但树的个树一旦超过100,再增加树的个数模型效果改善就不大了:

     

    故最终参数调整如下:

    maxCategories=32,treeMaxDepth=15,seed=7,treeNum=150:

     

            可见,只用带标签的数据,利用随机森林训练出的模型风险数据召回率并不是很高(接近0.5),因为有些无标签数据中也包含黑样本特征的重要信息。

            故接下来用以上训练出的模型对无样本数据打标签。由于篇幅原因,在下一篇博客中介绍。

     

     

     

     

     

    展开全文
  • 当前,金融业正处于以科技赋能,实现大发展、大变革关键时期,金融科技蓬勃发展,与此同时,金融科技企业生产运行过程中产生客户个人属性、资金交易、合同等敏感信息数据也逐步以不同形式转化为资产传输于信息...

    引言

     

     

    当前,金融业正处于以科技赋能,实现大发展、大变革的关键时期,金融科技蓬勃发展,与此同时,金融科技企业生产运行过程中产生的客户个人属性、资金交易、合同等敏感信息数据也逐步以不同形式转化为资产传输于信息网络之间、存储在信息系统之中,极度考验金融数据安全保护能力。

     

    背景分析

     

     

    44%的金融风险来源于数据泄露

     

    根据中国信息通信研究院、普华永道、平安金融安全研究院联合发布的《2018-2019年度金融科技安全分析报告》显示:针对客户资料及企业重要业务数据的安全事件成为发生频率最高的安全事件类别,合计高达44%的比例(造成“客户资料泄露”约22%,以及“企业敏感信息泄露”约22%),成为持续影响金融科技企业最主要的网络安全风险。

     

    71%的金融科技企业关注“数据安全及隐私保护”

     

    71%的金融科技企业表示,“数据安全及隐私保护”是企业目前及未来最需要加强的网络安全领域,这一项网络安全工作的受关注度及重要性远远超过其它网络安全工作领域。由于监管合规关注度增强、个人信息主体对个人信息保护意识度及要求的提升,金融科技企业需要加大数据安全及隐私保护领域的投入,亦需要主动寻求技术手段和专业的安全厂商进行风险规避。

    市场需求

    刚性与增值需求并举,金融业数据安全治理迫切性增强。

     

    刚性需求:

     

    1.数据库运维环境中敏感数据泄露的风险管控需求。

     

    2.对办公网、互联网环境敏感数据违规存储的排查需求。

     

    3.敏感数据分布不清晰、管控权限分配不合理等产生的分类分级需求。

     

    4.数据外发风险管控以及OA文件流转敏感数据监视与保护需求。

     

    增值需求:

     

    1.敏感数据共享业务数据保护需求、代码泄露管控需求。

     

    2.数据威胁集中分析与呈现需求。

     

    • 决策部门:整体把握全网数据安全风险态势,实现数据价值最大化,辅助业务决策,商业变现。

       

    • 业务及技术部门:由被动转向主动管理,需要加强事件预警和响应机制,完善风险处置手段。

    解决方案

     

     

    基于金融行业业务数据特性,开展针对金融业务数据的合规安全风险识别,同时面向不同的业务数据使用、流转场景开展针对性的安全防护解决方案设计。

     

     

    1.满足风控、安全及相关部门对全行数据风险合规排查需求。

     

    2.解决业务、办公等工作终端违规存储、外设拷贝、网络外发导致的数据泄露问题。

     

    3.解决业务系统账号异常使用问题,对业务系统数据违规使用行为监控审计。

     

    4.结合外发审批流程,实现数据管控一体化要求。

     

    5.解决大批量数据导出分析而导致信息泄露问题(数据共享安全)。

     

     

    方案价值

     

    1.数据安全合规排查

     

    满足人民银行、公安、网信、银保监会等国家主管部门对重要数据及公民客户金融信息(个人及机构客户信息及其衍生信息)监管要求,摸清数据底数,排查OA、邮件、网站、文件系统等服务端、各终端数据安全现状,排除数据泄露风险。

     

    2.数据安全针对性保护

     

    ①异常访问实时预警:

    监控及发现用户对业务系统各类涉敏数据的异常访问行为,提供实时预警,从源头控制风险。

     

    ②实现终端数据保护:

    对涉敏数据的终端存储、使用等行为全面监控与保护,防止数据违规外发(外设、IM及邮件等)。

     

    ③数据保护覆盖全面:

    对变型、嵌套、加密以及各类格式涉敏数据实现全面保护覆盖,确保数据安全保护无死角。

     

    ④数据外发严格审批:

    确因工作需要的数据外发、拷贝应通过严格审批后外发,但需保证安全性同时,降低审批工作量,并记录审核日志。

     

    ⑤数据风险全局掌控:

    动态、实时掌握全行涉敏数据分布、流动状况,全面掌控全行数据风险态势,实时发现及跟踪安全事件,实现数据安全可视化。

     

    结语

     

    数据安全将持续成为金融业的工作重点,世平信息作为专业的数据安全厂商,会以数据安全合规为出发点,在产品研发上力争上游,辅助金融行业企业把金融数据规划好、管理好、保护好、应用好,深挖数据价值,释放数据潜能,在金融业务应用与金融数据安全保持平衡的情况下推动金融行业实现高质量发展。

    展开全文
  • 上一篇博客讲了利用随机森林模型,在有标签的交易数据基础上建立模型,并简要讲了随机森林一些参数调优,这篇将会对无标签数据进行处理,并与原训练数据合并送入随机森林模型学习,得到最终模型。并会将测试数据接...
  • 搞清楚什么时候开始或停止交易策略,调整风险和资金管理技巧,甚至设置进入和退出条件参数都取决于市场“制度”或当前情况。 能够识别不同市场制度并相应地改变您策略可能意味着市场成功和失败之间差异。...
  • 了解不同市场状况如何影响您策略表现可能...搞清楚什么时候开始或停止交易策略,调整风险和资金管理技巧,甚至设置进入和退出条件参数都取决于市场“制度”或当前情况。 能够识别不同市场制度并相应...
  • 了解不同市场状况如何影响您...搞清楚什么时候开始或停止交易策略,调整风险和资金管理技巧,甚至设置进入和退出条件参数都取决于市场“制度”或当前情况。 能够识别不同市场制度并相应地改变您策...
  • 身份证识别-HMS

    2020-11-07 15:12:50
    其中华为的身份证识别服务提供对中国大陆第二代居民身份证的识别,从带有身份证信息的图像或视频流中,识别出带格式的文本信息,简单高效而且免费。该服务可以对身份证信息做结构化识别和录入,在保险、金融、电商等...
  • “了解不同股市状况,改变交易策略,对股市收益有很大影响。 弄清楚何时开始或何时止损,调整风险和资金管理技巧,都取决于股市当前状况。 ▼ 有些策略在波澜不惊股市中表现良好,而有些策略可能适合强劲...
  • 搞清楚什么时候开始或停止交易策略,调整风险和资金管理技巧,甚至设置进入和退出条件参数都取决于市场“制度”或当前情况。能够识别不同市场制度并相应地改变您策略可能意味着市场成功和失败之间差异。在...
  • 通证设计中一个重要因素,是消除或尽量减少人为因素影响,这样就不会给人作恶机会。...这样,不会由于一开始就能发出所有币,而且能够上市交易融很多钱,让人没有了干活动力。也不会存在者跑路的风险,...
  • 物流行业,实现一种全新速度:用OCR技术,自动精准识别录入各种运输文件,优化操作流程,实现快速交易 技术环节: 企业三证识别自动识别三证信息,自动查询企业工商信息,数据清洗,对存量、新增企业做信息验证,...
  • 识别、评估以及开发新供应源所带来额外成本 交易成本升高 距离所造成运输风险和延误 汇率风险 支付风险 与成本相关各种关税和非关税贸易壁垒 质量风险 由于距离遥远或报告机制不同,难以获得经过验证...
  • 引言: 邢不行系列帖子“量化小...【必读文章】EOS期现套利,一周时间,15%无风险收益 10年400倍策略分享(附视频逐行代码讲解) 个人微信:xingbx007,有问题欢迎交流。 警惕!避免数字货币交易所排名陷阱...
  • 由Jeff Schumacher创立公司 ...NAX整合软件和方法,为机构交易识别、构建、推出和衡量由资产支持产品、风险投资和证券化资产。NAX迄今已从北美、欧洲和亚洲12家机构投资者、家族理财室投资者..
  • “了解不同股市状况,改变交易策略,对股市收益有很大影响。 弄清楚何时开始或何时止损,调整风险和资金管理技巧,都取决于股市当前状况。
  • 了解不同市场状况如何影响您策略...搞清楚什么时候开始或停止交易策略,调整风险和资金管理技巧,甚至设置进入和退出条件参数都取决于市场“制度”或当前情况。 能够识别不同市场制度并相应地改变您...
  • 金融交易的风险识别交易利润平衡,一直是金融行业关键,也是衡量金融机构盈利能力标准尺度。在金融业务中,厘清金融机构与企业的交易关联度指标,确认风险集中度和风险暴露度,对守住底线、防...
  • 刷脸支付说白了就是用自己脸(身份证明)来跟金融做一个消费交易,大家对于信息这个事情是非常敏感,因此就会存在一个安全风险问题,还有就是对商家泄露信息太多,造成消费者担心等情况,也是时有发生。...
  • 京东金融登录行为识别赛题总结

    千次阅读 2018-04-16 22:00:58
    采用的是将每个用户的交易记录与距离该交易记录时间最短的一次成功登录记录进行关联2、针对登录时间戳,登录时长与交易时长,发现在午夜发生风险的可能比较大,取时间戳的小时数作为一个特征。3、取用户发生交易的...
  • 使用业界先进风控引擎结合“规则+AI”模型,对风险设备使用、模拟行为、暴力重放等攻击进行综合实时风控判决,解决企业账号、活动、交易等关键业务环节存在欺诈威胁,降低企业经济损失。 用户体验好...
  • 据360金融最近公布2020年一季度业绩报告披露内容,360金融在系统性能领域自主研发技术,将反欺诈等风控决策实时应用到每一个环节,实时风险识别前移,日均完成决策数据计算396亿次,客户最快8秒获得授信额度,...
  • 健全资本市场制度建设 防范市场风险 16日早间,证监会召开2019年全国...加强对各类股市杠杆融资的风险监测、识别、分析和预警。严格程序化交易管理。针对我国程序化交易中存在突出问题,细化证券公司、期货公司为?..
  • 风险承受测试非常重要 虽然炒汇投资者队伍日渐成熟,但需要指出是,在银行发展外汇保证金交易客户时,却并不能有效地识别和选择恰当客户,未能充分评估客户的风险承受能力和该产品客户适合度,且盲目降低...
  • 团队介绍蚂蚁金服风险与决策中心整体负责其国内外业务场景的交易和资金风险防控,包括盗用、欺诈、营销作弊、垃圾注册识别和决策等。团队以大数据积淀挖掘和前沿机器学习研发应用为核...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 150
精华内容 60
关键字:

交易风险的识别