DataCastle企业风险算法赛实战(进阶难度)

news2024/11/28 15:49:12

        

目录

一、数据读取及分析

1、数据读取

2、数据分析

二、数据挖掘

三、模型构建及评估

四、划重点

推荐相关文章


        去年在DataCastle上参加了华录杯算法赛,初赛前10、进复赛就没打了。相比于之前文章 kaggle风控建模实战(文末附链接),本文数据处理较为复杂、特征挖掘内容较多,适合统计学/机器学习相关专业、或者有一定模型算法/数据挖掘经验的同学,经验较浅的也可以作为进阶项目实战提升。

一、数据读取及分析

1、数据读取

        使用DataCastle上华录杯算法赛-企业安全风险评估赛道数据集,其中训练集7117条、测试集1500条,测试集没有给score、需要参赛选手上传预测结果平台自动评估反馈;下图为训练集数据,其中score为风险评分、取值范围0-100,因此这个赛题可以转为二分类模型、也可以用回归模型 数据获取见文末

        数据集中详细信息包括如下9个表,需要以业户id为主键拼接、再做特征挖掘

(1)运政业户信息

(2)运政车辆信息

(3)车辆违法违规信息(道路交通安全,来源抄告)

(4)车辆违法违规信息(交通运输违法,来源抄告)

(5)动态监控报警信息(车辆,超速行驶)

(6)动态监控报警信息(车辆,疲劳驾驶)

(7)动态监控上线率(企业,%)

(8)运政车辆年审记录信息

(9)运政质量信誉考核记录

2、数据分析

(1)训练集score分布,大多集中在高分(分数越代表安全风险越低)

(2)将数据拼接后,查看存在过交通安全、运输违法车辆对应的业户id风险评分分布情况,可以发现这部分评分整体偏低,因此是否有过违法违规行为对风险评分影响较大

二、数据挖掘

1、运政业户信息和运政车辆信息表

        均有行业类别字段(分别为企业的行业类别、车辆的行业类别),数据拼接后可以衍生类别一致性特征;

2、交通安全违法/运输违法表

        按照观察时间往前切片[0,1,5,10,15,30,60,90,180,360,720](天),分别统计不同时间窗口下的交通安全违法次数、运输违法次数

3、动态监控报警信息(车辆,超速行驶)表/动态监控报警信息(车辆,疲劳驾驶)表

        分别统计不同时间窗口下的超速报警次数;对最高时速(Km/h), 持续点数, 持续时长(秒)三个字段分别统计不同时间窗口下的max, min, mean, median, std, count, sum

4、动态监控上线率(企业,%)表

        对近3个月、近6个月上线率分别统计mean, max, min, std;分别统计近3个月、近6个月上线率不满100%的次数

5、运政车辆年审记录信息表

        分别统计近0,1,3,5,7,10,20年的年审次数、年审合格次数

6、运政质量信誉考核记录表

        分别统计近30,90,360,720天的信誉考核次数,以及考核结果为优良(AAA), 合格(AA), 基本合格(A), 不合格(B)各类别的次数

数据挖掘代码,最终特征数量548个

def get_feature_across_window(df,key,col,func,day_diff,window_list,float_fea_list=[]):
    l=[]
    for window in window_list:
        df_window=df[df[day_diff]<=window]
        if func==cnt_feature:
            df_window_sta=df_window.pipe(func,key,col).add_suffix('_'+'window'+'_'+str(window))
        elif func==float_feature_stata:
            df_window_sta=df_window.pipe(func,key,col,float_fea_list).add_suffix('_'+'window'+'_'+str(window))
        l.append(df_window_sta)
    return pd.concat(l,axis=1)
​
def cnt_feature(df,key,col):
    result=df.groupby([key])[col].count().to_frame().rename(columns={col:'cnt'})
    return result
​
STATS_LIST = ['max', 'min', 'mean', 'median', 'std','count','sum']
def float_feature_stata(df,key,col,float_fea_list,STATS_LIST=STATS_LIST):
    l=[]
    for col in float_fea_list:
        df_col_sta=df.groupby(key)[col].agg(STATS_LIST)
        df_col_sta.columns=[col+'_'+sta for sta in STATS_LIST]
        l.append(df_col_sta)
​
    return pd.concat(l,axis=1)
