Home Credit - Credit Risk Model Stability

news2024/11/18 3:50:08

本篇是对Kaggle上Home Credit - Credit Risk Model Stability竞赛中的开源代码VotingClassifier Home Credit的解读。原链接在VotingClassifier Home Credit (kaggle.com)。

%%writefile script.py
import sys
from pathlib import Path
import subprocess
import os
import gc
from glob import glob

import numpy as np
import pandas as pd
import polars as pl
from datetime import datetime
import seaborn as sns
import matplotlib.pyplot as plt
import joblib
import warnings
warnings.filterwarnings('ignore')

ROOT = '/kaggle/input/home-credit-credit-risk-model-stability'

from sklearn.model_selection import TimeSeriesSplit, GroupKFold, StratifiedGroupKFold
from sklearn.base import BaseEstimator, RegressorMixin
from sklearn.metrics import roc_auc_score
import lightgbm as lgb

class Pipeline:

    def set_table_dtypes(df):
        for col in df.columns:
            if col in ["case_id", "WEEK_NUM", "num_group1", "num_group2"]:
                df = df.with_columns(pl.col(col).cast(pl.Int64))
            elif col in ["date_decision"]:
                df = df.with_columns(pl.col(col).cast(pl.Date))
            elif col[-1] in ("P", "A"):
                df = df.with_columns(pl.col(col).cast(pl.Float64))
            elif col[-1] in ("M",):
                df = df.with_columns(pl.col(col).cast(pl.String))
            elif col[-1] in ("D",):
                df = df.with_columns(pl.col(col).cast(pl.Date))
        return df

    def handle_dates(df):
        for col in df.columns:
            if col[-1] in ("D",):
                df = df.with_columns(pl.col(col) - pl.col("date_decision"))  #!!?
                df = df.with_columns(pl.col(col).dt.total_days()) # t - t-1
        df = df.drop("date_decision", "MONTH")
        return df

    def filter_cols(df):
        
        for col in df.columns:
            if (col not in ["target", "case_id", "WEEK_NUM"]) & (df[col].dtype == pl.String):
                freq = df[col].n_unique()
                if (freq == 1) | (freq > 200):
                    df = df.drop(col)
        
        return df


class Aggregator:
    #Please add or subtract features yourself, be aware that too many features will take up too much space.
    def num_expr(df):
        cols = [col for col in df.columns if col[-1] in ("P", "A")]
        expr_max = [pl.max(col).alias(f"max_{col}") for col in cols]
        return expr_max
    
    def date_expr(df):
        cols = [col for col in df.columns if col[-1] in ("D")]
        expr_max = [pl.max(col).alias(f"max_{col}") for col in cols]
        return  expr_max
    
    def str_expr(df):
        cols = [col for col in df.columns if col[-1] in ("M",)]
        expr_max = [pl.max(col).alias(f"max_{col}") for col in cols]
        return  expr_max
    
    def other_expr(df):
        cols = [col for col in df.columns if col[-1] in ("T", "L")]
        expr_max = [pl.max(col).alias(f"max_{col}") for col in cols]
        return  expr_max 
    
    def count_expr(df):
        cols = [col for col in df.columns if "num_group" in col]
        expr_max = [pl.max(col).alias(f"max_{col}") for col in cols] 
        return  expr_max
    
    def get_exprs(df):
        exprs = Aggregator.num_expr(df) + \
                Aggregator.date_expr(df) + \
                Aggregator.str_expr(df) + \
                Aggregator.other_expr(df) + \
                Aggregator.count_expr(df)

        return exprs

def read_file(path, depth=None):
    df = pl.read_parquet(path)
    df = df.pipe(Pipeline.set_table_dtypes)
    if depth in [1,2]:
        df = df.group_by("case_id").agg(Aggregator.get_exprs(df)) 
    return df

