逻辑回归

简介: 逻辑回归

@TOC

1 应用场景

逻辑回归被广泛应用在目标变量是二值变量的场合 (0, 1)

2 公式

– P(y=1|x) 表示 y = 1的概率
– 从而得到 y = 1 对 y = 0 概率的比值

3 模型估计

– 极大似然估计
在这里插入图片描述
模型阐释/评估
– 一个解释变量的阐释图
在这里插入图片描述

4 读取与整理数据

整理数据格式,将数值变量和因子变量分类

data0=read.csv("accepts.csv",na.strings = "",colClasses = newcolclass)
str(data0)
nrow(data0)
summary(data0)
#定义目标角色
target0="bad_ind"
colclass=sapply(data0,class)
newcolclass=ifelse(colclass=="character","factor","numeric")

#找出data0中变量时numeric的名称
numerics=names(which(sapply(data0,is.numeric)))
length(numerics)

#找出data0是factor的变量名称,集合的差
factors=setdiff(names(which(sapply(data0,is.factor))),target0)
length(factors)

5 变量筛选

5.1集中度和分类数筛选

###取值集中在某一取值
maxper=sapply(data0, function(x) max(table(x)/length(x)))
summary(maxper)

centors=names(which(maxper>0.95))
#分类太多的可以考虑合并
maxperf=sapply(data0[,factors], function(x) max(table(x)/length(x)))
summary(maxperf)

5.2 缺失值分析

nanumber=sapply(data0,function(x) sum(is.na(x)))
summary(nanumber)

#查找大于80%的缺失值
missings3=names(which(nanumber>=0.7*nrow(data0)))

#查找大于50%的缺失值
missings2=names(which(nanumber>=0.5*nrow(data0)))

#查找大于30%的缺失值
missings1=names(which(nanumber>=0.3*nrow(data0)))

修改缺失值的值,数值型用中位数填补,因子型用众数填补

#修改数值型和因子型列缺失值
modifyna=function(x){
  for (i in 1:length(x)) {
    if(sum(is.na(data0[,i]>0))){
      if(class(data0[,i])=="numeric"){
      x[,i][is.na(x[,i])]=median(x[,i],na.rm = T)
      }else{
        a=table(x[,i])
        b=which(a==max(a))
        x[,i][is.na(x[,i])]=names(b)
      }
    }
  }
  x
}
data1=modifyna(data0)

填补后缺失值为0

在这里插入图片描述

#将y放在第一列
name=colnames(data1)
match("bad_ind",name)
data2=data1[,c(3,1:2,4:length(data1))]

5.3 频率筛选

#根据业务删除与y无关的

nrow(data2)
colname2=colnames(data2)
match(c("application_id","account_number"),colname2)
data3=data2[,c(-2,-3)]

对过多种类的分类变量进行处理


lvls=sapply(data2[factors],function(x) length(levels(x)))
summary(lvls)


manylvls=names(which(lvls>8))
manylvls
data2$vehicle_make
factors=setdiff(factors,manylvls)

*删除数值类型少的numeric变量,并把二分类变量变为logic因子变量

concret=names(which(lev!=2 & lev<30))
concret
#logic变量
logic=names(which(lev==2))
logic
data3[,logic]=as.data.frame(lapply(data3[,logic],as.factor))
colnames(data3)[2]="vehicle_year"

#确定第一次删除的变量

ignores=c(centors,missings3,manylvls,concret,target0)
input=setdiff(names(data3),ignores)

IV(信息价值)通常应用于评分模型,是基于WOE(证据权重)计算的,
反应的是单个自变量自身与因变量之间的关系,衡量自变量的预测能力,
是筛选变量参考的指标。

计算变量的IV值,ln(bad/good)*(bad-good)

x=data3$age_oldest_tr
target=data3[,1]
summary(x)

x=binning(x,bins=8,method="quantile")
temp1=table(x,target)
temp1

#频数统计表转化为数据框,矩阵的长度为水平的个数
temp2=as.data.frame(matrix(temp1,length(unique(x)),2))
length(unique(temp1))
#计算比例
temp3=as.data.frame(sapply(temp2, function(x) x/sum(x)))

#权重
woe=log(temp3[,2]/temp3[,1])*100
woe

#IV值
iv=sum((temp3[,2]-temp3[,1])*woe)