​
​
window_list=[0,1,5,10,15,30,60,90,180,360,720]
def traffic_safety_data_pre(df,window_list):
    df_copy=df.copy()
    df_copy['行业类别']=df_copy['行业类别'].map({'包车客运':'道路旅客运输','危货运输':'道路危险货物运输'})
    df_copy['观察时间']='2022-06-30'
    df_copy['day_diff']=(pd.to_datetime(df_copy['观察时间'])-pd.to_datetime(df_copy['违规时间'])).dt.days
    
    key,col,func,day_diff,window_list='车牌号','行业类别',cnt_feature,'day_diff',window_list
    result=df_copy.pipe(get_feature_across_window,key,col,func,day_diff,window_list)
    return result
​
def speeding_data_pre(df,window_list):
    df_copy=df.rename(columns={'车牌号码':'车牌号'}).copy()
    df_copy['观察时间']='2022-06-30'
    df_copy['day_diff']=(pd.to_datetime(df_copy['观察时间'])-pd.to_datetime(df_copy['开始时间'])).dt.days
    
    key,col,func,day_diff,window_list='车牌号','报警类型',float_feature_stata,'day_diff',window_list
    float_fea_list=['最高时速(Km/h)', '持续点数', '持续时长(秒)']
    df_float=df_copy.pipe(get_feature_across_window,key,col,func,day_diff,window_list,float_fea_list)
    
    key,col,func,day_diff,window_list='车牌号','报警类型',cnt_feature,'day_diff',window_list
    df_cnt=df_copy.pipe(get_feature_across_window,key,col,func,day_diff,window_list)
    
    
    return pd.concat([df_float,df_cnt],axis=1)
    
def get_launch_df(df):
    df_copy=df.copy()
    three_month_col=[str(month)+'月上线率' for month in [4,5,6]]
    six_month_col=[str(month)+'月上线率' for month in [1,2,3,4,5,6]]
    stata_list=['mean','max','min','std']
    df_fea_3month=df_copy[three_month_col].agg(stata_list,axis=1).add_prefix('three_month_')
    df_fea_6month=df_copy[six_month_col].agg(stata_list,axis=1).add_prefix('six_month_')
    
    df_fea_3month_cnt=df_copy[df_copy[three_month_col]!=1].count(axis=1).to_frame().rename(columns={0:'not1_cnt'}).add_prefix('three_month_')
    df_fea_6month_cnt=df_copy[df_copy[six_month_col]!=1].count(axis=1).to_frame().rename(columns={0:'not1_cnt'}).add_prefix('six_month_')
    
    return pd.concat([
        df_copy,
        df_fea_3month,
        df_fea_6month,
        df_fea_3month_cnt,
        df_fea_6month_cnt
    ],axis=1)
​
def annual_review_df(df):
    df_copy=df.rename(columns={'车辆牌照号':'车牌号'}).copy()
    df_copy['观察时间']=2022
    df_copy['year_diff']=df_copy['观察时间']-df_copy['年审年度']
    
    key,col,func,day_diff,window_list='车牌号','审批结果',cnt_feature,'year_diff',[0,1,3,5,7,10,20]
    df_review_cnt=df_copy.pipe(get_feature_across_window,key,col,func,day_diff,window_list).add_prefix('review_')
    
    df_qualified_cnt=df_copy[df_copy['审批结果']=='年审合格'].pipe(get_feature_across_window,key,col,func,day_diff,window_list).add_prefix('qualified_')
    df_annual_review=pd.concat([df_review_cnt,df_qualified_cnt],axis=1)
​
    return df_annual_review
​
def reputation_assessment_df(df):
    df_copy=df.copy()
    df_copy['观察时间']='2022-06-30'
    df_copy['day_diff']=(pd.to_datetime(df_copy['观察时间'])-pd.to_datetime(df_copy['考核日期'])).dt.days
    
    key,col,func,day_diff,window_list='业户ID','质量信誉考核结果',cnt_feature,'day_diff',[30,90,360,720]
    df_reputation_all=df_copy.pipe(get_feature_across_window,key,col,func,day_diff,window_list).add_prefix('reputation_all_')
    
    l=[]
    for grade in ['优良(AAA)', '合格(AA)', '基本合格(A)', '不合格(B)']:
        key,col,func,day_diff,window_list='业户ID','质量信誉考核结果',cnt_feature,'day_diff',[30,90,360,720]
        df_reputation_grade=df_copy[df_copy['质量信誉考核结果']==grade].pipe(get_feature_across_window,key,col,func,day_diff,window_list).add_prefix('reputation_'+re.findall('\((.*?)\)',grade)[0]+'_')
        l.append(df_reputation_grade)
    df_reputation_assessment=pd.concat([df_reputation_all]+l,axis=1)
    return df_reputation_assessment
