《Python金融大数据风控建模实战》 第8章 Logistic回归模型

16 篇文章 53 订阅
15 篇文章 0 订阅

《Python金融大数据风控建模实战》 第8章 Logistic回归模型

本章引言

Logistic回归是建立评分卡模型最常用的方法,因其具有输出概率、可解释性好和模型参数少等优势,即使在其他各种机器学习算法突飞猛进的情况下,也仍然是工业界建立评分卡模型的主流方法,其模型表现也常作为参考标准,用于衡量其他机器学习模型的效果。

Python代码实现及注释

# 8章:logistic回归模型

import os
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
import variable_bin_methods as varbin_meth
import variable_encode as var_encode
from sklearn.metrics import confusion_matrix,recall_score,accuracy_score,precision_score
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
import warnings
warnings.filterwarnings("ignore") ##忽略警告
##数据读取
def data_read(data_path,file_name):
    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 = columns
    ##将标签变量由状态1,2转为0,1;0表示好用户,1表示坏用户
    df.target = df.target - 1
      ##数据分为data_train和 data_test两部分,训练集用于得到编码函数,验证集用已知的编码规则对验证集编码
    data_train, data_test = train_test_split(df, test_size=0.2, random_state=0,stratify=df.target)
    return data_train, data_test
##离散变量与连续变量区分   
def category_continue_separation(df,feature_names):
    categorical_var = []
    numerical_var = []
    if 'target' in feature_names:
        feature_names.remove('target')
    ##先判断类型,如果是int或float就直接作为连续变量
    numerical_var = list(df[feature_names].select_dtypes(include=['int','float','int32','float32','int64','float64']).columns.values)
    categorical_var = [x for x in feature_names if x not in numerical_var]
    return categorical_var,numerical_var
if __name__ == '__main__':
    path = 'D:\\code\\chapter8'
    data_path = os.path.join(path ,'data')
    file_name = 'german.csv'
    ##读取数据
    data_train, data_test = data_read(data_path,file_name)
    sum(data_train.target ==0)
    data_train.target.sum()
    ##区分离散变量与连续变量
    feature_names = list(data_train.columns)
    feature_names.remove('target')
    categorical_var,numerical_var = category_continue_separation(data_train,feature_names)
    for s in set(numerical_var):
        print('变量'+s+'可能取值'+str(len(data_train[s].unique())))
        if len(data_train[s].unique())<=10:
            categorical_var.append(s)
            numerical_var.remove(s)
            ##同时将后加的数值变量转为字符串
            index_1 = data_train[s].isnull()
            if sum(index_1) > 0:
                data_train.loc[~index_1,s] = data_train.loc[~index_1,s].astype('str')
            else:
                data_train[s] = data_train[s].astype('str')
            index_2 = data_test[s].isnull()
            if sum(index_2) > 0:
                data_test.loc[~index_2,s] = data_test.loc[~index_2,s].astype('str')
            else:
                data_test[s] = data_test[s].astype('str')

    ###连续变量分箱
    dict_cont_bin = {}
    for i in numerical_var:
        print(i)
        dict_cont_bin[i],gain_value_save , gain_rate_save = varbin_meth.cont_var_bin(data_train[i], data_train.target, method=2, 
                                                  mmin=3, mmax=12,  bin_rate=0.01, stop_limit=0.05, bin_min_num=20)
    ###离散变量分箱
    dict_disc_bin = {}
    del_key = []
    for i in categorical_var:
        dict_disc_bin[i],gain_value_save , gain_rate_save ,del_key_1 = varbin_meth.disc_var_bin(data_train[i], data_train.target, method=2, mmin=3,
                                     mmax=8, stop_limit=0.05, bin_min_num=20)
        if len(del_key_1)>0 :
            del_key.extend(del_key_1)
      
    ###删除分箱数只有1个的变量
    if len(del_key) > 0:
        for j in del_key:
            del dict_disc_bin[j]
    
    ##训练数据分箱
    ##连续变量分箱映射
    df_cont_bin_train = pd.DataFrame()
    for i in dict_cont_bin.keys():
        df_cont_bin_train = pd.concat([ df_cont_bin_train , varbin_meth.cont_var_bin_map(data_train[i], dict_cont_bin[i]) ], axis = 1)
    ##离散变量分箱映射
#    ss = data_train[list( dict_disc_bin.keys())]
    df_disc_bin_train = pd.DataFrame()
    for i in dict_disc_bin.keys():
        df_disc_bin_train = pd.concat([ df_disc_bin_train , varbin_meth.disc_var_bin_map(data_train[i], dict_disc_bin[i]) ], axis = 1)

  
    ##测试数据分箱
    ##连续变量分箱映射
    df_cont_bin_test = pd.DataFrame()
    for i in dict_cont_bin.keys():
        df_cont_bin_test = pd.concat([ df_cont_bin_test , varbin_meth.cont_var_bin_map(data_test[i], dict_cont_bin[i]) ], axis = 1)
    ##离散变量分箱映射
