案例及数据说明
本选题用到的数据包括公共数据集、用户通话数据、违约行为数据。
训练集数据:用户通话数据(201703-201706),违约行为数据(201707),公共数据-基本信息(201703-201706),公共数据-通话(20170528-20170628),公共数据-轨迹(20170528-20170628),公共数据-上网(20170528-20170628)。初赛只提供了7000条训练数据,需要自行组合训练集和测试集,去验证算法,由于训练数据较少,训练的模型稳定性不高,且可能出现过拟合的现象。
通信信用风险评估(是否违约),属于二分类问题,关键在于对基础数据的理解分析,做好特征工程,利用Python的sklearn包封装的算法模型进行模型选择、评估、调优。
基础数据读取
读取数据,利用pandas的read_csv
函数,结合通信信用风险评估这个选题的数据,实践过程中,有下面几点需要注意的地方。
# sys:1: DtypeWarning: Columns (7,30,31,35) have mixed types. Specify dtype option on import or set low_memory=False.
警告:列有混合的数据类型,故都强制转换为了object
,尝试了如下不同的思路处理这个警告信息。
强制设置dtype参数,dtype='unicode'
或者dtype='object'
,这种处理方式简单粗暴,但是这不是一个内存高效的方法,而且也会为后面的数据关联埋下一个大坑,读取DataTech_Credit_Train_Communication1.txt
和DataTech_Credit_Train_User1.txt
,没有设置dtype
,UseI_Id
默认为int64
类型,而读取DataTech_公共数据_基础信息1.txt
,设置了dtype='unicode'
,后期将这两个表关联时,死活关联不上,故放弃这种处理方式。
生成基于小样本的dtype设置,nrows=100
,获得小样本的dtypes
读取整个dataframe
,可以尝试try/except捕获错误的dtype
猜测。经过尝试,发现警告信息的这4列USER_CREDIT_ID
、ARPU
、SP_FEE
、FIST_USE_DATE
通过前100行猜测的数据类型为int64
,当用猜测的类型尝试读取整个dataframe
时,出现了如下报错信息。
ValueError: Integer column has NA values in column 36
通过查阅pandas的文档,发现The lack of NaN rep in integer columns is a pandas “gotcha”.
The usual workaround is to simply use floats.integer
不支持NA
,通常通过转换为float
解决。接下来即可以尝试强制设置这四列dtype
为float
,再次读取整个dataframe
(这一点没有继续尝试)。
设置na_values参数,在强制设置报警的四列的dtype
为float
时,是假设因为NA values导致报错ValueError
的,那么pandas的默认的NA values 设置包括哪些呢?是否需要添加自定义的NA values,如何正确添加自定义的NA values,自定义的设置是否会覆盖默认设置?以及针对不同的column设置不同的NA values?这也是值得下一步深入探讨的点。
Usage of converters,converters
在pandas中非常heavy,效率低下,因为read_csv
是单进程,故应该被用作最后的手段。CSV文件可以逐行处理,可把文件切片,运行多个进程,通过多个转换器并行处理,但这是另外一个课题了(暂时没有尝试)。使用converters
的过程中,也发现一个问题,converter
和dtype
的设置会有冲突,因此屏蔽了dtype
的设置,而且数据集里的\N
读取的时候是被当作字符串读取的,不是NA valuse(这一点目前还没理清楚),通过不断利用try/except的方式找到每一有报警信息的列的脏数据,发现有三类:\N
、''
、数据超过int64的范围,后面我也附上了自定义的converters
.
Parser Warning: Both a converter and dtype were specified for column AGE - only the converter will be used 'FIST_USE_DATE': conv})
def conv(val):
if val == '\N' or val == '':
return np.NaN
try:
return np.int64(val)
except:
return -1
大数据文件的读取
公共数据集里面有两个大数据文件:公共数据-轨迹(20170528-20170628)1.96G,公共数据-上网(20170528-20170628)1.56G。作为只有4G内存的乞丐机处理起来还是有点难度,关于大数据文件的处理也是一个值得深究的点。
初看选题三的数据字典,开始还认为数据的读取应该是so easy的,但在实践过程中,还是踏入了不少的坑,爬出来也不容易啊。
附1:read_csv
函数的常见参数
参数 | 说明 |
path | 文件系统位置、URL、文件型对象的字符串 |
sep或delimiter | 对行中各字段进行拆分的字符序列或正则表达式 |
header | 用作列名的行号,默认为0(第一行),如果没有header行设置为None |
names | 设置列名列表,结合header=None |
na_values | 用于替换(覆盖默认值?)NA的值 |
converters | 由列号/列名跟函数之间的映射关系组成的字典。如{‘foo’: f}会对foo列的所有值应用函数f |
nrows | 需要读取的行数 |