def read_files(regex_path, depth=None):
    chunks = []
    
    for path in glob(str(regex_path)):
        df = pl.read_parquet(path)
        df = df.pipe(Pipeline.set_table_dtypes)
        if depth in [1, 2]:
            df = df.group_by("case_id").agg(Aggregator.get_exprs(df))
        chunks.append(df)
    
    df = pl.concat(chunks, how="vertical_relaxed")
    df = df.unique(subset=["case_id"])
    return df

def feature_eng(df_base, depth_0, depth_1, depth_2):
    df_base = (
        df_base
        .with_columns(
            month_decision = pl.col("date_decision").dt.month(),
            weekday_decision = pl.col("date_decision").dt.weekday(),
        )
    )
    for i, df in enumerate(depth_0 + depth_1 + depth_2):
        df_base = df_base.join(df, how="left", on="case_id", suffix=f"_{i}")
    df_base = df_base.pipe(Pipeline.handle_dates)
    return df_base

def to_pandas(df_data, cat_cols=None):
    df_data = df_data.to_pandas()
    if cat_cols is None:
        cat_cols = list(df_data.select_dtypes("object").columns)
    df_data[cat_cols] = df_data[cat_cols].astype("category")
    return df_data, cat_cols

def reduce_mem_usage(df):
    """ iterate through all the columns of a dataframe and modify the data type
        to reduce memory usage.        
    """
    start_mem = df.memory_usage().sum() / 1024**2
    
    for col in df.columns:
        col_type = df[col].dtype
        if str(col_type)=="category":
            continue
        
        if col_type != object:
            c_min = df[col].min()
            c_max = df[col].max()
            if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)  
            else:
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)
        else:
            continue
    end_mem = df.memory_usage().sum() / 1024**2    
    return df

ROOT            = Path("/kaggle/input/home-credit-credit-risk-model-stability")

TRAIN_DIR       = ROOT / "parquet_files" / "train"
TEST_DIR        = ROOT / "parquet_files" / "test"

data_store = {
    "df_base": read_file(TRAIN_DIR / "train_base.parquet"),
    "depth_0": [
        read_file(TRAIN_DIR / "train_static_cb_0.parquet"),
        read_files(TRAIN_DIR / "train_static_0_*.parquet"),
    ],
    "depth_1": [
        read_files(TRAIN_DIR / "train_applprev_1_*.parquet", 1),
        read_file(TRAIN_DIR / "train_tax_registry_a_1.parquet", 1),
        read_file(TRAIN_DIR / "train_tax_registry_b_1.parquet", 1),
        read_file(TRAIN_DIR / "train_tax_registry_c_1.parquet", 1),
        read_files(TRAIN_DIR / "train_credit_bureau_a_1_*.parquet", 1),
        read_file(TRAIN_DIR / "train_credit_bureau_b_1.parquet", 1),
        read_file(TRAIN_DIR / "train_other_1.parquet", 1),
        read_file(TRAIN_DIR / "train_person_1.parquet", 1),
        read_file(TRAIN_DIR / "train_deposit_1.parquet", 1),
        read_file(TRAIN_DIR / "train_debitcard_1.parquet", 1),
    ],
    "depth_2": [
        read_file(TRAIN_DIR / "train_credit_bureau_b_2.parquet", 2),
    ]
}

df_train = feature_eng(**data_store)
del data_store
gc.collect()
df_train = df_train.pipe(Pipeline.filter_cols)
df_train, cat_cols = to_pandas(df_train)
df_train = reduce_mem_usage(df_train)
nums=df_train.select_dtypes(exclude='category').columns
from itertools import combinations, permutations
nans_df = df_train[nums].isna()
nans_groups={}
for col in nums:
    cur_group = nans_df[col].sum()
    try:
        nans_groups[cur_group].append(col)
    except:
        nans_groups[cur_group]=[col]
del nans_df; x=gc.collect()

def reduce_group(grps):
    use = []
    for g in grps:
        mx = 0; vx = g[0]
        for gg in g:
            n = df_train[gg].nunique()
            if n>mx:
                mx = n
                vx = gg
        use.append(vx)
    return use

