882单表+极简特征思路+2021 CCF 个贷违约预测赛道

687 阅读2分钟

小知识,大挑战!本文正在参与“    程序员必备小知识    ”创作活动

本文同时参与 「掘力星计划」    ,赢取创作大礼包,挑战创作激励金

赛题名称

个贷违约预测

赛题背景

为进一步促进金融普惠的推广落地,金融机构需要服务许多新的客群。银行作为对风险控制要求很高的行业,因为缺乏对新客群的了解,对新的细分客群的风控处理往往成为金融普惠的重要阻碍。如何利用银行现有信贷行为数据来服务新场景、新客群成了一个很有价值的研究方向,迁移学习是其中一个重要手段。

赛题任务

本赛题要求利用已有的与目标客群稍有差异的另一批信贷数据,辅助目标业务风控模型的创建,两者数据集之间存在大量相同的字段和极少的共同用户。此处希望大家可以利用迁移学习捕捉不同业务中用户基本信息与违约行为之间的关联,帮助实现对新业务的用户违约预测。

数据

Baseline

因为靠着很多人的代码才跑通比赛,所以也想分享一下自己的特征工程思路。 在“第一次打比赛”公众号的基础上 ,删去了另一个表(因为线上线下差距过大),仅仅使用与测试数据分布一直的训练表构造特征。一些基础的处理一样,增加了类别特征的统计行特征以及后验概率特征。

线下roc_auc_score: 0.8817699803915139

线上:

后续思路供大家参考:

连续型数据分箱转成类别变量,然后做目标编码

类别变量交叉组合

统计类别变量下连续变量的统计特性(均值,方差,最大最小值等)

#!/usr/bin/env python
# coding: utf-8

# In[1]:



import warnings
warnings.simplefilter('ignore')

import os
import re
import gc

import numpy as np
import pandas as pd
pd.set_option('max_columns', None)
pd.set_option('max_rows', 200)
pd.set_option('float_format', lambda x: '%.3f' % x)

from tqdm.notebook import tqdm

from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import roc_auc_score

import lightgbm as lgb


# In[2]:



train_data = pd.read_csv('train_dataset/train_public.csv')


# In[3]:


test_data = pd.read_csv('test_public.csv')


# In[4]:


# print(train_data['isDefault'].shape)
# print(train_internet['isDefault'].shape)
# print(train_internet['isDefault'].value_counts(dropna=True))

# print(train_data['isDefault'].value_counts(dropna=True))


# In[5]:



data = pd.concat([train_data, test_data])

print(data.shape)
data.head()


# In[6]:


data['issue_date'] = pd.to_datetime(data['issue_date'])
data['issue_mon'] = data['issue_date'].dt.year * 100 + data['issue_date'].dt.month
data.drop(['issue_date'], axis=1, inplace=True)

data['class'] = data['class'].map({
    'A': 0, 'B': 1, 'C': 2, 'D': 3,
    'E': 4, 'F': 5, 'G': 6
})
lbe = LabelEncoder()
data['employer_type'] = lbe.fit_transform(data['employer_type'])


# In[7]:


lbe = LabelEncoder()
data['industry'] = lbe.fit_transform(data['industry'])


# In[8]:


data['work_year'] = data['work_year'].map({
    '< 1 year': 0, '1 year': 1, '2 years': 2, '3 years': 3, '4 years': 4,
    '5 years': 5, '6 years': 6, '7 years': 7, '8 years': 8, '9 years': 9,
    '10+ years': 10
})

data['work_year'].fillna(-1, inplace=True)


# In[9]:


def clean_mon(x):
    mons = {'jan':1, 'feb':2, 'mar':3, 'apr':4,  'may':5,  'jun':6,
            'jul':7, 'aug':8, 'sep':9, 'oct':10, 'nov':11, 'dec':12}
    year_group = re.search('(\d+)', x)
    if year_group:
        year = int(year_group.group(1))
        if year < 22:
            year += 2000
        elif 100 > year > 22:
            year += 1900
        else:
            year = 2022
    else:
        year = 2022

    month_group = re.search('([a-zA-Z]+)', x)
    if month_group:
        mon = month_group.group(1).lower()
        month = mons[mon]
    else:
        month = 0

    return year*100 + month

data['earlies_credit_mon'] = data['earlies_credit_mon'].apply(lambda x: clean_mon(x))


# In[10]:



后续会考虑一下如何用另一个表~

点个关注不迷路~

研究方向为图异常检测,图表示学习,期待大家的交流指点~

秋招已结束~ 大家带我打比赛吧~

                                                   2021、9、26