Porto Seguro’s Safe Driver Prediction
这是Kaggle在9月30日开启的一个新的比赛,举办者是巴西最大的汽车与住房保险公司之一:Porto Seguro。该比赛要求参赛者根据汽车保单持有人的数据建立机器学习模型,分析该持有人是否会在次年提出索赔。比赛所提供的数据均已进行处理,由于数据特征没有实际意义,因此无法根据常识或业界知识简单地进行特征工程。
1.数据准备
首先,加载必要的包:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold
import xgboost as xgb
import seaborn as sns
读入数据,需要注意的是,由于举办方将缺失值全部设置为-1,因此,在读入数据的时候,要添加参数na_values=-1,以重新确定缺失值的所在。
##读入数据,并取得特征:
train = pd.read_csv("D:\CZM\Kaggle\data\\train.csv",na_values = -1)
test = pd.read_csv("D:\CZM\Kaggle\data\\test.csv",na_values = -1)
2.探索性数据分析(EDA)-数据总体
本部分将对数据总体进行探索性分析,从中提取有用的总体信息。
2.1 从特征列名中提取信息
首先,查看一下数据的规模:
In [13]: len(train)
Out[13]: 595212
In [14]: len(train.columns)
Out[14]: 59
In [15]: len(test)
Out[15]: 892816
In [16]: len(test.columns)
Out[16]: 58
我们发现,训练集中有595212个样本,测试集有892816个样本,这是数据集的基本规模。
另外,测试集中有58列,训练集中有59列,这是由于测试集中不包含需要预测的目标变量。
接下来,查看一下测试集具体有哪些列:
In [34]: train.columns
Out[34]:
Index(['id', 'target', 'ps_ind_01', 'ps_ind_02_cat', 'ps_ind_03',
'ps_ind_04_cat', 'ps_ind_05_cat', 'ps_ind_06_bin', 'ps_ind_07_bin',
'ps_ind_08_bin', 'ps_ind_09_bin', 'ps_ind_10_bin', 'ps_ind_11_bin',
'ps_ind_12_bin', 'ps_ind_13_bin', 'ps_ind_14', 'ps_ind_15',
'ps_ind_16_bin', 'ps_ind_17_bin', 'ps_ind_18_bin', 'ps_reg_01',
'ps_reg_02', 'ps_reg_03', 'ps_car_01_cat', 'ps_car_02_cat',
'ps_car_03_cat', 'ps_car_04_cat', 'ps_car_05_cat', 'ps_car_06_cat',
'ps_car_07_cat', 'ps_car_08_cat', 'ps_car_09_cat', 'ps_car_10_cat',
'ps_car_11_cat', 'ps_car_11', 'ps_car_12', 'ps_car_13', 'ps_car_14',
'ps_car_15', 'ps_calc_01', 'ps_calc_02', 'ps_calc_03', 'ps_calc_04',
'ps_calc_05', 'ps_calc_06', 'ps_calc_07', 'ps_calc_08', 'ps_calc_09',
'ps_calc_10', 'ps_calc_11', 'ps_calc_12', 'ps_calc_13', 'ps_calc_14',
'ps_calc_15_bin', 'ps_calc_16_bin', 'ps_calc_17_bin', 'ps_calc_18_bin',
'ps_calc_19_bin', 'ps_calc_20_bin'],
dtype='object')
这里显示出了train数据集的列名,根据以上内容以及比赛举办方提供的数据说明,我们能够提取出的信息如下:
- 除去作为唯一标识的ID列以及target列之外,特征列共有57列。
- 特征列的列名结构是统一的,共有被下划线分割开来的四层词缀:第一层词缀是所有特征列都有的ps,不需要关注;第二层词缀有ind、reg、car、calc四个类别;第三层词缀是单纯的编号;而第四层词缀有bin、cat两个种类,需要注意的是,不是所有的特征列都具有第四层词缀的。
- 根据举办方给出的数据说明,第四层词缀标注的是特征的变量类型,cat为多分类变量,bin为二分类变量,无词缀则属于连续或顺序变量;而第二层词缀则是变量名称,Ind是与司机个人相关的特征,reg是地区相关的特征,car是汽车相关的特征,calc则是其他通过计算或估计得到的特征。第三层词缀虽然官方没有明说,但应该是每个变量名称下的变量编号。
因此,我们可以根据特征名称,对所有特征列归类:
calccol = [];carcol = [];indcol = [];regcol = [];
col = train.columns;lencol = len(col)
for i in range(lencol):
st = col[i]
if st.find('car') != -1:
carcol.append(st)
else:
if st.find('calc')!= -1:
calccol.append(st)
else:
if st.find('ind')!= -1:
indcol.append(st)
else:
if st.find('reg')!= -1:
regcol.append(st)
##把每种类型的列归类,会有意义的
bincol = [];catcol = [];othercol = []
for i in range(lencol):
st = col[i]
if st.find('bin') != -1:
bincol.append(st)
else:
if st.find('cat') != -1:
catcol.append(st)
else:
if (st != 'target') and (st != 'id'):
othercol.append(st)
然后,对所有数据列的数据类型归纳为下表:
特征列名 | 特征名 | 特征后缀 | 变量类型 |
---|---|---|---|
ps_ind_01 | ind | 无 | 连续或顺序变量 |
ps_ind_02_cat | ind | cat | 分类变量 |
ps_ind_03 | ind | 无 | 连续或顺序变量 |
ps_ind_04_cat | ind | cat | 分类变量 |
ps_ind_05_cat | ind | cat | 分类变量 |
ps_ind_06_bin | ind | bin | 0-1变量 |
ps_ind_07_bin | ind | bin | 0-1变量 |
ps_ind_08_bin | ind | bin | 0-1变量 |
ps_ind_09_bin | ind | bin | 0-1变量 |
ps_ind_10_bin | ind | bin | 0-1变量 |
ps_ind_11_bin | ind | bin | 0-1变量 |
ps_ind_12_bin | ind | bin | 0-1变量 |
ps_ind_13_bin | ind | bin | 0-1变量 |
ps_ind_14_bin | ind | bin | 0-1变量 |
ps_ind_15_bin | ind | bin | 0-1变量 |
ps_ind_16_bin | ind | bin | 0-1变量 |
ps_ind_17_bin | ind | bin | 0-1变量 |
ps_ind_18_bin | ind | bin | 0-1变量 |
ps_car_01_cat | car | cat | 分类变量 |
ps_car_02_cat | car | cat | 分类变量 |
ps_car_03_cat | car< |