###自编函数
var.iv=function(x,target){
  if(is.numeric(x)){
    #分箱
    x=binning(x,bins=8,method = "quantile")
    #频数表
    x=table(x,target)
    #转列表
    x=as.data.frame(matrix(x,nrow(x),ncol(x)))
    #比例矩阵
   x=sapply(x,function(x) x/sum(x))
    if(!is.matrix(x)){Iv=0} else{
      #权重
      woe=log(x[,2]/x[,1])*100
      #IV值
      Iv=sum((x[,2]-x[,1])[!is.infinite(woe)]*woe[!is.infinite(woe)])
    }
   return(Iv)
  }
}

var.iv(data3[,12],target)

data4=data3[input]
class(data4)
#计算输入数据的IV值
iv.value=sapply(data4,function(x) var.iv(x,target))
IV=unlist(iv.value)
#增加IV等于0的为因子变量
factors=append(factors,"used_ind")
class(IV)
summary(IV)

#列表转向量
as.vector(unlist(iv.value))

#修改数据框某一列的数据类型
data4$used_ind=as.factor(data4$used_ind)

#选择IV大于10,bad和good差较大的变量
ninput=names(which(IV>10))
length(ninput)

对于分类型变量,也应该筛选IV>10比较合适,这里是为了后面逐步回归比较AIC值,选择大于1的IV值

fvar.iv=function(x,target){
  if(is.factor(x)){
    #分箱
    #频数表
    x=table(x,target)
    #转列表
    x=as.data.frame(matrix(x,nrow(x),ncol(x)))
    #比例矩阵
    x=sapply(x,function(x) x/sum(x))
    
      #权重
      woe=log(x[,2]/x[,1])*100
      #IV值
      fIv=sum((x[,2]-x[,1])[!is.infinite(woe)]*woe[!is.infinite(woe)])
      return(fIv)
    
  }
}
fvar.iv(data4[,1],target)

fiv.value=sapply(data4,function(x) fvar.iv(x,target))
Fiv=unlist(fiv.value)
class(Fiv)

###确定最终进入模型的变量

finput=names(which(Fiv>1))
input=append(ninput,finput)
data_input=data4[,input]
str(data_input)
summary(data_input)

###确定最终进入模型的变量

finput=names(which(Fiv>1))
input=append(ninput,finput)
data_input=data4[,input]
str(data_input)
summary(data_input)

#分割数据设置,训练集和测试集

set.seed(1)
n=nrow(data_input)
train_number=sample(1:n,round(n*0.8))

##构建训练集

train=data_input[train_number,]
train_y=target[train_number]

table(train_y)

test=data_input[-train_number,]
test_y=target[-train_number]

构建模型

logitfit=glm(train_y~.,data=train,family="binomial")
summary(logitfit)

coef(logitfit)

#系数的含义优势比的增加量
sapply(coef(logitfit), function(x) round(exp(x),3))
logitfitstep=step(logitfit)

logitfit=glm(train_y ~ age_oldest_tr + tot_rev_line + fico_score + ltv,data=train,family = "binomial")

通过逐步回归,选择能使AIC最小的变量进入模式

在这里插入图片描述

AIC,即赤池信息量准则,是衡量统计模型拟合优良性的一种标准。

●赤池信息量准则建立在熵的概念基础上,可以权衡所估计模型的复杂度和此模型拟合数据的优良性。

AIC= =2k- 2Ln(L)

其中k是模型参数个数,L是似然函数。通常选择AIC最小的模型为最优模型。

●当两个模型之间存在较大差异时,差异主要体现在似然函数项,当似然函数差异不显著时,上式第一项,即模型复杂度则起作用,从而参数个数少的模型是较好的选择。

BIC,即贝叶斯信息准则,与AIC相似,用于模型选择。

训练模型时,增加参数数量,也就是增加模型复杂度,会增大似然函数,但是也会导致过拟合现象,针对该问题,AIC和BIC均引入了与模型参数个数相关的惩罚项,BIC的惩罚项比AIC的大,考虑了样本数量,样本数量过多时,可有效防止模型精度过高造成的模型复杂度过高。

BIC= kLn(n)- 2Ln(L)

.. 其中,k为模型参数个数,n为样本数量,L为似然函数。kln(n)惩罚项在维数过大且训练样本数据相对较少的情况下,可以有效避免出现维度灾难现象。

6 对模型进行样本内外预测

library(gtools)
library(gmodels)

#样本内预测

logit_train_fit=fitted(logitfit)
summary(logit_train_fit)
summary(target)

###########################################样本外预测

logit_test_fit=predict(logitfit,newdata = test,type="response") #加responce输出是P,否则是y值
summary(logit_test_fit)
###########################################样本外预测