​
​
def get_all_df(df_list,df_train_label):
    
    df_all=df_list[1].rename(columns={'车辆牌照号':'车牌号'}).merge(df_train_label,left_on=['车牌号'],right_on=['car_id'],how='left').drop(['car_id'],axis=1)
    df_all['sample_label']=np.where(df_all.score.notnull(),'train','test')
    df_all=df_all.merge(df_list[0],on=['业户ID'],how='left')
    df_all.rename(columns={'行业类别_x':'车辆行业类别','行业类别_y':'企业行业类别'},inplace=True)
    df_all['类别一致性']=np.where(df_all['车辆行业类别']==df_all['企业行业类别'],1,0)
    
    df_traffic_safety=df_list[2].pipe(traffic_safety_data_pre,[30,90,180,360,720])
    df_illegal_trans=df_list[3].pipe(traffic_safety_data_pre,[30,90,180,360,720])
    df_speeding=df_list[4].pipe(speeding_data_pre,window_list)
    df_fatigue_driving=df_list[5].pipe(speeding_data_pre,window_list)
    df_launch=df_list[6].pipe(get_launch_df)
    df_annual_review=df_list[7].pipe(annual_review_df)
    df_reputation_assessment=df_list[8].pipe(reputation_assessment_df)
    
    df_license_concat=pd.concat([
        df_traffic_safety.add_prefix('traffic_safety_'),
        df_illegal_trans.add_prefix('illegal_trans_'),
        df_speeding.add_prefix('speeding_'),
        df_fatigue_driving.add_prefix('fatigue_driving_'),
        df_annual_review.add_prefix('annual_review_')
    ],axis=1)
    df_launch.columns=['launch_'+col if col not in ['企业名称'] else col for col in df_launch.columns]
    
    df_all=df_all.merge(df_license_concat.reset_index(),on=['车牌号'],how='left')
    df_all=df_all.merge(df_launch,on=['企业名称'],how='left')
    df_all=df_all.merge(df_reputation_assessment.reset_index(),on=['业户ID'],how='left')
​
    return df_all
​
df_all=get_all_df(df_list,df_train_label)
print(df_all.shape)
df_all.head()
                             
​
fea_list=['车牌颜色','车辆行业类别','企业行业类别','类别一致性']+list(df_all.loc[:,'traffic_safety_cnt_window_30':].columns)
len(fea_list)

三、模型构建及评估

        使用xgb构建回归模型,使用mse、mae、r2进行评估(其他回归模型、二分类模型的方式大家可以自行尝试)

from math import sqrt
from sklearn.metrics import mean_absolute_error,mean_squared_error,r2_score
​
def init_params_regression():
    params_xgb={
        'objective':'reg:squarederror',
        'eval_metric':'rmse',
#        'silent':0,
        'nthread':4,
        'n_estimators':500,
        'eta':0.02,
#        'num_leaves':10,
        'max_depth':3,
        'min_child_weight':50,
        'scale_pos_weight':1,
        'gamma':5,
        'reg_alpha':2,
        'reg_lambda':2,
        'subsample':0.8,
        'colsample_bytree':0.8,
        'seed':123
    }
    return params_xgb
​
def mse_value(y_value,df,model):
    y_pred=model.predict(df)
    mae=mean_absolute_error(y_value, y_pred)
    mse=mean_squared_error(y_value, y_pred)
    r2=r2_score(y_value, y_pred)
​
    return mae,mse,r2
    
def model_train_sklearn_regression(model_label,train,y_name,model_var,params=None,random_state=123):
    
    if params is None:
        params=init_params_regression()
    x_train,x_test, y_train, y_test =train_test_split(train[model_var],train[y_name],test_size=0.2, random_state=random_state)
​
    model=XGBRegressor(**params)
    
    model.fit(x_train,y_train,eval_set=[(x_train, y_train),(x_test, y_test)],verbose=False) # 调参时设verbose=False
    train_mae,train_mse,train_r2=mse_value(y_train,x_train,model)
    test_mae,test_mse,test_r2=mse_value(y_test,x_test,model)
    all_mae,all_mse,all_r2=mse_value(train[y_name],train[model_var],model)
    
    dic={
        'model_label':model_label,
        'train':y_train.count(),
        'test':y_test.count(),
        'all':train.shape[0],
        'train_mse':train_mse,'train_mae':train_mae,'train_r2':train_r2,
        'test_mse':test_mse,'test_mae':test_mae,'test_r2':test_r2,
        'all_mse':all_mse,'all_mae':all_mae,'all_r2':all_r2,
    }
    return dic,model
    