def group_columns_by_correlation(matrix, threshold=0.8):
    correlation_matrix = matrix.corr()
    groups = []
    remaining_cols = list(matrix.columns)
    while remaining_cols:
        col = remaining_cols.pop(0)
        group = [col]
        correlated_cols = [col]
        for c in remaining_cols:
            if correlation_matrix.loc[col, c] >= threshold:
                group.append(c)
                correlated_cols.append(c)
        groups.append(group)
        remaining_cols = [c for c in remaining_cols if c not in correlated_cols]
    
    return groups

uses=[]
for k,v in nans_groups.items():
    if len(v)>1:
            Vs = nans_groups[k]
            grps= group_columns_by_correlation(df_train[Vs], threshold=0.8)
            use=reduce_group(grps)
            uses=uses+use
    else:
        uses=uses+v
df_train=df_train[uses]

data_store = {
    "df_base": read_file(TEST_DIR / "test_base.parquet"),
    "depth_0": [
        read_file(TEST_DIR / "test_static_cb_0.parquet"),
        read_files(TEST_DIR / "test_static_0_*.parquet"),
    ],
    "depth_1": [
        read_files(TEST_DIR / "test_applprev_1_*.parquet", 1),
        read_file(TEST_DIR / "test_tax_registry_a_1.parquet", 1),
        read_file(TEST_DIR / "test_tax_registry_b_1.parquet", 1),
        read_file(TEST_DIR / "test_tax_registry_c_1.parquet", 1),
        read_files(TEST_DIR / "test_credit_bureau_a_1_*.parquet", 1),
        read_file(TEST_DIR / "test_credit_bureau_b_1.parquet", 1),
        read_file(TEST_DIR / "test_other_1.parquet", 1),
        read_file(TEST_DIR / "test_person_1.parquet", 1),
        read_file(TEST_DIR / "test_deposit_1.parquet", 1),
        read_file(TEST_DIR / "test_debitcard_1.parquet", 1),
    ],
    "depth_2": [
        read_file(TEST_DIR / "test_credit_bureau_b_2.parquet", 2),
    ]
}

df_test = feature_eng(**data_store)
del data_store
gc.collect()
df_test = df_test.select([col for col in df_train.columns if col != "target"])
df_test, cat_cols = to_pandas(df_test)
df_test = reduce_mem_usage(df_test)
gc.collect()

df_train['target']=0
df_test['target']=1

df_train=pd.concat([df_train,df_test])
df_train=reduce_mem_usage(df_train)

y = df_train["target"]
df_train= df_train.drop(columns=["target", "case_id", "WEEK_NUM"])

joblib.dump((df_train,y,df_test),'data.pkl')

导入必要的库:代码开始部分导入了多个Python库,包括用于数据处理的NumPy、Pandas、Polars,以及用于可视化的Seaborn、Matplotlib等。

设置警告过滤器:使用warnings.filterwarnings('ignore')来忽略警告信息,这在处理大型数据集时很常见。

 定义数据路径:设置ROOT变量,指向包含输入数据的目录。

定义Pipeline类:这个类包含几个静态方法,用于设置数据类型、处理日期列和过滤列。

定义Aggregator类:这个类包含多个静态方法,用于聚合数据,如计算最大值等。

定义数据读取函数read_fileread_files函数用于读取Parquet格式的文件,并将它们转换为Polars DataFrame。

特征工程feature_eng函数用于添加新特征,如决策月份和星期几等。

转换为Pandas DataFrameto_pandas函数用于将Polars DataFrame转换为Pandas DataFrame,并优化内存使用。

内存优化reduce_mem_usage函数用于减少DataFrame的内存占用,通过将数据类型转换为更小的类型。

读取和处理训练数据:代码读取训练数据文件,应用特征工程,并进行内存优化。代码通过分析缺失值的模式,决定哪些列是有用的,并据此过滤列。

基于相关性分组列group_columns_by_correlation函数用于基于列之间的相关性将它们分组。

读取、处理和保存测试数据:类似地,读取测试数据文件,应用特征工程,并进行内存优化。设置目标变量,并将训练数据和测试数据合并。最后,使用joblib.dump将处理后的训练数据、测试数据和目标变量保存到一个文件中。

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

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

