├── AutomatedLoanRepayment.ipynb ├── README.md ├── output.svg ├── output_34_0.svg └── requirements.txt /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 基于Featuretools自动特征工程构建预测贷款偿还特征 3 | 4 | 5 | 特征工程是一个基于现有数据构建新特征(也称作预测变量或具有解释的变量)的过程. 传统上,使用领域知识手工一次构建一个来完成特征工程.在以前的笔记中,我们知道特征工程对于数据科学至关重要但人工方法很耗时,乏味,容易出错以及必须针对每个项目重做.自动化特征工程是在短时间内从一组关系表中自动构建成百上千新特征从而如同人工方法一样在这一关键过程中为数据科学家提供帮助.在本文,我们使用[Featuretools,一个Python开源库](https://www.featuretools.com/)将自动化特征工程应用于房贷信用贷违约风险数据集以进行自动构建特征. 6 | 7 | 9 | 这个课题是目前在Kaggle上进行的机器学习竞赛项目,意图是给定历史贷款和申请数据的情况下,预测申请人是否会拖欠贷款. 数据分布在7个不同的表中, 这成为自动化特征工程中一个目标:必须将所有数据整合到一个DataFrame数据框用作训练(一个用于测试), 旨在为预测问题捕获尽可能多的可用信息. 正如所见,Featuretools只需要几行代码有效地执行这些繁琐的过程,即基于这些表构建新特征.而且,此代码通用与任何数据科学问题. 10 | 11 | 12 | 在本文中,我们将实现一个自动特征工程方法来解决贷款偿还问题.而Featuretools提供了许多用于自定义的选项以提高准确性,我们将更专注于比较高级的实现.(后文,包括"Engine Life"和"Retail Spending"展示该库的一些额外功能). 13 | 14 | 15 | 本文方法将包括以下内容: 16 | 17 | 18 | * 读取关系数据表集合 19 | 20 | * 创建一个Featuretools的`实体集`且为它添加`实体` 21 | 22 | * 根据需要识别正确的变量类型 23 | 24 | * 识别数据索引 25 | 26 | * 为`实体`之间添加关联关系 27 | 28 | * 选择特征基元用于创建新特征 29 | 30 | * 基本基元集 31 | 32 | * 检查将要被创建的特征 33 | 34 | * 运行深度特征合成生成成千上万个新特征 35 | 36 | 37 | 38 | ## 课题中的数据集 39 | 40 | 41 | 目前在Kaggle上运行的[房屋贷款信用违约风险竞赛](https://www.kaggle.com/c/home-credit-default-risk)是一项监督分类任务,目的是预测申请人(或称之为客户)申请贷款将是否拖欠该贷款. 该数据包括客户的社会经济指标,历史贷款的特定财务信息,以及有关 Home Credit(赞助比赛的机构)和其他信贷机构历史贷款的综合数据. 此项竞赛的度量标准是受试者特征曲线(ROC AUC),并根据违约情况进行了预测。我们可以通过交叉验证训练数据(带有标签)或将测试预测提交给Kaggle以查看我们在公共排行榜上的位置(仅通过10%的测试计算得出)来评估提交的内容数据. 42 | 43 | 44 | [房屋贷款信用风险数据集](https://www.kaggle.com/c/home-credit-default-risk/data)是由7个表构成: 45 | 46 | 47 | * application_train/application_test:trainning/testing为每个客户的主要家庭授信数据, 主要包括客户社会经济指标和特定的贷款特征.每笔贷款都有唯一的行并由特征`SK_ID_CURR`作为唯一标识符.application_train数据带有`TARGET`列, 其中,0:标识贷款已被偿还, 1标识贷款未被偿还. 48 | 49 | 50 | * bureau: 历史信用数据, 有关客户历史从其他金融机构获得的信用数据(而非家庭信贷)的数据。每笔贷款历史信用在表中都有其自己的行,但是申请表中的一个客户可以具有多笔历史借贷数据。历史信用表由特征`SK_ID_BUREAU`作为唯一标识. 51 | 52 | 53 | * bureau_balance: 贷款账户月度余额,有关征信局的贷款账户月度余额数据.每行都有一个贷款账户信息,单个贷款账户可以有很多行. 这是征信局中回溯每笔贷款历史还款行为数据, 通过`SK_ID_BUREAU`标识每笔贷款(没有唯一索引). 54 | 55 | 56 | * previous_application:在申请表中的客户历史上在Home Credit申请贷款笔数,申请数据表中的每个客户可以拥有多笔历史贷款. 每笔历史贷款在这张表中都有且仅有一行,并由特征`SK_ID_PREV`作为唯一标识. 57 | 58 | 59 | * POS_CASH_BALANCE: 月度余额, 有关历史销售点的月度数据或来自历史贷款数据的现金贷款. 每行是销售点或现金贷款的一个月的数据, 并且一笔历史的贷款可以有多行.这是征信局中回溯每笔现金贷款或销售点历史还款行为数据, 通过`SK_ID_PREV`标识每笔贷款(没有唯一索引). 60 | 61 | 62 | * credit_card_balance: 信用卡贷款月度余额数据, 每一行记录一张信用卡一个月的余额, 且单张信用卡可以有很多行. 这些记录是回溯信用卡历史贷款每个月还款数据,并通过`SK_ID_PREV`标识每张卡(没有唯一索引). 63 | 64 | 65 | * installments_payment: 分期付款, 以前在Home Credit上的贷款付款历史记录. 每笔付款和每笔未支付的款项都有一行. 通过`SK_ID_PREV`关联历史贷款(在此表中不是唯一的). 66 | 67 | 68 | ```python 69 | # pandas and numpy for data manipulation 70 | import pandas as pd 71 | import numpy as np 72 | 73 | # featuretools for automated feature engineering 74 | import featuretools as ft 75 | ``` 76 | 77 | 78 | ### 读取数据 79 | 80 | 81 | 首先我们需要读取这7张表,并进行异常值处理(这在手工特征工程也一样). 82 | 83 | 84 | ```python 85 | # Read in the datasets and replace the anomalous values 86 | # 读取数据集并替换异常值 87 | app_train = pd.read_csv('input/application_train.csv').replace({365243: np.nan}) 88 | app_test = pd.read_csv('input/application_test.csv').replace({365243: np.nan}) 89 | bureau = pd.read_csv('input/bureau.csv').replace({365243: np.nan}) 90 | bureau_balance = pd.read_csv('input/bureau_balance.csv').replace({365243: np.nan}) 91 | cash = pd.read_csv('input/POS_CASH_balance.csv').replace({365243: np.nan}) 92 | credit = pd.read_csv('input/credit_card_balance.csv').replace({365243: np.nan}) 93 | previous = pd.read_csv('input/previous_application.csv').replace({365243: np.nan}) 94 | installments = pd.read_csv('input/installments_payments.csv').replace({365243: np.nan}) 95 | ``` 96 | 97 | 98 | 我们将traing和testing数据集合并以确保生成相同的特征, 特征矩阵被构建后,再把两个数据集拆分. 99 | 100 | 101 | ```python 102 | app_test['TARGET'] = np.nan 103 | 104 | # Join together training and testing 105 | app = app_train.append(app_test, ignore_index = True, sort = True) 106 | ``` 107 | 108 | 109 | 几个索引是错误的数据类型(浮点数),因此我们需要使它们全部相同(整数)以添加关系,且以 0 填充缺失值 110 | 111 | 112 | ```python 113 | for index in ['SK_ID_CURR', 'SK_ID_PREV', 'SK_ID_BUREAU']: 114 | for dataset in [app, bureau, bureau_balance, cash, credit, previous, installments]: 115 | if index in list(dataset.columns): 116 | dataset[index] = dataset[index].fillna(0).astype(np.int64) 117 | ``` 118 | 119 | 120 | # Featuretools 基础 121 | 122 | 123 | [Featuretools](https://docs.featuretools.com/#minute-quick-start)是一个使用一种技术叫做`Deep Feature Synthesis` 深度特征合成从一组相关表中创建特征的python开源库.自动特征工程,像许多机器学习主题一样, 是一个基于简单思想的复杂主题.通过这一次研究这些思想,我们建立对Featuretools的理解,以后更加充分利用它. 124 | 125 | 126 | 在此过程中我们会涉及一些概念: 127 | 128 | 129 | * [实体 and 实体集合](https://docs.featuretools.com/loading_data/using_entitysets.html): 表和用于追踪所有表格的数据结构 130 | 131 | * [表之间关系](https://docs.featuretools.com/loading_data/using_entitysets.html#adding-a-relationship):一张表与另一张表如何关联 132 | 133 | * [特征基元](https://docs.featuretools.com/automated_feature_engineering/primitives.html):聚合和转换通过堆叠以构建特征,通俗理解就是业务主键,通常是业务订单号. 134 | 135 | * [深度特征合成](https://docs.featuretools.com/automated_feature_engineering/afe.html): 使用特征基元生成成千上万个新特征的方法 136 | 137 | 138 | # 实体和实体集合 139 | 140 | 实体是简单的一张表或pandas的`dataframe`数据框. 观测值必须在行中,特征必须在列中. 一个实体在Featuretools中必须有一个唯一的缩影且索引不重复. 目前, 只有`app`, `bureau`和`previous`具有唯一索引(分别是`SK_ID_CURR`, `SK_ID_BUREAU`, 和 `SK_ID_PREV`). 对于别的数据框, 我们必须通过制定参数`make_index=True`参数为这些没有唯一索引的数据框创建索引并命名. 141 | 142 | 143 | 实体也可以具有时间索引,一个时间索引可以指定该行信息(任何数据中都没有日期时间, 但是有一些相对时间(以月或天为单位)可以视为时间变量, 尽管在本文中我们不会将其用作时间索引). 144 | 145 | 146 | 一个实体集由表及其之间的关系构成. 这来自数据结构自身的方法和属性.使用实体集可使我们将多个表组合在一起使创建特征, 这比跟踪单个表和关系简单得多.实体集和实体是可以应用于任何数据集的抽象,因为它们不依赖于基础数据特定字段. 147 | 148 | 149 | 首先我们初始化一个空实体集命名为`clients`. 150 | 151 | 152 | ```python 153 | # Entity set with id applications 154 | es = ft.EntitySet(id = 'clients') 155 | ``` 156 | 157 | 158 | ### 变量类型 159 | 160 | 161 | Featuretools 会自动推断变量类型. 然而,有些特征我们需要向Featuretools指定变量类型, 例如表现为整数的`bool`变量. 在Featuretools中可以通过一个字典指定变量类型. 162 | 163 | 164 | 我们首先要为`app`数据指定正确的变量类型,即辨别已经记录为数值(1.0或0.0)的`Boolean`变量,我们可以遍历数据集中的每个变量是否只有2值且类型为数值.我们也可以直接指定某个列为特定类型, 例如有序变量`Ordinal`类型.识别正确的变量类型很重要,因为Featuretools是根据不同的数据类型运行不同的操作逻辑(如同我们进行人工构建特征工程一样). 165 | 166 | 167 | ```python 168 | import featuretools.variable_types as vtypes 169 | ``` 170 | 171 | 172 | ```python 173 | app_types = {} 174 | 175 | # Handle the Boolean variables: 176 | # 手动指定`Boolean`变量 177 | 178 | for col in app.columns: 179 | if (app[col].nunique() == 2) and (app[col].dtype == float): 180 | app_types[col] = vtypes.Boolean 181 | 182 | # Remove the `TARGET` 183 | del app_types['TARGET'] 184 | 185 | print('There are {} Boolean variables in the application data.'.format(len(app_types))) 186 | ``` 187 | 188 | There are 32 Boolean variables in the application data. 189 | 190 | 191 | 192 | ```python 193 | # Ordinal variables 194 | # 有序离散变量 195 | app_types['REGION_RATING_CLIENT'] = vtypes.Ordinal 196 | app_types['REGION_RATING_CLIENT_W_CITY'] = vtypes.Ordinal 197 | app_types['HOUR_APPR_PROCESS_START'] = vtypes.Ordinal 198 | ``` 199 | 200 | 201 | `previous`数据表是唯一应记录为`Boolean`特征的其他实体.正确地指定变量类型避免Featuretools构建无意义的特征,例如对`Boolean`进行求均值或求最大值. 202 | 203 | 204 | ```python 205 | previous_types = {} 206 | 207 | # Handle the Boolean variables: 208 | for col in previous: 209 | if (previous[col].nunique() == 2) and (previous[col].dtype == float): 210 | previous_types[col] = vtypes.Boolean 211 | 212 | print('There are {} Boolean variables in the previous data.'.format(len(previous_types))) 213 | ``` 214 | 215 | There are 2 Boolean variables in the previous data. 216 | 217 | 218 | 219 | 除了标记为`Boolean`变量外, 我们必须确保Featuretools不会构造没有意义的特征, 例如统计聚合(均值,最大值等).`credit`, `cash`, and `installments`表数据都有`SK_ID_CURR` 变量. 然而,实际上我们不需要这个变量,因为是通过表`previous`中的 `SK_ID_PREV`关联到表`app`中. 220 | 221 | 223 | 我们并不基于`SK_ID_CURR`创建特征, 因为他是没有业务意义的id,并不具有预测能力. 我们处理这些变量的选项是告诉Featuretools忽略它们. 或者在将数据表加入实体集之前就将它们移除, 我们将采用后一种方法. 224 | 225 | 226 | ```python 227 | installments = installments.drop(columns = ['SK_ID_CURR']) 228 | credit = credit.drop(columns = ['SK_ID_CURR']) 229 | cash = cash.drop(columns = ['SK_ID_CURR']) 230 | ``` 231 | 232 | 233 | ## 添加实体集 234 | 235 |
现在我们定义了每个实体,表数据, 并将其添加到实体集. 如果没有表索引则需要创建索引或设置参数`make_index=True`. 在这个案例中我们需要创建一个索引,并为这个索引命名. 与此同时,我们通过变量类型字典指定个别需特定的变量类型. 以下代码将7张表添加到实体集中. 236 | 237 | 238 | ```python 239 | # Entities with a unique index 240 | # 具有唯一索引的实体 241 | es = es.entity_from_dataframe(entity_id = 'app', dataframe = app, index = 'SK_ID_CURR', 242 | variable_types = app_types) 243 | 244 | es = es.entity_from_dataframe(entity_id = 'bureau', dataframe = bureau, index = 'SK_ID_BUREAU') 245 | 246 | es = es.entity_from_dataframe(entity_id = 'previous', dataframe = previous, index = 'SK_ID_PREV', 247 | variable_types = previous_types) 248 | 249 | # Entities that do not have a unique index 250 | # 没有唯一索引的实体, 通过`make_index=True`参数标记,并通过`index`参数命名 251 | es = es.entity_from_dataframe(entity_id = 'bureau_balance', dataframe = bureau_balance, 252 | make_index = True, index = 'bureaubalance_index') 253 | 254 | es = es.entity_from_dataframe(entity_id = 'cash', dataframe = cash, 255 | make_index = True, index = 'cash_index') 256 | 257 | es = es.entity_from_dataframe(entity_id = 'installments', dataframe = installments, 258 | make_index = True, index = 'installments_index') 259 | 260 | es = es.entity_from_dataframe(entity_id = 'credit', dataframe = credit, 261 | make_index = True, index = 'credit_index') 262 | ``` 263 | 264 | 265 | ```python 266 | # Display entityset so far 267 | # 显示到目前为止的添加的实体 268 | es 269 | ``` 270 | 271 | 272 | 273 | 274 | Entityset: clients 275 | Entities: 276 | app [Rows: 356255, Columns: 122] 277 | bureau [Rows: 1716428, Columns: 17] 278 | previous [Rows: 1670214, Columns: 37] 279 | bureau_balance [Rows: 27299925, Columns: 4] 280 | cash [Rows: 10001358, Columns: 8] 281 | installments [Rows: 13605401, Columns: 8] 282 | credit [Rows: 3840312, Columns: 23] 283 | Relationships: 284 | No relationships 285 | 286 | 287 | 288 | 289 |
`实体集`允许我们将所有分表组成一个数据结构. 这相对于一次操作一张表容易得多(正如我们人工构建特征工程那样). 290 | 291 | 292 | # 实体间关系 293 | 294 |
实体间关系不仅是Featuretools中的一个基本概念,也是任何关系型数据库表间关系.表间关系最常见得类型之一就是一对多关系.一对多关系最好的思路之一是将其比喻为父子关系.父是一个单一的个体,但是可以有多个子.在表前后关系中, 一个父表对应每个个体都有唯一一个观测行, 而每个子表对应父表每个个体可以有很多个观测行.在一个父表中, 每个个体有一个单独的行且是通过索引确定的唯一行(也可以叫做主键). 每一个父表中的个体在子表中可以有多行.还可以更复杂,因为子表也可以有他们自己的子表.作为父表的孙子表. 295 | 296 | 297 |
作为父与子关系案例, 每个客户在数据框`app`都有一行(通过`SK_ID_CURR`标记),与此同时每个客户在表`bureau`中有多笔历史贷款.因此, 表`bureau`是表`app`的子表. 表`bureau`是表`bureau_balance`父表因为表`bureau`中的每一笔贷款(通过`SK_ID_BUREAU`指定)在表`bureau_balance`中有多个月还款记录.当我们进行人工特征工程时,跟踪这些关系需要投入大量的时间(也是常见错误的来源). 我们可以将这些关系添加到`实体集`中并让Featuretools跟踪执行. 298 | 299 | 300 | ```python 301 | print('Parent: app, Parent Variable of bureau: SK_ID_CURR\n\n', app.iloc[:, 111:115].head()) 302 | print('\nChild: bureau, Child Variable of app: SK_ID_CURR\n\n', bureau.iloc[:, :5].head()) 303 | ``` 304 | 305 | Parent: app, Parent Variable of bureau: SK_ID_CURR 306 | 307 | SK_ID_CURR TARGET TOTALAREA_MODE WALLSMATERIAL_MODE 308 | 0 100002 1.0 0.0149 Stone, brick 309 | 1 100003 0.0 0.0714 Block 310 | 2 100004 0.0 NaN NaN 311 | 3 100006 0.0 NaN NaN 312 | 4 100007 0.0 NaN NaN 313 | 314 | Child: bureau, Child Variable of app: SK_ID_CURR 315 | 316 | SK_ID_CURR SK_ID_BUREAU CREDIT_ACTIVE CREDIT_CURRENCY DAYS_CREDIT 317 | 0 215354 5714462 Closed currency 1 -497.0 318 | 1 215354 5714463 Active currency 1 -208.0 319 | 2 215354 5714464 Active currency 1 -203.0 320 | 3 215354 5714465 Active currency 1 -203.0 321 | 4 215354 5714466 Active currency 1 -629.0 322 | 323 | 324 | 325 | `SK_ID_CURR`215354行在父表中每一个只有一行但是在子表中有多行. 326 | 327 |
两张表通过一个共享变量链接. 表`app`和表`bureau`通过`Sk_ID_CURR`变量链接, 而表`bureau`和表`bureau_balance`通过`SK_ID_BUREAU`链接. 这个链接变量在父表中称为`父`变量, 在子表中称为`子`变量. 328 | 329 | 330 | ```python 331 | print('Parent: bureau, Parent Variable of bureau_balance: SK_ID_BUREAU\n\n', bureau.iloc[:, :5].head()) 332 | print('\nChild: bureau_balance, Child Variable of bureau: SK_ID_BUREAU\n\n', bureau_balance.head()) 333 | ``` 334 | 335 | Parent: bureau, Parent Variable of bureau_balance: SK_ID_BUREAU 336 | 337 | SK_ID_CURR SK_ID_BUREAU CREDIT_ACTIVE CREDIT_CURRENCY DAYS_CREDIT 338 | 0 215354 5714462 Closed currency 1 -497.0 339 | 1 215354 5714463 Active currency 1 -208.0 340 | 2 215354 5714464 Active currency 1 -203.0 341 | 3 215354 5714465 Active currency 1 -203.0 342 | 4 215354 5714466 Active currency 1 -629.0 343 | 344 | Child: bureau_balance, Child Variable of bureau: SK_ID_BUREAU 345 | 346 | bureaubalance_index SK_ID_BUREAU MONTHS_BALANCE STATUS 347 | 0 0 5715448 0 C 348 | 1 1 5715448 -1 C 349 | 2 2 5715448 -2 C 350 | 3 3 5715448 -3 C 351 | 4 4 5715448 -4 C 352 | 353 | 354 | 355 |
常规上,我们利用父与子之间关系通过将一个父的所有子分组聚合数据从而进行统计计算. 例如,我们可以将一个客户的所有贷款汇总并计算平均贷款金额.这是很直接的,但是当我们想要构建这些成百上千的特征就会变得非常乏味.一次构建一个这样的特征非常低效,因为我们需要一遍又一遍重复写这些代码且这些代码并不能应用于不同的项目! 356 | 357 | 358 |
当我们需要聚合祖孙表时事情将变得更糟糕, 因为我们需要两步: 首先聚合父级, 然后再聚合祖父级.待会我们将见到Featuretools可以自动完成这些工作, 并给予这些数据生成成千上万的特征. 当我们人工构建这些特征平均每个花费15分钟(正如我们人工构建特征一样),如果完成Featuretools构建这些特征将耗费数小时. 359 | 360 | 361 | 362 | ### 添加关系 363 | 364 |
直接使用图数据表定义关系, 对于每个关系,首先需要指定父变量和子变量,在这些表之间总共有6个关系(将trainning和testing关系当做一个).以下我们指明实体与实体之间的关系并将其添加到实体集中. 365 | 366 | 367 | ```python 368 | # Relationship between app_train and bureau 369 | # app_train 与 bureau 关联 370 | r_app_bureau = ft.Relationship(es['app']['SK_ID_CURR'], es['bureau']['SK_ID_CURR']) 371 | 372 | # Relationship between bureau and bureau balance 373 | # bureau 与 balance 关联 374 | r_bureau_balance = ft.Relationship(es['bureau']['SK_ID_BUREAU'], es['bureau_balance']['SK_ID_BUREAU']) 375 | 376 | # Relationship between current app and previous apps 377 | # app 和 previous apps 关联 378 | r_app_previous = ft.Relationship(es['app']['SK_ID_CURR'], es['previous']['SK_ID_CURR']) 379 | 380 | # Relationships between previous apps and cash, installments, and credit 381 | # previous apps and cash, installments, and credit实体之间的关系 382 | 383 | r_previous_cash = ft.Relationship(es['previous']['SK_ID_PREV'], es['cash']['SK_ID_PREV']) 384 | r_previous_installments = ft.Relationship(es['previous']['SK_ID_PREV'], es['installments']['SK_ID_PREV']) 385 | r_previous_credit = ft.Relationship(es['previous']['SK_ID_PREV'], es['credit']['SK_ID_PREV']) 386 | ``` 387 | 388 | 389 | ```python 390 | # Add in the defined relationships 391 | # 添加定义的实体关系 392 | es = es.add_relationships([r_app_bureau, r_bureau_balance, r_app_previous, 393 | r_previous_cash, r_previous_installments, r_previous_credit]) 394 | # Print out the EntitySet 395 | es 396 | ``` 397 | 398 | 399 | 400 | 401 | Entityset: clients 402 | Entities: 403 | app [Rows: 356255, Columns: 122] 404 | bureau [Rows: 1716428, Columns: 17] 405 | previous [Rows: 1670214, Columns: 37] 406 | bureau_balance [Rows: 27299925, Columns: 4] 407 | cash [Rows: 10001358, Columns: 8] 408 | installments [Rows: 13605401, Columns: 8] 409 | credit [Rows: 3840312, Columns: 23] 410 | Relationships: 411 | bureau.SK_ID_CURR -> app.SK_ID_CURR 412 | bureau_balance.SK_ID_BUREAU -> bureau.SK_ID_BUREAU 413 | previous.SK_ID_CURR -> app.SK_ID_CURR 414 | cash.SK_ID_PREV -> previous.SK_ID_PREV 415 | installments.SK_ID_PREV -> previous.SK_ID_PREV 416 | credit.SK_ID_PREV -> previous.SK_ID_PREV 417 | 418 | 419 | 420 | 421 |
再次,使用实体集的好处是实体集能为我们追踪实体关系.这使得我们可以在更高的抽象水平上工作, 考虑整个数据集,而不是每个个体数据表, 极大地提升效率. 422 | 423 | 424 |
粗略概要:我们需要谨慎地在多个来自父表的子表创建菱形图链路. 如果我们直接通过`SK_ID_CURR`链接表`app`和表`cash`;通过`SK_ID_PREV`链接`previous` and `cash`; 通过`SK_ID_CURR`链接`app` 和 `previous`, 然后通过`app`和`cash`创建链路.这个链路显得模糊不清, 因此我们可以通过`previous`替代`app`和`cash`的链接,使用`SK_ID_PREV`在`previous`(父)与`cash`(子)之间创建关系. 然后使用`SK_ID_CURR`在`app`(父)和`previous`(子)之间创建一个关系.然后Featuretools可以通过多重基元堆叠在`app`上创建特征衍生自`previous`和`cash`. 425 | 426 | 427 |
如果这不好理解, 那么只要记住一个路径包括一个父到任何后代. 例如, 一个祖父到祖孙的链路是通过父而不是直接通过共享变量. 428 | 429 | 430 |
所有实体都可以通过链路进行关联.理论上这使得我们可以计算任何实体特征, 但是在实践中, 我们只以表`app`为基准计算特征因为他是用于训练/预测. 最终结果是一个dataframe数据框,且每一个在`app`中客户将有成千上万个特征. 431 | 432 | 433 | 我们几乎可以开始构建成千上万个特征了, 但是还有一些基础概念需要了解. 以下将介绍特征基元. 434 | 435 | 436 | ## 可视化特征实体 437 | 438 | 439 | ```python 440 | %matplotlib inline 441 | ``` 442 | 443 | 444 | ```python 445 | es.plot() 446 | ``` 447 | 448 | 449 | 450 | 451 | ![avatar](/output.png) 452 | 453 | 454 | 455 | 456 | # 特征基元 457 | 458 | 459 |
特征基元是应用于表或一组表集来构建特征的操作准则.这些简单的计算方法, 我们在人工构造变量过程中已经使用了很多,可以彼此堆叠以创建复杂的深层特征.特征基元分为两类: 460 | 461 | 462 | * __聚合__: 该函数将每个父的子分组在一起进行统计数据, 例如平均值,最小值,最大值或标准差,以及子之间的交叉. 一个示例是每个客户的最大历史贷款金额, 使用表之间的关系多个表进行聚合. 463 | 464 | * __转换__: 该操作应用于单表中一个或多个列. 例如取一列的绝对值,或查找一张表中两列的差值. 465 | 466 | 467 | 468 |
Featuretools可以使用的特征基元如下表. 469 | 470 | 471 | ```python 472 | # List the primitives in a dataframe 473 | # 特征基元表. 474 | primitives = ft.list_primitives() 475 | pd.options.display.max_colwidth = 100 476 | 477 | primitives[primitives['type'] == 'aggregation'].tail(10) 478 | ``` 479 | 480 | 481 | 482 | 483 |
484 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 |
nametypedescription
12lastaggregationDetermines the last value in a list.
13modeaggregationDetermines the most commonly repeated value.
14sumaggregationCalculates the total addition, ignoring `NaN`.
15stdaggregationComputes the dispersion relative to the mean value, ignoring `NaN`.
16medianaggregationDetermines the middlemost number in a list of values.
17avg_time_betweenaggregationComputes the average number of seconds between consecutive events.
18trendaggregationCalculates the trend of a variable over time.
19percent_trueaggregationDetermines the percent of `True` values.
20time_since_lastaggregationCalculates the time elapsed since the last datetime (default in seconds).
21num_uniqueaggregationDetermines the number of distinct values, ignoring `NaN` values.
569 |
570 | 571 | 572 | 573 | 574 | ```python 575 | primitives[primitives['type'] == 'transform'].tail(10) 576 | ``` 577 | 578 | 579 | 580 | 581 |
582 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 |
nametypedescription
68less_than_equal_to_scalartransformDetermines if values are less than or equal to a given scalar.
69isintransformDetermines whether a value is present in a provided list.
70cum_meantransformCalculates the cumulative mean.
71add_numeric_scalartransformAdd a scalar to each value in the list.
72less_thantransformDetermines if values in one list are less than another list.
73num_wordstransformDetermines the number of words in a string by counting the spaces.
74absolutetransformComputes the absolute value of a number.
75cum_sumtransformCalculates the cumulative sum.
76multiply_booleantransformElement-wise multiplication of two lists of boolean values.
77not_equal_scalartransformDetermines if values in a list are not equal to a given scalar.
667 |
668 | 669 | 670 | 671 | 672 | ```python 673 | primitives.type.unique() 674 | ``` 675 | 676 | 677 | 678 | 679 | array(['aggregation', 'transform'], dtype=object) 680 | 681 | 682 | 683 | 684 | # 深度特征合成 685 | 686 | 687 |
[深度特征合成 (DFS)]是featuretools用于创建新特征的方法.DFS基于特征基元堆栈特征"深度"等同于特征数.例如, 我们要计算客户历史借款最大值(称`MAX(previous.loan_amount)`),这是一个深度为1的深度特征.创建一个深度为2的特征. 我们需要堆叠特征客户的每笔贷款平均月还款额的最大值(例如`MAX(previous(MEAN(installments.payment)))`).在手动特征工程中, 需要两次单独分组和聚合花费超过15分钟为每一个特征写代码. 688 | 689 | 690 |
深度特征合成是一个非常有效的方法,在创造特征过程中为我们人类克服了时间局限性和想象力.无需独立自主进行思考(不用耐心去实现特征构建).因此,DFS只需要进行细微调整即可应用于任何数据集. 在特征工程中, 我们通常应用相同函数于不同的数据集, 但是当我们手动完成时, 必须重复编写代码, 因为每个项目是特定的. Featuretools代码可以应用于任何数据集因为他是更高级的抽象. 691 | 692 | 693 | 你可以阅读[使用深度特征合成在自动化特征工程的论文]如果你想更深层次理解的话. 694 | 695 | 696 |
为了在Featuretools中执行DFS, 我们通过使用`dfs`函数的`entityset`,`target_entity`(我们需要制作的特征), `agg_primitives`,`trans_primitives`,`max_depth`等参数,以及其他一些参数,具体取决于我们的用例. 还有多任务参数`njobs`和信息打印参数`verbose`. 697 | 698 | 699 |
另一个重要参数是`eatures_only`. 如果我们设置为`True`, `dfs`将只生成特征名,而不会实际计算出特征值(特征矩阵值). 当我们进行特征创建和保存检查时,只生成特征名而不进行计算是非常有用的. 700 | 701 | 702 | ## 深度特征合成默认原函数 703 | 704 | 705 |
在Featuretools中不使用任何领域知识我们可以使用深度特征合成默认原函数构建成千上万特征.首先使用聚合和转换原函数. 一个深度为2的实体特征. 将只生成特征名进行保存和检查. 706 | 707 | 708 | ```python 709 | # Default primitives from featuretools 710 | default_agg_primitives = ["sum", "std", "max", "skew", "min", "mean", "count", "percent_true", "num_unique", "mode"] 711 | default_trans_primitives = ["day", "year", "month", "weekday", "haversine", "num_words", "num_characters"] 712 | 713 | # DFS with specified primitives 714 | feature_names = ft.dfs(entityset = es, target_entity = 'app', 715 | trans_primitives = default_trans_primitives, 716 | agg_primitives=default_agg_primitives, 717 | where_primitives = [], seed_features = [], 718 | max_depth = 2, n_jobs = -1, verbose = 1, 719 | features_only=True) 720 | ``` 721 | 722 | Built 2069 features 723 | 724 | 725 | 726 |
即使是对深度特征合成基本调用也能为我们生成1500多个特征. 诚然,这些特征并非都重要. 但是依旧意味着我们可以节约数百小时.此外,`dfs`也许能找到重要的特征, 在这之前我们从未想到过的特征. 727 | 728 | 729 |
我们可以查看一些特征名称: 730 | 731 | 732 | ```python 733 | feature_names[-15:] 734 | ``` 735 | 736 | 737 | 738 | 739 | [, 740 | , 741 | , 742 | , 743 | , 744 | , 745 | , 746 | , 747 | , 748 | , 749 | , 750 | , 751 | , 752 | , 753 | ] 754 | 755 | 756 | 757 | 758 |
注意Featuretools是如何将多个基元进行批次堆叠.这是深度特征合成和自动特征工程的背后思路之一,不必人工进行分组和聚合. Featuretools可以使用架构(`实体`,`关系`,和`基元`)进行, 我们也可以使用Featuretools扩展我们的领域知识. 759 | 760 | 761 | # 建立在领域知识上的特征 762 | 763 | 764 | 765 |
Featuretools可以自动为我们构建成千上万个特征. 但是并不意味着我们不能使用领域知识去提升预测性能. Featuretools可以添加我们的领域知识通过堆放额外的基础领域特征.我们根据自己的知识以及数千位在Kaggle上解决此问题的数据科学家的知识,在手动特征工程笔记本中识别并创建了许多有用的特征.我们不仅可以获得一个领域知识特征,而且可以有效获得数十甚至数百个知识特征.__在这里,我们将说明使用领域知识的选项是为了比较.但我们将坚持使用Featuretools的简单实现.__ 766 | 767 |
更多信息见Featuretools[文档](https://docs.featuretools.com/guides/tuning_dfs.html)或者阅读其他文章. 768 | 769 | ### 种子特征 770 | 771 |
种子特征是我们在数据中创建的领域特征, 然后可以在Featuretools的基础上构建它们. 例如, 我们看到贷款利率是一个重要特征, 因为利率较高的贷款可能更具风险. 在Featuretools中, 我们可以将贷款利率(当前贷款和历史贷款两者)编码为种子特征, Featuretools会在可能的情况下基于此领域知识构建其他解释变量. 772 | 773 | 774 | ### 特别值 775 | 776 |
特别值与种子特征具有相似的思路, 除了它们使我们能够形成条件特征. 例如, 我们可能想为每个客户查找已关闭的历史贷款的平均金额和仍处于还款状态的历史贷款的平均金额. 通过在表`bureau`中变量`CREDIT_ACTIVE`指定有趣的值, 我们可以让Featuretools做到这一点, 手工执行此操作将非常繁琐,并且积极可能发生错误. 777 | 778 | 779 | ### 自定义基元 780 | 781 | 782 |
如果我们不满意Featuretools中可用的基元, 可以自定义函数完成数据聚合和转换. 这是Featuretools最有用之处, 因为他可以为编写很多特征操作应用于多个数据集. 783 | 784 | 785 |
__在本文中将专注于Featuretools的基本应用, 但是请注意一些功能可以用于优化数据和使用领域知识!__ 786 | 787 | 788 | # 基元选择 789 | 790 | 791 |
在实践特征构建中, 我们使用一组基元并进行定义基元组, 他们将生成1800多个特征. 792 | 793 | 794 | ```python 795 | # Specify primitives 796 | agg_primitives = ["sum", "max", "min", "mean", "count", "percent_true", "num_unique", "mode"] 797 | trans_primitives = ['percentile', 'and'] 798 | ``` 799 | 800 | 801 | ```python 802 | # Deep feature synthesis 803 | feature_names = ft.dfs(entityset=es, target_entity='app', 804 | agg_primitives = agg_primitives, 805 | trans_primitives = trans_primitives, 806 | n_jobs = -1, verbose = 1, 807 | features_only = True, 808 | max_depth = 2) 809 | ``` 810 | 811 | Built 2188 features 812 | 813 | 814 | 815 | ```python 816 | ft.save_features(feature_names, 'input/features.txt') 817 | ``` 818 | 819 | 820 | 如果我们保存特征, 我们可以使用他们进行`特征矩阵计算`. 这非常有用, 当我们想要在不同数据集生成相同特征时(例如我们有特定的训练和测试集). 821 | 822 | 823 | ## 运行深度特征合成 824 | 825 | 826 |
如果我们对将要构建的特征满意, 则可以运行深度特征合成并创建特征矩阵. 以下调用运行完整的深度特征合成. 根据您的计算机,这可能需要很长时间. Featuretools确实允许并行处理, 但是每个核必须能够处理整个实体集. 827 | 828 | 829 | __该代码运行实际上是使用Dask(云服务器)完成的.Dask上代码运行时间不到2个小时, 这是一个很好的示例, 说明了我们如何使用并行处理以最有效的方式使用资源.__ 830 | 831 | 832 | ```python 833 | import sys 834 | print('Total size of entityset: {:.5f} gb.'.format(sys.getsizeof(es) / 1e9)) 835 | ``` 836 | 837 | Total size of entityset: 11.80507 gb. 838 | 839 | 840 | 841 | ```python 842 | import psutil 843 | 844 | print('Total number of cpus detected: {}.'.format(psutil.cpu_count())) 845 | print('Total size of system memory: {:.5f} gb.'.format(psutil.virtual_memory().total / 1e9)) 846 | ``` 847 | 848 | Total number of cpus detected: 12. 849 | Total size of system memory: 17.17987 gb. 850 | 851 | 852 | 853 | ```python 854 | # feature_matrix, feature_names = ft.dfs(entityset=es, target_entity='app', 855 | # agg_primitives = agg_primitives, 856 | # trans_primitives = trans_primitives, 857 | # n_jobs = -1, verbose = 1, features_only = False, 858 | # max_depth = 1, chunk_size = 10) 859 | ``` 860 | 861 | 862 | ```python 863 | feature_matrix.reset_index(inplace = True) 864 | feature_matrix.to_csv('input/feature_matrix.csv', index = False) 865 | ``` 866 | 867 | 868 |
在这个[地址](https://www.kaggle.com/willkoehrsen/home-credit-default-risk-feature-tools)选择`feature_matrix_article.csv`下载特征矩阵.那里还有自动特征工程特征矩阵的其他几种版本. 869 | 870 | 871 | # 结论 872 | 873 | 874 |
在本文, 我们看到了如何针对数据科学问题实施自动化特征工程. __自动化特征工程为我们创建数千个特征基于一个关系表,大大提高了我们作为数据科学家的效率.__ 此外, 我们依然可以使用领域知识,甚至可以通过手动构建特征主题来加强领域知识.主要收获: 875 | 876 | * 自动化特征工程消耗1小时执行完10小时的人工特征工程. 877 | 878 | * 自动化特征工程只需要少了代码(相比于人工特征工程每个特征都要编写大量逻辑代码)即可构建数千个特征. 879 | 880 | * 总体上, 自动化特征工程性能比人工特征工程性能好(见另一个笔记). 881 | 882 | 883 |
自动化特征工程的好处是显著的,将极大地帮助我们作为一名数据科学家, 它不会减少对数据科学家的需求, 而是可以使我们更高效, 并在更短的时间内建立更好的预测管道. 884 | -------------------------------------------------------------------------------- /output.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | clients 11 | 12 | 13 | 14 | app 15 | 16 | app (356255 rows) 17 | 18 | SK_ID_CURR : index 19 | AMT_ANNUITY : numeric 20 | AMT_CREDIT : numeric 21 | AMT_GOODS_PRICE : numeric 22 | AMT_INCOME_TOTAL : numeric 23 | AMT_REQ_CREDIT_BUREAU_DAY : numeric 24 | AMT_REQ_CREDIT_BUREAU_HOUR : numeric 25 | AMT_REQ_CREDIT_BUREAU_MON : numeric 26 | AMT_REQ_CREDIT_BUREAU_QRT : numeric 27 | AMT_REQ_CREDIT_BUREAU_WEEK : numeric 28 | AMT_REQ_CREDIT_BUREAU_YEAR : numeric 29 | APARTMENTS_AVG : numeric 30 | APARTMENTS_MEDI : numeric 31 | APARTMENTS_MODE : numeric 32 | BASEMENTAREA_AVG : numeric 33 | BASEMENTAREA_MEDI : numeric 34 | BASEMENTAREA_MODE : numeric 35 | CNT_CHILDREN : numeric 36 | CNT_FAM_MEMBERS : numeric 37 | CODE_GENDER : categorical 38 | COMMONAREA_AVG : numeric 39 | COMMONAREA_MEDI : numeric 40 | COMMONAREA_MODE : numeric 41 | DAYS_BIRTH : numeric 42 | DAYS_EMPLOYED : numeric 43 | DAYS_ID_PUBLISH : numeric 44 | DAYS_LAST_PHONE_CHANGE : numeric 45 | DAYS_REGISTRATION : numeric 46 | DEF_30_CNT_SOCIAL_CIRCLE : numeric 47 | DEF_60_CNT_SOCIAL_CIRCLE : numeric 48 | ELEVATORS_AVG : numeric 49 | ELEVATORS_MEDI : numeric 50 | ELEVATORS_MODE : numeric 51 | EMERGENCYSTATE_MODE : categorical 52 | ENTRANCES_AVG : numeric 53 | ENTRANCES_MEDI : numeric 54 | ENTRANCES_MODE : numeric 55 | EXT_SOURCE_1 : numeric 56 | EXT_SOURCE_2 : numeric 57 | EXT_SOURCE_3 : numeric 58 | FLAG_OWN_CAR : categorical 59 | FLAG_OWN_REALTY : categorical 60 | FLOORSMAX_AVG : numeric 61 | FLOORSMAX_MEDI : numeric 62 | FLOORSMAX_MODE : numeric 63 | FLOORSMIN_AVG : numeric 64 | FLOORSMIN_MEDI : numeric 65 | FLOORSMIN_MODE : numeric 66 | FONDKAPREMONT_MODE : categorical 67 | HOUSETYPE_MODE : categorical 68 | LANDAREA_AVG : numeric 69 | LANDAREA_MEDI : numeric 70 | LANDAREA_MODE : numeric 71 | LIVINGAPARTMENTS_AVG : numeric 72 | LIVINGAPARTMENTS_MEDI : numeric 73 | LIVINGAPARTMENTS_MODE : numeric 74 | LIVINGAREA_AVG : numeric 75 | LIVINGAREA_MEDI : numeric 76 | LIVINGAREA_MODE : numeric 77 | NAME_CONTRACT_TYPE : categorical 78 | NAME_EDUCATION_TYPE : categorical 79 | NAME_FAMILY_STATUS : categorical 80 | NAME_HOUSING_TYPE : categorical 81 | NAME_INCOME_TYPE : categorical 82 | NAME_TYPE_SUITE : categorical 83 | NONLIVINGAPARTMENTS_AVG : numeric 84 | NONLIVINGAPARTMENTS_MEDI : numeric 85 | NONLIVINGAPARTMENTS_MODE : numeric 86 | NONLIVINGAREA_AVG : numeric 87 | NONLIVINGAREA_MEDI : numeric 88 | NONLIVINGAREA_MODE : numeric 89 | OBS_30_CNT_SOCIAL_CIRCLE : numeric 90 | OBS_60_CNT_SOCIAL_CIRCLE : numeric 91 | OCCUPATION_TYPE : categorical 92 | ORGANIZATION_TYPE : categorical 93 | OWN_CAR_AGE : numeric 94 | REGION_POPULATION_RELATIVE : numeric 95 | TARGET : numeric 96 | TOTALAREA_MODE : numeric 97 | WALLSMATERIAL_MODE : categorical 98 | WEEKDAY_APPR_PROCESS_START : categorical 99 | YEARS_BEGINEXPLUATATION_AVG : numeric 100 | YEARS_BEGINEXPLUATATION_MEDI : numeric 101 | YEARS_BEGINEXPLUATATION_MODE : numeric 102 | YEARS_BUILD_AVG : numeric 103 | YEARS_BUILD_MEDI : numeric 104 | YEARS_BUILD_MODE : numeric 105 | FLAG_CONT_MOBILE : boolean 106 | FLAG_DOCUMENT_10 : boolean 107 | FLAG_DOCUMENT_11 : boolean 108 | FLAG_DOCUMENT_12 : boolean 109 | FLAG_DOCUMENT_13 : boolean 110 | FLAG_DOCUMENT_14 : boolean 111 | FLAG_DOCUMENT_15 : boolean 112 | FLAG_DOCUMENT_16 : boolean 113 | FLAG_DOCUMENT_17 : boolean 114 | FLAG_DOCUMENT_18 : boolean 115 | FLAG_DOCUMENT_19 : boolean 116 | FLAG_DOCUMENT_2 : boolean 117 | FLAG_DOCUMENT_20 : boolean 118 | FLAG_DOCUMENT_21 : boolean 119 | FLAG_DOCUMENT_3 : boolean 120 | FLAG_DOCUMENT_4 : boolean 121 | FLAG_DOCUMENT_5 : boolean 122 | FLAG_DOCUMENT_6 : boolean 123 | FLAG_DOCUMENT_7 : boolean 124 | FLAG_DOCUMENT_8 : boolean 125 | FLAG_DOCUMENT_9 : boolean 126 | FLAG_EMAIL : boolean 127 | FLAG_EMP_PHONE : boolean 128 | FLAG_MOBIL : boolean 129 | FLAG_PHONE : boolean 130 | FLAG_WORK_PHONE : boolean 131 | LIVE_CITY_NOT_WORK_CITY : boolean 132 | LIVE_REGION_NOT_WORK_REGION : boolean 133 | REG_CITY_NOT_LIVE_CITY : boolean 134 | REG_CITY_NOT_WORK_CITY : boolean 135 | REG_REGION_NOT_LIVE_REGION : boolean 136 | REG_REGION_NOT_WORK_REGION : boolean 137 | REGION_RATING_CLIENT : ordinal 138 | REGION_RATING_CLIENT_W_CITY : ordinal 139 | HOUR_APPR_PROCESS_START : ordinal 140 | 141 | 142 | 143 | bureau 144 | 145 | bureau (1716428 rows) 146 | 147 | SK_ID_BUREAU : index 148 | SK_ID_CURR : id 149 | CREDIT_ACTIVE : categorical 150 | CREDIT_CURRENCY : categorical 151 | DAYS_CREDIT : numeric 152 | CREDIT_DAY_OVERDUE : numeric 153 | DAYS_CREDIT_ENDDATE : numeric 154 | DAYS_ENDDATE_FACT : numeric 155 | AMT_CREDIT_MAX_OVERDUE : numeric 156 | CNT_CREDIT_PROLONG : numeric 157 | AMT_CREDIT_SUM : numeric 158 | AMT_CREDIT_SUM_DEBT : numeric 159 | AMT_CREDIT_SUM_LIMIT : numeric 160 | AMT_CREDIT_SUM_OVERDUE : numeric 161 | CREDIT_TYPE : categorical 162 | DAYS_CREDIT_UPDATE : numeric 163 | AMT_ANNUITY : numeric 164 | 165 | 166 | 167 | bureau->app 168 | 169 | 170 | SK_ID_CURR 171 | 172 | 173 | 174 | previous 175 | 176 | previous (1670214 rows) 177 | 178 | SK_ID_PREV : index 179 | SK_ID_CURR : id 180 | NAME_CONTRACT_TYPE : categorical 181 | AMT_ANNUITY : numeric 182 | AMT_APPLICATION : numeric 183 | AMT_CREDIT : numeric 184 | AMT_DOWN_PAYMENT : numeric 185 | AMT_GOODS_PRICE : numeric 186 | WEEKDAY_APPR_PROCESS_START : categorical 187 | HOUR_APPR_PROCESS_START : numeric 188 | FLAG_LAST_APPL_PER_CONTRACT : categorical 189 | RATE_DOWN_PAYMENT : numeric 190 | RATE_INTEREST_PRIMARY : numeric 191 | RATE_INTEREST_PRIVILEGED : numeric 192 | NAME_CASH_LOAN_PURPOSE : categorical 193 | NAME_CONTRACT_STATUS : categorical 194 | DAYS_DECISION : numeric 195 | NAME_PAYMENT_TYPE : categorical 196 | CODE_REJECT_REASON : categorical 197 | NAME_TYPE_SUITE : categorical 198 | NAME_CLIENT_TYPE : categorical 199 | NAME_GOODS_CATEGORY : categorical 200 | NAME_PORTFOLIO : categorical 201 | NAME_PRODUCT_TYPE : categorical 202 | CHANNEL_TYPE : categorical 203 | SELLERPLACE_AREA : numeric 204 | NAME_SELLER_INDUSTRY : categorical 205 | CNT_PAYMENT : numeric 206 | NAME_YIELD_GROUP : categorical 207 | PRODUCT_COMBINATION : categorical 208 | DAYS_FIRST_DRAWING : numeric 209 | DAYS_FIRST_DUE : numeric 210 | DAYS_LAST_DUE_1ST_VERSION : numeric 211 | DAYS_LAST_DUE : numeric 212 | DAYS_TERMINATION : numeric 213 | NFLAG_LAST_APPL_IN_DAY : boolean 214 | NFLAG_INSURED_ON_APPROVAL : boolean 215 | 216 | 217 | 218 | previous->app 219 | 220 | 221 | SK_ID_CURR 222 | 223 | 224 | 225 | bureau_balance 226 | 227 | bureau_balance (27299925 rows) 228 | 229 | bureaubalance_index : index 230 | SK_ID_BUREAU : id 231 | MONTHS_BALANCE : numeric 232 | STATUS : categorical 233 | 234 | 235 | 236 | bureau_balance->bureau 237 | 238 | 239 | SK_ID_BUREAU 240 | 241 | 242 | 243 | cash 244 | 245 | cash (10001358 rows) 246 | 247 | cash_index : index 248 | SK_ID_PREV : id 249 | MONTHS_BALANCE : numeric 250 | CNT_INSTALMENT : numeric 251 | CNT_INSTALMENT_FUTURE : numeric 252 | NAME_CONTRACT_STATUS : categorical 253 | SK_DPD : numeric 254 | SK_DPD_DEF : numeric 255 | 256 | 257 | 258 | cash->previous 259 | 260 | 261 | SK_ID_PREV 262 | 263 | 264 | 265 | installments 266 | 267 | installments (13605401 rows) 268 | 269 | installments_index : index 270 | SK_ID_PREV : id 271 | NUM_INSTALMENT_VERSION : numeric 272 | NUM_INSTALMENT_NUMBER : numeric 273 | DAYS_INSTALMENT : numeric 274 | DAYS_ENTRY_PAYMENT : numeric 275 | AMT_INSTALMENT : numeric 276 | AMT_PAYMENT : numeric 277 | 278 | 279 | 280 | installments->previous 281 | 282 | 283 | SK_ID_PREV 284 | 285 | 286 | 287 | credit 288 | 289 | credit (3840312 rows) 290 | 291 | credit_index : index 292 | SK_ID_PREV : id 293 | MONTHS_BALANCE : numeric 294 | AMT_BALANCE : numeric 295 | AMT_CREDIT_LIMIT_ACTUAL : numeric 296 | AMT_DRAWINGS_ATM_CURRENT : numeric 297 | AMT_DRAWINGS_CURRENT : numeric 298 | AMT_DRAWINGS_OTHER_CURRENT : numeric 299 | AMT_DRAWINGS_POS_CURRENT : numeric 300 | AMT_INST_MIN_REGULARITY : numeric 301 | AMT_PAYMENT_CURRENT : numeric 302 | AMT_PAYMENT_TOTAL_CURRENT : numeric 303 | AMT_RECEIVABLE_PRINCIPAL : numeric 304 | AMT_RECIVABLE : numeric 305 | AMT_TOTAL_RECEIVABLE : numeric 306 | CNT_DRAWINGS_ATM_CURRENT : numeric 307 | CNT_DRAWINGS_CURRENT : numeric 308 | CNT_DRAWINGS_OTHER_CURRENT : numeric 309 | CNT_DRAWINGS_POS_CURRENT : numeric 310 | CNT_INSTALMENT_MATURE_CUM : numeric 311 | NAME_CONTRACT_STATUS : categorical 312 | SK_DPD : numeric 313 | SK_DPD_DEF : numeric 314 | 315 | 316 | 317 | credit->previous 318 | 319 | 320 | SK_ID_PREV 321 | 322 | 323 | 324 | -------------------------------------------------------------------------------- /output_34_0.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | clients 11 | 12 | 13 | 14 | app 15 | 16 | app (356255 rows) 17 | 18 | SK_ID_CURR : index 19 | AMT_ANNUITY : numeric 20 | AMT_CREDIT : numeric 21 | AMT_GOODS_PRICE : numeric 22 | AMT_INCOME_TOTAL : numeric 23 | AMT_REQ_CREDIT_BUREAU_DAY : numeric 24 | AMT_REQ_CREDIT_BUREAU_HOUR : numeric 25 | AMT_REQ_CREDIT_BUREAU_MON : numeric 26 | AMT_REQ_CREDIT_BUREAU_QRT : numeric 27 | AMT_REQ_CREDIT_BUREAU_WEEK : numeric 28 | AMT_REQ_CREDIT_BUREAU_YEAR : numeric 29 | APARTMENTS_AVG : numeric 30 | APARTMENTS_MEDI : numeric 31 | APARTMENTS_MODE : numeric 32 | BASEMENTAREA_AVG : numeric 33 | BASEMENTAREA_MEDI : numeric 34 | BASEMENTAREA_MODE : numeric 35 | CNT_CHILDREN : numeric 36 | CNT_FAM_MEMBERS : numeric 37 | CODE_GENDER : categorical 38 | COMMONAREA_AVG : numeric 39 | COMMONAREA_MEDI : numeric 40 | COMMONAREA_MODE : numeric 41 | DAYS_BIRTH : numeric 42 | DAYS_EMPLOYED : numeric 43 | DAYS_ID_PUBLISH : numeric 44 | DAYS_LAST_PHONE_CHANGE : numeric 45 | DAYS_REGISTRATION : numeric 46 | DEF_30_CNT_SOCIAL_CIRCLE : numeric 47 | DEF_60_CNT_SOCIAL_CIRCLE : numeric 48 | ELEVATORS_AVG : numeric 49 | ELEVATORS_MEDI : numeric 50 | ELEVATORS_MODE : numeric 51 | EMERGENCYSTATE_MODE : categorical 52 | ENTRANCES_AVG : numeric 53 | ENTRANCES_MEDI : numeric 54 | ENTRANCES_MODE : numeric 55 | EXT_SOURCE_1 : numeric 56 | EXT_SOURCE_2 : numeric 57 | EXT_SOURCE_3 : numeric 58 | FLAG_OWN_CAR : categorical 59 | FLAG_OWN_REALTY : categorical 60 | FLOORSMAX_AVG : numeric 61 | FLOORSMAX_MEDI : numeric 62 | FLOORSMAX_MODE : numeric 63 | FLOORSMIN_AVG : numeric 64 | FLOORSMIN_MEDI : numeric 65 | FLOORSMIN_MODE : numeric 66 | FONDKAPREMONT_MODE : categorical 67 | HOUSETYPE_MODE : categorical 68 | LANDAREA_AVG : numeric 69 | LANDAREA_MEDI : numeric 70 | LANDAREA_MODE : numeric 71 | LIVINGAPARTMENTS_AVG : numeric 72 | LIVINGAPARTMENTS_MEDI : numeric 73 | LIVINGAPARTMENTS_MODE : numeric 74 | LIVINGAREA_AVG : numeric 75 | LIVINGAREA_MEDI : numeric 76 | LIVINGAREA_MODE : numeric 77 | NAME_CONTRACT_TYPE : categorical 78 | NAME_EDUCATION_TYPE : categorical 79 | NAME_FAMILY_STATUS : categorical 80 | NAME_HOUSING_TYPE : categorical 81 | NAME_INCOME_TYPE : categorical 82 | NAME_TYPE_SUITE : categorical 83 | NONLIVINGAPARTMENTS_AVG : numeric 84 | NONLIVINGAPARTMENTS_MEDI : numeric 85 | NONLIVINGAPARTMENTS_MODE : numeric 86 | NONLIVINGAREA_AVG : numeric 87 | NONLIVINGAREA_MEDI : numeric 88 | NONLIVINGAREA_MODE : numeric 89 | OBS_30_CNT_SOCIAL_CIRCLE : numeric 90 | OBS_60_CNT_SOCIAL_CIRCLE : numeric 91 | OCCUPATION_TYPE : categorical 92 | ORGANIZATION_TYPE : categorical 93 | OWN_CAR_AGE : numeric 94 | REGION_POPULATION_RELATIVE : numeric 95 | TARGET : numeric 96 | TOTALAREA_MODE : numeric 97 | WALLSMATERIAL_MODE : categorical 98 | WEEKDAY_APPR_PROCESS_START : categorical 99 | YEARS_BEGINEXPLUATATION_AVG : numeric 100 | YEARS_BEGINEXPLUATATION_MEDI : numeric 101 | YEARS_BEGINEXPLUATATION_MODE : numeric 102 | YEARS_BUILD_AVG : numeric 103 | YEARS_BUILD_MEDI : numeric 104 | YEARS_BUILD_MODE : numeric 105 | FLAG_CONT_MOBILE : boolean 106 | FLAG_DOCUMENT_10 : boolean 107 | FLAG_DOCUMENT_11 : boolean 108 | FLAG_DOCUMENT_12 : boolean 109 | FLAG_DOCUMENT_13 : boolean 110 | FLAG_DOCUMENT_14 : boolean 111 | FLAG_DOCUMENT_15 : boolean 112 | FLAG_DOCUMENT_16 : boolean 113 | FLAG_DOCUMENT_17 : boolean 114 | FLAG_DOCUMENT_18 : boolean 115 | FLAG_DOCUMENT_19 : boolean 116 | FLAG_DOCUMENT_2 : boolean 117 | FLAG_DOCUMENT_20 : boolean 118 | FLAG_DOCUMENT_21 : boolean 119 | FLAG_DOCUMENT_3 : boolean 120 | FLAG_DOCUMENT_4 : boolean 121 | FLAG_DOCUMENT_5 : boolean 122 | FLAG_DOCUMENT_6 : boolean 123 | FLAG_DOCUMENT_7 : boolean 124 | FLAG_DOCUMENT_8 : boolean 125 | FLAG_DOCUMENT_9 : boolean 126 | FLAG_EMAIL : boolean 127 | FLAG_EMP_PHONE : boolean 128 | FLAG_MOBIL : boolean 129 | FLAG_PHONE : boolean 130 | FLAG_WORK_PHONE : boolean 131 | LIVE_CITY_NOT_WORK_CITY : boolean 132 | LIVE_REGION_NOT_WORK_REGION : boolean 133 | REG_CITY_NOT_LIVE_CITY : boolean 134 | REG_CITY_NOT_WORK_CITY : boolean 135 | REG_REGION_NOT_LIVE_REGION : boolean 136 | REG_REGION_NOT_WORK_REGION : boolean 137 | REGION_RATING_CLIENT : ordinal 138 | REGION_RATING_CLIENT_W_CITY : ordinal 139 | HOUR_APPR_PROCESS_START : ordinal 140 | 141 | 142 | 143 | bureau 144 | 145 | bureau (1716428 rows) 146 | 147 | SK_ID_BUREAU : index 148 | SK_ID_CURR : id 149 | CREDIT_ACTIVE : categorical 150 | CREDIT_CURRENCY : categorical 151 | DAYS_CREDIT : numeric 152 | CREDIT_DAY_OVERDUE : numeric 153 | DAYS_CREDIT_ENDDATE : numeric 154 | DAYS_ENDDATE_FACT : numeric 155 | AMT_CREDIT_MAX_OVERDUE : numeric 156 | CNT_CREDIT_PROLONG : numeric 157 | AMT_CREDIT_SUM : numeric 158 | AMT_CREDIT_SUM_DEBT : numeric 159 | AMT_CREDIT_SUM_LIMIT : numeric 160 | AMT_CREDIT_SUM_OVERDUE : numeric 161 | CREDIT_TYPE : categorical 162 | DAYS_CREDIT_UPDATE : numeric 163 | AMT_ANNUITY : numeric 164 | 165 | 166 | 167 | bureau->app 168 | 169 | 170 | SK_ID_CURR 171 | 172 | 173 | 174 | previous 175 | 176 | previous (1670214 rows) 177 | 178 | SK_ID_PREV : index 179 | SK_ID_CURR : id 180 | NAME_CONTRACT_TYPE : categorical 181 | AMT_ANNUITY : numeric 182 | AMT_APPLICATION : numeric 183 | AMT_CREDIT : numeric 184 | AMT_DOWN_PAYMENT : numeric 185 | AMT_GOODS_PRICE : numeric 186 | WEEKDAY_APPR_PROCESS_START : categorical 187 | HOUR_APPR_PROCESS_START : numeric 188 | FLAG_LAST_APPL_PER_CONTRACT : categorical 189 | RATE_DOWN_PAYMENT : numeric 190 | RATE_INTEREST_PRIMARY : numeric 191 | RATE_INTEREST_PRIVILEGED : numeric 192 | NAME_CASH_LOAN_PURPOSE : categorical 193 | NAME_CONTRACT_STATUS : categorical 194 | DAYS_DECISION : numeric 195 | NAME_PAYMENT_TYPE : categorical 196 | CODE_REJECT_REASON : categorical 197 | NAME_TYPE_SUITE : categorical 198 | NAME_CLIENT_TYPE : categorical 199 | NAME_GOODS_CATEGORY : categorical 200 | NAME_PORTFOLIO : categorical 201 | NAME_PRODUCT_TYPE : categorical 202 | CHANNEL_TYPE : categorical 203 | SELLERPLACE_AREA : numeric 204 | NAME_SELLER_INDUSTRY : categorical 205 | CNT_PAYMENT : numeric 206 | NAME_YIELD_GROUP : categorical 207 | PRODUCT_COMBINATION : categorical 208 | DAYS_FIRST_DRAWING : numeric 209 | DAYS_FIRST_DUE : numeric 210 | DAYS_LAST_DUE_1ST_VERSION : numeric 211 | DAYS_LAST_DUE : numeric 212 | DAYS_TERMINATION : numeric 213 | NFLAG_LAST_APPL_IN_DAY : boolean 214 | NFLAG_INSURED_ON_APPROVAL : boolean 215 | 216 | 217 | 218 | previous->app 219 | 220 | 221 | SK_ID_CURR 222 | 223 | 224 | 225 | bureau_balance 226 | 227 | bureau_balance (27299925 rows) 228 | 229 | bureaubalance_index : index 230 | SK_ID_BUREAU : id 231 | MONTHS_BALANCE : numeric 232 | STATUS : categorical 233 | 234 | 235 | 236 | bureau_balance->bureau 237 | 238 | 239 | SK_ID_BUREAU 240 | 241 | 242 | 243 | cash 244 | 245 | cash (10001358 rows) 246 | 247 | cash_index : index 248 | SK_ID_PREV : id 249 | MONTHS_BALANCE : numeric 250 | CNT_INSTALMENT : numeric 251 | CNT_INSTALMENT_FUTURE : numeric 252 | NAME_CONTRACT_STATUS : categorical 253 | SK_DPD : numeric 254 | SK_DPD_DEF : numeric 255 | 256 | 257 | 258 | cash->previous 259 | 260 | 261 | SK_ID_PREV 262 | 263 | 264 | 265 | installments 266 | 267 | installments (13605401 rows) 268 | 269 | installments_index : index 270 | SK_ID_PREV : id 271 | NUM_INSTALMENT_VERSION : numeric 272 | NUM_INSTALMENT_NUMBER : numeric 273 | DAYS_INSTALMENT : numeric 274 | DAYS_ENTRY_PAYMENT : numeric 275 | AMT_INSTALMENT : numeric 276 | AMT_PAYMENT : numeric 277 | 278 | 279 | 280 | installments->previous 281 | 282 | 283 | SK_ID_PREV 284 | 285 | 286 | 287 | credit 288 | 289 | credit (3840312 rows) 290 | 291 | credit_index : index 292 | SK_ID_PREV : id 293 | MONTHS_BALANCE : numeric 294 | AMT_BALANCE : numeric 295 | AMT_CREDIT_LIMIT_ACTUAL : numeric 296 | AMT_DRAWINGS_ATM_CURRENT : numeric 297 | AMT_DRAWINGS_CURRENT : numeric 298 | AMT_DRAWINGS_OTHER_CURRENT : numeric 299 | AMT_DRAWINGS_POS_CURRENT : numeric 300 | AMT_INST_MIN_REGULARITY : numeric 301 | AMT_PAYMENT_CURRENT : numeric 302 | AMT_PAYMENT_TOTAL_CURRENT : numeric 303 | AMT_RECEIVABLE_PRINCIPAL : numeric 304 | AMT_RECIVABLE : numeric 305 | AMT_TOTAL_RECEIVABLE : numeric 306 | CNT_DRAWINGS_ATM_CURRENT : numeric 307 | CNT_DRAWINGS_CURRENT : numeric 308 | CNT_DRAWINGS_OTHER_CURRENT : numeric 309 | CNT_DRAWINGS_POS_CURRENT : numeric 310 | CNT_INSTALMENT_MATURE_CUM : numeric 311 | NAME_CONTRACT_STATUS : categorical 312 | SK_DPD : numeric 313 | SK_DPD_DEF : numeric 314 | 315 | 316 | 317 | credit->previous 318 | 319 | 320 | SK_ID_PREV 321 | 322 | 323 | 324 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | bokeh>=1.0.2 2 | dask>=1.0.0 3 | distributed>=1.25.1 4 | featuretools>=0.10.1 5 | ipython>=5.8.0 6 | jupyter>=1.0.0 7 | lightgbm>=2.2.2 8 | matplotlib>=2.2.3 9 | psutil>=5.4.8 10 | pyarrow>=0.11.1 11 | scikit-learn>=0.20.2 12 | seaborn>=0.9.0 13 | tsfresh>=0.11.1 14 | umap-learn>=0.3.7 15 | graphviz>=0.10.1 16 | --------------------------------------------------------------------------------