logit_test_fit=predict(logitfit,newdata = test,type="response") #加responce输出是P,否则是y值
summary(logit_test_fit)

#预测效果检验

##########################################逻辑分类-样本内
p=table(train_y)/length(train_y)

##以p[2]作为临界值划分
logit.cluster=factor(logit_train_fit>p[2],levels=c(F,T),labels=c(0,1))
table(logit.cluster)

#预测准确率
per.pre.train=table(train_y,logit.cluster,dnn=c("Actual","predicted"))
per.pre.train
p11=per.pre.train[2,2]/sum(per.pre.train[2,])
p11

p00=per.pre.train[1,1]/sum(per.pre.train[1,])
p00

accuracy=(per.pre.train[1,1]+per.pre.train[2,2])/sum(per.pre.train)
accuracy

分别查看11,00和总体的正确率

#######################################样本外
#p.pred=exp(logit_test_fit)/(1+exp(logit_test_fit)) 没有responce的概率处理
p.pred=logit_test_fit
summary(p.pred)

pt=table(test_y)/length(test_y)
pt
log(pt[2]/pt[1])
logit.pred=factor(p.pred>p[2],levels=c(F,T),labels=c("0","1"))
table(logit.pred)

#对比预测与真实值

table_pre.test=table(test_y,logit.pred,dnn = c("Actual","predicted"))
table_pre.test

pt11=table_pre.test[2,2]/sum(table_pre.test[2,])
pt11
pt00=table_pre.test[1,1]/sum(table_pre.test[1,])
pt00

accuracyp=(table_pre.test[1,1]+table_pre.test[2,2])/sum(table_pre.test)
accuracyp

在这里插入图片描述
这里的预测阈值采用的是训练集中1发生概率的阈值做比较,效果一般

7ROC曲线检验模型

#####################################预测效果检验
library(colorspace)
library(pROC)

modelroc=roc(test_y,logit_test_fit,plot=T)

plot(modelroc,print.auc=T,auc.polygon=T,grid=c(0.1,0.2),grid.col=c("green","red"),max.auc.polygon=T,auc.polygon.col="skyblue",print.thres=T)

modelauc=auc(modelroc)
modelauc

在这里插入图片描述

通过roc曲线可以选择最适合的阈值

目录
相关文章
WK
|
2月前
|
机器学习/深度学习 算法 数据挖掘
什么是逻辑回归分类器
逻辑回归分类器是一种广泛应用于二分类问题的统计方法,它基于线性组合并通过Sigmoid函数将输出映射为概率值进行分类。核心原理包括:线性组合假设函数、Sigmoid函数转换及基于概率阈值的预测。该模型计算高效、解释性强且鲁棒性好,适用于信用评估、医疗诊断、舆情分析和电商推荐等多种场景。利用现有机器学习库如scikit-learn可简化其实现过程。
WK
31 1
|
3月前
|
机器学习/深度学习 数据挖掘 C#
用C#实现简单的线性回归
用C#实现简单的线性回归
41 1
|
4月前
|
机器学习/深度学习
逻辑回归
【7月更文挑战第22天】逻辑回归
40 5
|
4月前
|
数据可视化 Python
数学方法解决线性回归问题
【7月更文挑战第21天】数学方法解决线性回归问题
45 2
|
4月前
什么是线性回归
【7月更文挑战第21天】什么是线性回归。
68 2
|
4月前
|
机器学习/深度学习 算法 数据挖掘
线性回归
【7月更文挑战第21天】线性回归。
58 1
|
5月前
|
机器学习/深度学习 存储 自然语言处理
逻辑回归的介绍和应用
**逻辑回归简介** 逻辑回归是一种分类模型,尽管名字含“回归”,实际上是用于二分类问题的。它简单易懂,计算高效,适用于许多领域,如医学、社会科学、市场营销等。优点是模型简单,易于实现,具有强解释性。然而,它易受多重共线性影响,可能欠拟合,分类精度有限,尤其对非线性问题和数据不平衡问题处理不佳。在实践中,逻辑回归常作为其他复杂算法的基线,如用于信用卡欺诈检测和点击率预测。通过调整和与其他技术结合,如GBDT,可以提升其性能。
|
机器学习/深度学习 存储 算法
逻辑回归模型
逻辑回归模型
129 0
|
机器学习/深度学习 API 算法框架/工具
二、逻辑回归
二、逻辑回归

相关实验场景

更多