相关文章

MySQL数据库的数据文件保存在哪?MySQL数据存在哪里

在安装好MySQL数据库使用一段时间后&#xff0c;会产生许多的数据库和数据。那这些数据库的数据文件存放在本地文件夹的什么位置呢 一、默认位置 一般来说MySQL数据库的数据文件都是存放在data文件夹之中&#xff0c;但是根据使用的存储引擎不同&#xff0c;产生的一些文件也…

【MATLAB源码-第213期】基于matlab的16QAM调制解调系统软硬判决对比仿真,输出误码率曲线对比图。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 一、16QAM调制原理 在16QAM&#xff08;16 Quadrature Amplitude Modulation&#xff09;调制中&#xff0c;一个符号表示4个比特的数据。这种调制方式结合了幅度调制和相位调制&#xff0c;能够在相同的频谱资源下传输更多…

智慧环保一体化平台哪家好?(已解答)

在环保行业数字化转型的大潮中&#xff0c;朗观视觉智慧环保一体化平台应运而生&#xff0c;成为推动环境治理现代化的重要手段。选择一个合适的智慧环保一体化平台对于提升环境管理效率、实现精细化监管具有重要意义。本文将从多个维度为您提供一份深度分析与选择指南&#xf…

python数据类型之元组、集合和字典

目录 0.三者主要作用 1.元组 元组特点 创建元组 元组解包 可变和不可变元素元组 2.集合 集合特点 创建集合 集合元素要求 集合方法 访问与修改 子集和超集 相等性判断 集合运算 不可变集合 3.字典 字典特点 字典创建和常见操作 字典内置方法 pprin模块 0.…

在线改图片怎么做更简单?快速修改图片尺寸的方法

现在一般拍摄出的图片尺寸都会比较大&#xff0c;想要上传大网上的一些平台展示时&#xff0c;经常会受到平台的限制&#xff0c;无法将图片正常上传到平台&#xff0c;那么如何将图片尺寸快速调整呢&#xff1f;比较简单的一种方式&#xff0c;可以通过在线改图片的工具来实现…

【数据结构】线性表习题 |顺序表 |链表 |栈和队列

&#x1f4d6;专栏文章&#xff1a;数据结构学习笔记 &#x1faaa;作者主页&#xff1a;格乐斯 前言 线性表习题 |顺序表 |链表 |栈和队列 顺序表和链表 1、 选B 1002(5-1)108* 第i个元素地址X&#xff0c;元素长度Len&#xff0c;第j个元素地址Y 公式&#xff1a;YXL…

Ardupilot开源代码之Rover上路 - 后续3

Ardupilot开源代码之Rover上路 - 后续3 1. 源由2. 深度配置2.1 编码器2.2 WS2812B LED灯带2.3 4GLTE超视距2.3.1 摄像头2.3.2 QGC OSD虚拟遥控2.3.3 QGC外接JoyStick遥控 2.4 伴机电脑供电 3. 实测效果4. 遗留&后续4.1 设置倒车按钮4.2 MP无法连接ESP82664.3 高精度编码器问…

水泥超低排平台哪家好?

随着环保政策的加强和绿色发展理念的深入人心&#xff0c;水泥行业的超低排放改造已成为行业发展的新趋势。选择一个合适的水泥超低排平台对于确保改造效果和实现企业的可持续发展至关重要。朗观视觉小编将从多个角度出发&#xff0c;为您提供一份综合评估与选择攻略&#xff0…

解释JAVA语言中关于方法的重载

在JAVA语言中&#xff0c;方法的重载指的是在同一个类中可以存在多个同名方法&#xff0c;但它们的参数列表不同。具体来说&#xff0c;重载的方法必须满足以下至少一条条件: 1. 参数个数不同。 2. 参数类型不同。 3. 参数顺序不同。 当调用一个重载方法时&#xff0c;编译器…

C——日常练习题(宏)

