《Python金融大数据风控建模实战》 第5章 变量编码方法

《Python金融大数据风控建模实战》 第5章 变量编码方法

本章引言

在机器学习中,样本、变量、标签、模型等概念会频繁出现,本章从变量角度给出实际应用中的处理方法。机器学习模型通常只能处理结构化数据,而非结构化数据要转化为结构化数据才可以用于模型训练。在机器学习中,变量、字段、属性、特征、输入、预测因子、自变量是同一个意思,样本、观测、实例、记录是同一个意思,结果、预测变量、输出、目标、因变量、响应、标签是同一个意思。
在统计学中,将变量按照取值是否连续分为离散变量和连续变量。有时离散变量是字符串类型,而建模中的预测模型绝大多数只能对数值类型进行建模分析(CatBoost模型可以直接对类别变量建模)。因此,为了让模型可以正常运行,必须要提前对离散变量进行编码转换,以进行数值化,其原则是保证编码后变量的距离可计算且符合原始变量之间的距离测量。

Python代码实现及注释

# 5 变量编码

'''
变量编码:one-hot编码、标签编码、自定义字典映射、woe编码
程序的运行逻辑是:数据读取—>划分训练集与测试集—>训练集变量编码—>保存编码规则—>测试集变量编码
需要用到的Python包有:Pandas包、scikit-learn包和Pickle包,用到的函数如下:
    data_read ():用于读取数据
    onehot_encode():One-hot编码函数
    label_encode():标签编码函数
    dict_encode():自定义映射函数,用于有序变量编码
    woe_encode():WOE编码函数
'''

'''
os是Python环境下对文件,文件夹执行操作的一个模块
pickle可以把字典、列表等结构化数据存到本地文件,读取后返回的还是字典、列表等结构化数据。而file.write、file.read存取的对象是字符串。
本章使用的OneHotEncoder、LabelEncoder来自sklearn.preprocessing,train_test_split来自sklearn.model_selection
'''
import os
import pandas as pd
import numpy as np
import pickle
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
import warnings
warnings.filterwarnings("ignore") # 忽略警告
# 注意sklearn版本要在v.20.0以上,不同版本函数的位置会不同。

def data_read(data_path,file_name):
    '''
    csv文件是一种用,和换行符区分数据记录和字段的一种文件结构,可以用excel表格编辑,也可以用记事本编辑,是一种类excel的数据存
    储文件,也可以看成是一种数据库。pandas提供了pd.read_csv()方法可以读取其中的数据并且转换成DataFrame数据帧。python的强大
    之处就在于他可以把不同的数据库类型,比如txt/csv/.xls/.sql转换成统一的DataFrame格式然后进行统一的处理。真是做到了标准化。
    pd.read_csv()函数参数:
        os.path.join()函数:连接两个或更多的路径名组件
        sep:如果不指定参数,则会尝试使用逗号分隔。
        delimiter :定界符,备选分隔符(如果指定该参数,则sep参数失效)
        delim_whitespace  指定空格是否作为分隔符使用,等效于设定sep=\s+’。如果这个参数设定为True那么delimiter 参数失效。
        header :指定行数用来作为列名,数据开始行数。如果文件中没有列名,则默认为0【第一行数据】,否则设置为None。
    '''
    df = pd.read_csv( os.path.join(data_path, file_name), delim_whitespace = True, header = None )

    ##变量重命名
    columns = ['status_account','duration','credit_history','purpose', 'amount',
               'svaing_account', 'present_emp', 'income_rate', 'personal_status',
               'other_debtors', 'residence_info', 'property', 'age',
               'inst_plans', 'housing', 'num_credits',
               'job', 'dependents', 'telephone', 'foreign_worker', 'target']

    '''
    修改列名的两种方式为:
        直接使用df.columns的方式重新命名,不过这种方式需要列出所有列名。
        使用rename方法,注意如果需要原地修改需要带上inplace=True的参数,否则原dataframe列名不会发生改变。
    '''
    df.columns = columns

    ##将标签变量由状态1,2转为0,1;0表示好用户,1表示坏用户
    df.target = df.target - 1

    '''
    数据分为data_train和 data_test两部分,训练集用于得到编码函数,验证集用已知的编码规则对验证集编码。
    这里是采用的是scikit-learn的model_selection模块中的train_test_split()函数实现数据切分,函数原型为:
        sklearn.model_selection.train_test_split(*arrays, **options)
    主要参数说明:
        arrays:为需要切分的原始数据,可以是列表、Numpy arrays、稀疏矩阵、pandas的数据框。
        test_size:划分的测试数据的占比,为0-1的数,默认为0.25,即训练数据为原始数据的75%,测试数据为原始数据的25%
        train_size:与test_size设置一个参数即可,并满足加和为1的关系。
        random_state:随机数设置,可以保证每次切分得到的数据是相同的,这样在比较不用算法的性能时更加严谨,保证了数据集的一致性。
                     如果不设置,每次将随机选择随机数,产生不同的切分结果。  
        shuffle:是否在切分前打乱数据原有的顺序,默认为进行随机洗牌。
        stratify:设置是否采用分层抽样,默认为none,不分层。分层抽样可以保证正负样本的比例与原始的数据集一致。如果设置为none,
                  则切分时采用随机采样方式。如果需要进行分层采样,则需要指定按哪个变量分层,一般按照标签进行采样。  
                  如在本程序中,使用target标签进行采样。
    '''
    data_train, data_test = train_test_split(df, test_size=0.2, random_state=0,stratify=df.target)

    return data_train, data_test

# one—hot编码
def onehot_encode(df,data_path_1,flag='train'):

    '''
    reset_index()函数中,drop=True: 把原来的索引index列去掉,丢掉;drop=False:保留原来的索引(以前的可能是乱的)
    inplace=True:不创建新的对象,直接对原始对象进行修改;
    inplace=False:对数据进行修改,创建并返回新的对象承载其修改结果。
    '''
    df = df.reset_index(drop=True)

    # 判断数据集是否存在缺失值
    '''
    Python pandas判断缺失值一般采用 isnull(),然而生成的却是所有数据的truefalse矩阵,对于庞大的数据dataframe,很难一眼看出
    来哪个数据缺失,一共有多少个缺失数据,缺失数据的位置,而df.isnull().any()则会判断哪些”列”存在缺失值。
    下面这行代码表示有缺失值的列数大于0
    '''
    if sum(df.isnull().any()) > 0 :

        numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']

        '''
        pandas形成的dataframe数据集,如果有些列是数字,有些列是字母,或者有些是bool型,那么如果我们有时候只需要选取特定数据类
        型的列,例如:DataFrame.select_dtypes(include[‘int’], exclude=None)其中 include 包含的是需要获取的列的类型,exclude
        包含的不需要获取的数据类型
        '''
        var_numerics = df.select_dtypes(include=numerics).columns

        var_str = [ i for i in df.columns if i not in  var_numerics ]
        # 数据类型的缺失值用-7777填补
        if len(var_numerics) > 0:

            '''
            DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)
            函数功能:使用指定的方法填充NA / NaN值
            参数:
                value:变量,字典,Series,orDataFrame用于填充缺失值(例如0),或者指定为每个索引(对于Series)或列(对于DataFrame)
                      使用哪个字典/Serise/DataFrame的值。(不在字典/Series/DataFrame中的值不会被填充)这个值不能是一个列表。
                method:{
   ‘b
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值