params=init_params_regression() 
params.update({'n_estimators':900,'eta':0.65})
​
model_result,model=model_train_sklearn_regression('label',df_all[df_all['sample_label']=='train'],'score',
                                       fea_list[3:],params=params)
model_result

四、划重点

        关注公众号 Python风控模型与数据分析,回复 企业风险算法实战 获取本篇数据及代码

推荐相关文章

租房价格分析及预测(xgb+catboost+rf)

kaggle风控建模实战(XGB+LGB+RF+LR)

NGBoost参数详解及实战

catboost参数详解及实战(强推)

风控算法赛lgb实战-拍拍贷魔镜杯

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1166433.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智慧财务的未来

信息化时代&#xff0c;财务管理不再局限于传统的手工操作&#xff0c;而是借助RPA技术实现了自动化、智能化的转型。智慧财务作为财务管理的一种新模式&#xff0c;将为企业提供更加高效、便捷的服务&#xff0c;使企业能够更好地适应市场需求的变化&#xff0c;在瞬息万变的市…

批量删除文件名中的某些文字

怎么批量删除文件名中的某些文字&#xff1f;在整理电脑文件的时候&#xff0c;我们经常需要处理大量文件的重命名工作。当你的文件名称包含不必要或重复的字符时&#xff0c;可以进行批量删除&#xff0c;以使文件名称更简洁、清晰&#xff0c;提高可读性和识别性。例如&#…

【蓝桥杯软件赛 零基础备赛20周】第2周——常考知识点+判题

文章目录 0. 第1周答疑1. 常考知识点2. 蓝桥杯怎么判题2.1 判题系统如何判题2.2 测试数据和得分的关系2.3 自己做测试数据 3. 备赛计划4. 本周刷题 0. 第1周答疑 问题1&#xff1a;蓝桥杯怎么报名&#xff0c;什么时候报名&#xff1f; 答&#xff1a;集体报名或个人报名。大…

【word技巧】ABCD选项如何对齐?

使用word文件制作试卷&#xff0c;如何将ABCD选项全部设置对齐&#xff1f;除了一直按空格或者Tab键以外&#xff0c;还有其他方法吗&#xff1f;今天分享如何将ABCD选项对齐。 首先&#xff0c;我们打开【替换和查找】&#xff0c;在查找内容输入空格&#xff0c;然后点击全部…

利用关键字批量整理文件:用关键字轻松移动多个文件到指定文件夹

在日常生活和工作中&#xff0c;我们经常需要处理大量的文件&#xff0c;随着时间的推移&#xff0c;电脑中的文件越来越多&#xff0c;而文件的命名可能并不规范&#xff0c;导致查找和整理变得非常困难。因此&#xff0c;我们需要一种高效的文件管理方法&#xff0c;以方便我…

一种用醋酸刻蚀氧化铜的新方法

引言 由于乙酸不会氧化铜表面&#xff0c;因此乙酸常用于去除氧化铜而不侵蚀铜膜。乙酸还具有低表面张力&#xff0c;易于从表面移除。因此&#xff0c;不需要去离子(DI)水冲洗来移除残留的乙酸&#xff0c;可以防止水冲洗导致的铜再氧化。 英思特研究了在低温下用乙酸去除氧…

SSE加速随笔

Intel Intrinsics Guide 搞懂SSE 寄存器与指令数据细节 SSE指令集推出时&#xff0c;Intel公司在Pentium III CPU中增加了8个128位的SSE指令专用寄存器&#xff0c;称作XMM0到XMM7。这些XMM寄存器用于4个单精度浮点数运算的SIMD执行&#xff0c;并可以与MMX整数运算或x87浮点运…

01、SpringBoot + MyBaits-Plus 集成微信支付 -->项目搭建

目录 SpringBoot MyBaits-Plus 集成微信支付 之 项目搭建1、创建boot项目2、引入Swagger作用&#xff1a;2-1、引入依赖2-2、写配置文件进行测试2-3、访问Swagger页面2-4、注解优化显示 3、定义统一结果作用&#xff1a;3-1、引入lombok依赖3-2、写个统一结果的类-->RR类的…

Windows、程序员必装的工具

一、Typora 啥也不说了直接上图 Markdown语法 Typora免费版 提取码&#xff1a;av01 二维码&#xff1a; 1&#xff09;页面展示 2&#xff09;主题 3&#xff09;偏好设置 4&#xff09;Markdown语法设置偏好 5&#xff09;编辑器 6&#xff09;系统 二、Snipaste Snipaste…