题目&#xff1a;写一个宏&#xff0c;可以将一个整数的二进制位的奇数位和偶数位交换。 1.如何交换奇偶位&#xff08;涉及基础知识位运算&#xff09; 举例&#xff1a;如1001 奇偶位互换之后是0110;&#xff08;先搞懂这个简单举例&#xff09; (1).将奇数位保留&#…

免费撸gpt-4o和各种大模型实用经验分享

项目 Github: https://github.com/MartialBE/one-api 先贴两张图&#xff1a; 说明 免费撸AI大模型,各位可以对照下面我给出的大模型记录表来填&#xff0c;key需要自己去拿&#xff0c;国内都需要手机号验证&#xff0c;如果你不介意。另外我在自己的博客放出免费API给大家…

各位数字和-第13届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第72讲。 各位数字和&#…

使用 MPI 做 3D 带状矩阵的转置

目的&#xff1a;整个大矩阵从 [Nx, Ny, Nz] 转到 [Nz, Nx, Ny] 每个进程的输入&#xff1a;大矩阵的 [Nx / total_proc_num, Ny, Nz] 的部分 每个进程的输出&#xff1a;大矩阵的 [Nz / total_proc_num, Nx, Ny] 的部分 一开始我大概有一个想法&#xff0c;假设两个进程的话…

24款奔驰GLE350升级原厂环视全景360影像 抬头显示HUD

奔驰GLE350原厂360全景影像的清晰度通常取决于车辆的具体型号和年份&#xff0c;以及安装的摄像头和显示屏质量。一般来说&#xff0c;原厂360全景影像系统会提供高清的影像&#xff0c;让驾驶者能够清晰地看到车辆周围的环境&#xff0c;帮助进行停车和转弯等操作抬头显示&…

go学习笔记-从圣经中抄录的接口值的思考

接口值 接口值&#xff0c;由两个部分组成&#xff0c;一个具体的类型和那个类型的值 下面4个语句中&#xff0c;变量w得到了3个不同的值。&#xff08; 开始和最后的值是相同的&#xff09; var w io.Writer w os.Stdout w new(bytes.Buffer) w nil var w io.Writer var…

胶原蛋白流失大揭秘:你的肌肤还年轻吗?

&#x1f343;当我们谈及胶原蛋白&#xff0c;不少女生眼中都会闪过一丝光芒。为什么呢&#xff1f;因为胶原蛋白是维持我们肌肤弹性、水润的秘密武器啊&#xff01;但是&#xff0c;随着岁月的流逝&#xff0c;你是否发现自己的肌肤开始变得松弛、无弹性&#xff0c;甚至出现了…

夸夸生肖属鼠的女性朋友

属鼠人一生的命运受到许多因素的影响&#xff0c;包括性格、家庭、教育、环境等。属鼠人性格外向、求知欲强、善解人意、善于结交各种各样的朋友&#xff0c;有丰富的人脉&#xff0c;容易得到他人的帮助和支持。 属鼠的人聪明、机智&#xff0c;他们善于观察&#xff0c;富有…

手把手教学,一站式安装ubuntu及配置服务器

应用背景&#xff1a;实验室刚弄了一台4090的电脑&#xff0c;老师让我们搞成服务器 一、制作ubuntu启动盘 1.1 清华开源影像站下载ubuntu桌面版本Index of /ubuntu-releases/22.04/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 1.2 下载UltralSO软件 https://…

案例分享|Alluxio在自动驾驶模型训练中的应用与部署

分享嘉宾&#xff1a; 杨林三-辉羲智能 关于辉羲智能&#xff1a; 辉羲智能致力打造创新车载智能计算平台&#xff0c;提供高阶智能驾驶芯片、易用开放工具链及全栈自动驾驶解决方案&#xff0c;运用独创性“数据闭环定义芯片”方法学&#xff0c;助力车企构建低成本、大规模和…

Java延时队列取消未支付的订单

一、定义延迟任务类 package com.activity.domain;import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit;/*** 延迟任务类*/ public class DelayedCancellation implements Delayed {private String order;private final long delayTime; // 延迟时间p…