#    ss = data_test[list( dict_disc_bin.keys())]
    df_disc_bin_test = pd.DataFrame()
    for i in dict_disc_bin.keys():
        df_disc_bin_test = pd.concat([ df_disc_bin_test , varbin_meth.disc_var_bin_map(data_test[i], dict_disc_bin[i]) ], axis = 1)
    
    ###组成分箱后的训练集与测试集
    df_disc_bin_train['target'] = data_train.target
    data_train_bin = pd.concat([df_cont_bin_train,df_disc_bin_train],axis=1)
    df_disc_bin_test['target'] = data_test.target
    data_test_bin = pd.concat([df_cont_bin_test,df_disc_bin_test],axis=1)

    data_train_bin.reset_index(inplace=True,drop=True)
    data_test_bin.reset_index(inplace=True,drop=True)
    
    ###WOE编码
    var_all_bin = list(data_train_bin.columns)
    var_all_bin.remove('target')
    ##训练集WOE编码
    df_train_woe, dict_woe_map, dict_iv_values ,var_woe_name = var_encode.woe_encode(data_train_bin,data_path,var_all_bin, data_train_bin.target,'dict_woe_map', flag='train')
    ##测试集WOE编码
    df_test_woe, var_woe_name = var_encode.woe_encode(data_test_bin,data_path,var_all_bin, data_test_bin.target, 'dict_woe_map',flag='test')

    ####取出训练数据与测试数据
    x_train = df_train_woe[var_woe_name]
    x_train = np.array(x_train)
    y_train = np.array(data_train_bin.target)
    
    x_test = df_test_woe[var_woe_name]
    x_test = np.array(x_test)
    y_test = np.array(data_test_bin.target)
        
   
    ########logistic模型
    ##设置优化参数
    lr_param = {'C': [0.01, 0.1, 0.2, 0.5, 1, 1.5, 2],
                'class_weight': [{1: 1, 0: 1}, {1: 2, 0: 1}, {1: 3, 0: 1}]}
    ##初始化网格搜索
    lr_gsearch = GridSearchCV(
        estimator=LogisticRegression(random_state=0, fit_intercept=True, penalty='l2', solver='saga'),
        param_grid=lr_param, cv=3, scoring='f1', n_jobs=-1, verbose=2)
    ##执行超参数优化
    lr_gsearch.fit(x_train, y_train)
    '''
    上述网格搜索中有两个超参数,第一个超参数有7种可能性取值,第二个超参数有3种可能性取值,采用2折交叉验证,则总共经历7×3×3=63
    模型训练与评估,即每种参数组合都要通过交叉验证的方式得到评估指标的平均结果,即在3折交叉数据中的2折数据上建模,在另1折数据集上
    测试得到评估指标结果,将平均评估指标最好的的那组参数组合作为最优超参数。
    '''
    print('logistic model best_score_ is {0},and best_params_ is {1}'.format(lr_gsearch.best_score_,
                                                                             lr_gsearch.best_params_))
    
    ##用最优参数,初始化Logistic模型
    '''
    这里采用scikit-learn中linear-model模型下的LogisticRegression()函数进行Logistic回归模型训练,其原型如下:
    class sklearn.linear_model.LogisticRegression(penalty='l2', dual= False,tol=0.0001,C=1.0, fit_intercept=True,intercept_scaling=1,
    class_weight=None,random_state=None,solver='warn', max_iter=100, multi_class = 'warn',verbose=0, warm_start=False, n_jobs=None,l1_ratio=None)
    主要参数说明:
        penalty:选择使用哪种正则项来抑制过拟合,为字符串,可以为None、'l1''l2''elasticnet',不同的正则项可选的优化策略不同,
                 默认为'l2',即使用L2正则,如果为None,则表示不加正则项
        dual:布尔量,是否使用对偶形式,只能在L2正则且求解方式为liblinear solver才可以使用
        tol:指定模型迭代收敛的阈值
        C:正则项的惩罚系数。C=1/λ,因此C与实际作用在模型的惩罚成反比。即C越大,对正则项的惩罚效果越小,模型越容易过拟合,反之,
           C越小,对正则项的惩罚效果越大,模型越容易过拟合
        fit_intercept:模型训练时是否添加截距项,即w0。默认为True,即添加截距项。
        class_weight:确定是否加权来抑制样本不均衡,可以为字典形式的加权也可以自动加权。当设置为'balanced'时,则按照正负样本的比例加权。
                      如果需要自定义加权,可以采用字典的形式,如{'1':3,'0':1}即正样本的权重为3,负样本的权重为1。通过影响损失函数
                      的计算来抑制样本不均衡问题。默认为None即不加权,正负样本的权重相同。
        random_state:随机数设置,可以固定训练集,方便多个算法在同一个训练集上训练并比较模型的性能。
        solver:字符串,用于选择不同的优化算法。
        max_iter:整数,模型优化最大迭代次数。
    主要属性说明:
        coef_:用于查询模型训练后最终的权重系数,其数量与特征数相同,即每个特征训练一个权重。
        intercept_:用于查看截距项
        n_iter_:返回模型训练实际的迭代次数
    主要方法说明:
        fit(self,X,y[,sample_weight]):用于模型训练,在训练集上训练模型
        perdict(self,X):用于模型训练,在测试集上得到预测结果,这里给出标签输出,即0,1输出。
        predict_proba(self,X):用于模型预测。与perdict()方法不同的是,该方法给出概率预测结果,如ROC曲线就需要模型提供概率输出才可以进行计算
    '''
    LR_model_2 = LogisticRegression(C=lr_gsearch.best_params_['C'], penalty='l2', solver='saga',
                                    class_weight=lr_gsearch.best_params_['class_weight'])
    ##训练Logistic模型
    LR_model_fit = LR_model_2.fit(x_train, y_train)
    
    ##模型预测
    y_score_train = LR_model_fit.predict_proba(x_train)[:, 1]
    y_score_test = LR_model_fit.predict_proba(x_test)[:, 1]
  
    ##计算混淆矩阵与recall、precision
    y_pred = LR_model_fit.predict(x_test)
    cnf_matrix = confusion_matrix(y_test, y_pred)
    recall_value = recall_score(y_test, y_pred)
    precision_value = precision_score(y_test, y_pred)
    acc = accuracy_score(y_test, y_pred)
    print(cnf_matrix)
    print('Validation set:  model recall is {0},and percision is {1}'.format(recall_value,
                 precision_value)) 
  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 可以使用scikit-learn库中的LogisticRegression类来实现logistic回归模型。举个例子: ```python from sklearn.linear_model import LogisticRegression import numpy as np X = np.array([[1, 2], [3, 4], [5, 6]]) y = np.array([0, 1, 1]) log_reg = LogisticRegression() log_reg.fit(X, y) ``` 在上面的代码中,我们首先导入了LogisticRegression类和numpy库, 然后定义训练数据X和标签y.最后,我们实例化一个LogisticRegression对象并使用fit()方法来训练模型。 ### 回答2: Logistic回归是一种机器学习算法,主要用于二元分类问题,例如判断邮件是垃圾邮件还是非垃圾邮件。在Logistic回归模型中,通过建立一个或多个自变量和一个二元的因变量之间的关系,来预测新样本的分类。它的理论基础是极大似然估计。 在Python中,我们可以使用scikit-learn库来实现Logistic回归模型。以下是实现Logistic回归模型的步骤: 1. 导入相关库: ```python from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score ``` 2. 导入数据并拆分为训练集和测试集: ```python X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) ``` 其中,X为特征数据,而y为目标数据,test_size表示测试集所占的比例,random_state表示随机种子。 3. 创建Logistic回归模型并拟合训练数据: ```python logistic_model = LogisticRegression() logistic_model.fit(X_train, y_train) ``` 4. 使用测试数据进行预测: ```python y_pred = logistic_model.predict(X_test) ``` 5. 使用accuracy_score函数计算模型的精度: ```python accuracy = accuracy_score(y_test, y_pred) print('Accuracy:', accuracy) ``` 通过以上步骤便可以实现一个简单的Logistic回归模型。需要注意的是,在使用Logistic回归模型时,应该进行特征缩放和特征选择等操作,以便提高模型的预测准确度。 ### 回答3: Logistic回归模型是一种经典的分类模型,被广泛应用于机器学习和统计学领域。Python提供了丰富的库和工具来实现Logistic回归模型,使得该模型的实现变得简单、高效。在Python当中,可以使用Scikit-Learn、Statsmodels等库来实现Logistic回归模型。 首先,将数据集导入Python环境,并进行基本的数据预处理。可以使用Pandas库对数据集进行加载、清理和转换。在数据预处理之后,需要将数据集分为训练集和测试集。 然后,需要使用适当的Python库来建立Logistic回归模型。可以使用Scikit-Learn库的LogisticRegression类,它提供了一些重要的参数,例如正则化因子、优化算法、收敛模式等等。在建立模型之前,需要先定义目标变量和自变量。在参数拟合之后,可以使用该模型来预测和评估数据。 最后,需要进行模型评估和验证。通常使用一些指标来评估模型预测性能,例如精度、准确率、召回率、F1分数等等。可以使用混淆矩阵、ROC曲线、AUC值等来衡量模型的分类性能。 总之,Python提供了一种强大而通用的方法来实现Logistic回归模型。该模型可以发现变量之间的关系,并预测每个样本的分类。此外,Logistic回归模型还可以认为是其他分类模型的基础,例如支持向量机、神经网络等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值