Java反射详解:入门+使用+原理+应用场景

反射非常强大和有用&#xff0c;现在市面上绝大部分框架(spring、mybatis、rocketmq等等)中都有反射的影子&#xff0c;反射机制在框架设计中占有举足轻重的作用。 所以&#xff0c;在你Java进阶的道路上&#xff0c;你需要掌握好反射。 怎么才能学好反射&#xff0c;我们需要…

STM32CubeIDE安装中文语言包

软件包地址&#xff1a;https://archive.eclipse.org/technology/babel/update-site/R0.16.1/2018-12/ 打开IDE&#xff1a;Help--->Install New Software--->Add Locations&#xff1a;输入软件包地址 等待搜索结束&#xff1a;选择中文语言包&#xff0c;单击next进行安…

QQ邮箱发送验证码源码/API+HTML源码/支持API接口、自定义地址和内容/简单易用

源码简介&#xff1a; 一款支持API接口、自定义QQ邮箱地址、自定义邮箱标题和内容的源码。 近来我正在开发一款新的软件&#xff0c;但在注册环节中遇到了一个问题&#xff1a;需要使用QQ邮箱验证码。因此&#xff0c;我积极寻找相关的API接口或开发文档&#xff0c;但遗憾的…

学习小结,学而时习之,坚持学习之,温顾学习之

学习python一个多月了&#xff0c;之前也有接触过&#xff0c;还花了不少钱报班&#xff0c;看了看入门的头两节课&#xff0c;就止步了。每一种编程语言的入门感觉都差不多&#xff0c;学到现在&#xff0c;我对python的基本数据类型还是没掌握好啊&#xff0c;每次列表字典怎…

面向萌新的数学建模入门指南

时间飞逝&#xff0c;我的大一建模生涯也告一段落。感谢建模路上帮助过我的学长和学姐们&#xff0c;滴水之恩当涌泉相报&#xff0c;写下这篇感想&#xff0c;希望可以给学弟学妹们一丝启发&#xff0c;也就完成我的想法了。拙劣的文笔&#xff0c;也不知道写些啥&#xff0c;…

二叉树采用二叉链表存储:编写计算整个二叉树高度的算法

二叉树采用二叉链表存储&#xff1a;编写计算整个二叉树高度的算法 (二叉树的高度也叫二叉树的深度) 代码思路&#xff1a; 首先你要明白什么是树的高度&#xff0c;简言之就是树有多少层&#xff0c;如下图&#xff1a; 下面这棵树的高度就是4 首先我们观察根节点&#xff0…

软件测试:压力测试详解

压力测试 压力测试是一种软件测试&#xff0c;用于验证软件应用程序的稳定性和可靠性。压力测试的目标是在极其沉重的负载条件下测量软件的健壮性和错误处理能力&#xff0c;并确保软件在危急情况下不会崩溃。它甚至可以测试超出正常工作点的测试&#xff0c;并评估软件在极端…

使用免费 FlaskAPI 部署 YOLOv8

目标检测和实例分割是计算机视觉中关键的任务&#xff0c;使计算机能够在图像和视频中识别和定位物体。YOLOv8是一种先进的、实时的目标检测系统&#xff0c;因其速度和准确性而备受欢迎。 Flask是一个轻量级的Python Web框架&#xff0c;简化了Web应用程序的开发。通过结合Fla…

手把手教你:UE 4.27插件项目的自动化打包(Windows、Android、iOS统统搞定)

Windows平台 下载/安装Epic Games launcher&#xff1b;然后安装 Unreal Engine v4.27.2 注意&#xff1a;launcher和具体版本的engine务必安装在相同的父目录下&#xff01;如下&#xff1a; 2. 安装Visual Studio 2019或2022。安装完成后执行菜单&#xff1a;帮助 | 检查更…

3D医学三维技术影像PACS系统源码

一、系统概述 3D医学影像PACS系统&#xff0c;它集影像存储服务器、影像诊断工作站及RIS报告系统于一身,主要有图像处理模块、影像数据管理模块、RIS报告模块、光盘存档模块、DICOM通讯模块、胶片打印输出等模块组成&#xff0c; 具有完善的影像数据库管理功能&#xff0c;强大…

分享77个工作总结PPT,总有一款适合您

分享77个工作总结PPT&#xff0c;总有一款适合您 PPT下载链接&#xff1a;https://pan.baidu.com/s/1qdoA_Ylbxkmp2Qkh9VDw8A?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 水彩插画风幼儿说课PPT模板 舞龙舞狮文化传承通…