R语言--数据挖掘2--数据理解与准备

数据理解与准备

数据理解

主要是理解数据,包括分析抽样偏差,数据粒度,数据得精确含义,变量类型,冗余变量,完整性,缺省值,数据链接。这里主要先查看数据,处理冗余变量,进行缺失值的分析等。

获取并查看数据:

首先读取bankloan.csv文件中的数据为数据框bankLoan,并且使用R语言中的summary(bankLoan)初步查看数据的位置分布特征。

library(dplyr)
library(purrr)
library(xlsx)

setwd("D:/lagua/CODING/R-learn/R-code/Chap2-DataPreparation")

bankLoan = read.csv("bankloan.csv", header=TRUE,
                     fileEncoding ="GBK")

colnames(bankLoan) = c("Age", "Edu", "WorkAge",
                       "Address", "Income",
                       "DebtRatio", "CreditDebt",
                       "OtherDebt", "Default")
# ----------------数据空值检查------------------
#----------列检查-----------
colnames(bankLoan)
length(colnames(bankLoan))

#----------行检查-----------
summary(bankLoan)

得到:
在这里插入图片描述
在这里插入图片描述


冗余变量:

在对原始数据的初步分析之后,发现数据中不存在一些变量可以由其他的变量推导出来,也即没有冗余变量,所以在冗余变量处理部分,不作任何的处理。


缺失值:

如上图所示的summary(bankLoan)得到的结果所示,变量没有缺省值,即数据是完整的,故在这一步也不对数据进行任何的处理。

数据准备

清除变量,处理分类自变量,处理时间变量,异常值,极值,数据分箱,缺失数据,降维,欠采样与过抽样

根据生活的经验,所有的变量,年龄、教育、工龄、地址、收入、负债率、信用卡负债、其它负债等自变量都与是否违约有关。所以初步判定所有变量都是有效的,不用清除。

以下根据统计理论进行进一步地分析。


数据属性与描述:

处理分类型变量

分类自变量的类型,包括分类自变量定序自变量

关于分类自变量而言,对于属性变量,最常用的转换是将该自变量转变成哑变量;对于定序自变量,将该变量的序号转换成数值自变量。

经过以上summary(bankLoan)以及对原始数据的初步分析知,地址是属性变量,所以使用as.factor将变量的类型转变成因子类型,即分类变量;教育是定序变量,所以首先将其排序,并且转换成整数型自变量;而对于剩下的年龄、工龄、收入、信用卡负债、其他负债自变量,全部都转换成数值型变量,而其中的年龄、工龄需要转变成整数型变量

使用R的实现代码如下:

# 调整数据框列的类型
bankLoan = bankLoan %>% 
  mutate_at(.vars = vars("Address"),
            .fun = as.factor) %>%
  mutate_at(.vars = vars("Age", "WorkAge", "Income", 
                      "DebtRatio","CreditDebt","OtherDebt"),
            .fun = as.numeric) %>%
  mutate_at(.vars = vars("Age", "Edu", "WorkAge"),
            .fun = as.integer)
查看数据描述

主要查看数据的分布,其中包括均值、标准差、最小值、下四分位数、中位数、上四分位数、最大值、缺失值的数量,得到:
在这里插入图片描述

异常值:

首先介绍一下异常值的影响,自变量中会因为很多的因素导致在收集数据的时候出现异常值,这些异常值的存在会影响我们的分析。尤其是在进行回归分析时,当出现一个距离大部分数据比较远的离群点。我们在进行模型拟合之前,如果不去除这些异常值的话,会将我们的回归模型往离群点处“拉”。所以在数据建模之前,在进行数据准备时,需要分析数据中异常值,以获得预测以及应用分析效果比较好的模型。

其次,对于异常值的探测,由于异常值一般是比较少的点,偏离主要的群体比较远的那些观测值。一般对于异常值的探测使用的方法根据维度一般分为以下几类:

1、一维

2、二维及以上

在一维下,对于异常值的检验主要有两种方法:直方图法箱线图法。其中直方图法,首先将我们的一维变量数据分组,对所有的数据都排序之后分组,计算数据落到每个组的频数,就可以得到直方图。直方图可以显示出原始数据的分布。

直方图法:一般情况下,如果数据没有异常数据的话,数据一般是比较集中的,而异常的数据往往距离中间的数据比较远,从直观上来看,数据在左边或者右边会产生“拖尾“的现象,我们需要处理的是这些”两边“的数据。由于在大数定律下,数据的分布满足
p ( ∣ X − μ ∣ < 2 σ ) = 95.44 % p({|X-\mu|}<2\sigma)=95.44\% p(Xμ<2σ)=95.44%
而且假设检验中的 α \alpha α的一般取值为0.05,所以控制正常数据落到 2 σ 2\sigma 2σ的范围之内是合理的。由此原理,我们将 2 σ 2\sigma 2σ之外的数据看作异常值。

箱线图法:箱线图主要是使用分位数来确定数据中是否有异常值。其中有50%的数据在箱子中,即(Q1,Q3)中,当数据超过上界 Q 3 + 1.5 Δ Q Q_3+1.5\Delta Q Q3+1.5ΔQ和下界 Q 3 − 1.5 Δ Q Q_3-1.5\Delta Q Q31.5ΔQ之后,使用圈来表示,这是异常值。

对于多维数据,分别有距离法、分类预测模型(聚类)、基于树模型法、基于密度法来识别数据。

距离法:当 d > 3 d>3 d>3或一个阈值之后,就认为这些数据是异常值。注:距离一般使用的是欧氏距离。

分类预测模型法:k-means,在最小化误差函数的基础上将数据划分为预定的类数 K K K. 在聚类完成之后,计算一个类中每个点到类的族中心的距离,如果超过某个阈值,就认为这个点是异常值点。

其次,是对异常值的处理

主要有四种方法:

  1. 删除含有异常值的记录
  2. 将异常值视为缺失值,最后跟缺失值一起处理。
  3. 使用平均值来修正
  4. 不处理

根据下面的直方图来看,数据的分布呈现出极值分布,对于年龄,没有异常值;对于教育分布,虽然在右边有一个拖尾的数据,但是这并不是异常的数据,因为在显示中贷款的人群中是存在少部分高学历人群的,这是正常的现象,并不是异常数据,故不对其进行处理;同上,我也认为工龄的分布右边的拖尾是正常的;同理,收入、负债率、信用卡负债、其他负债的右边拖尾数据的存在是非常正常的。又因为在实际中存在有这种看似”异常“的数据,我们可以更加关注他们,对于是否给予他们贷款,需要具体情况具体分析,这就是不是仅仅剔除异常值,或者使用上面包含的四种方法的任意一种方法来处理的。在这些异常值中,我们需要单独拿出这些更加细致地根据具体情况分析,而不是在数据挖掘的初期就剔除这些异常值

综上,在异常值处理部分,先不对数据进行预处理。


极值处理:

**极值化:**实际数据中自变量或因变量的分布会呈现出偏斜有极值的现象,例如下图所示的图4 收入就有明显的极值分布。这回对一些模型产生很大的影响,所以我们需要对这些自变量进行极值化处理。

极值化处理一般有两种方法:

  • Box-Cox转化
  • 将具有极值化的变量转换为秩,然后再进行分组。

其中Box-Cox变换是指对变量 u u u进行:
z = { ( u + r ) λ − 1 λ λ ≠ 0 l o g ( u + r ) λ = 0 z = \begin{cases} \cfrac{(u+r)^{\lambda-1}}{\lambda} \quad &\lambda \ne 0 \\ log(u+r) & \lambda=0 \end{cases} z=λ(u+r)λ1log(u+r)λ=0λ=0
r r r是一个常数,对 u u u的所有可能取值都满足 u + r > 0 u+r \gt 0 u+r>0,对数转换时Box-Cox转换的一种特殊情形。

首先对本案例数据的所有变量画图,得到:

图1 年龄
图2 教育
图3 工龄
图4 收入
图5 负债率
图6 信用卡负债
图7 其他负债

如图所示,在经过数据筛选得到整数和数值型的数据中,教育、工龄、收入、信用卡负债、其他负债存在有极值分布,这里仅仅只针对数值型的数据收入、信用卡负债、其他负债变换来进行极值处理,但是对整数型变量教育、工龄不进行极致化处理。因为如果进行极值化处理,这些整数型数据就不再是整数了,这在数据分析中是不合理的,因为这改变了数据的变量类型。

这里我们首先对数据收入、信用卡负债、其他负债进行简单的数据变换,即 z = l o g ( u + 1 ) z = log(u + 1) z=log(u+1),得到:

图1 收入.1
图2 信用卡负债.1
图3 其他负债.1

上图的图1-图3看出,数据的分布不再是极值分布了,至此,极值处理完毕。


缺失数据:

根据上一张图片显示的对lona.nvars的描述可知,本案例数据中不存在缺失值。故不对缺失数据进行处理。


降维:

冗余变量不做处理,因为这里从summary(bankLoan)就已经知道所有的变量的中没有不变化的变量。

变量选择:

  1. 针对因变量为二分变量

(1)对于数值自变量而言,可以使用两样本t检验考察因变量取一种值时,与因变量取另外一种值时,该自变量的均值是否相等,然后选择哪些检验结果显著(不相等的)自变量。

(2)对于分类型自变量而言,可以使用卡方检验考察自变量的取值是否独立于因变量的取值,然后选择那些结果显著(不独立)的自变量。

注:以上检验显著,说明不同的自变量对因变量的取值是有显著影响的,这就说明这些自变量会影响因变量的取值,故不进行特征筛选。

  1. 因变量为分类变量

    可以将因变量取值两两配对,针对每对取值进行上述t检验或者卡方检验,然后选择那些对因变量的任何一对取值检验结果显著的自变量。

  2. 因变量为数值型变量

    可选择将因变量取值离散化之后,再使用上面的方法,或者使用以下:

    (1)计算个数值自变量与因变量的相关系数,剔除相关系数小或不显著的变量

    (2)对每个分类自变量,将其取值两两配对,针对每个取值,用t检验考察因变量的均值是否相等,只要对任何一对取值检验结果显著,就选择该自变量。

关于变量的选择,还有逐步选择的方法,包括向前选择,向后剔除,向前选择与向后剔除的结合。

针对本案例数据进行分析:

本案例数据情况:因变量违约,它只有两个取值0和1,其中1代表违约,0代表正常数据。由此可知,本例因变量是二分变量,所以针对以上提及到的第一种情况进行处理。

对分类型自变量Address进行卡方检验,得到

在这里插入图片描述
其中p值是小于0.01的,所以拒绝原假设,认为Address的取值对Default的取值有显著影响。

在这里插入图片描述

因为数据过多,我们不可能对所有的自变量都计算对所有因变量Default来进行检验,所以我们首先选出与因变量Default相关性比较小的变量来进行t检验。

如上图所示,相关系数绝对值最小的前四个:年龄、教育、变换后的收入、变换后的其他负债。

分别对其检验,得到结果:
在这里插入图片描述

如图所示,t.test(loanNew$Age ~ loanNew$Default)显示变量关于Default的两个取值是显著的。所以不考虑剔除此变量。
在这里插入图片描述

如图所示,t.test(loanNew$Edu ~ loanNew$Default)也是显著的,所以不考虑剔除此变量。
在这里插入图片描述

如图所示,t.test(loanNew$Income.1 ~ loanNew$Default)也是显著的,所以不考虑剔除此变量。
在这里插入图片描述

如图所示,t.test(loanNew$OtherDebt.1 ~ loanNew$Default)也是显著的,所以不考虑剔除此变量。

综上,不剔除任何的变量,认为所有的自变量都对因变量Default的取值有影响。


欠采样与过采样

观察数据:

在这里插入图片描述

其中响应变量占比比较少,因此对其进行过采样处理,以使得相应变量与非相应变量之间的比为1:2.

参考

R语言绘制热图(其实是相关系数图)实践(二)corrplot包

数据预处理之异常值处理

数据清洗中异常值(离群值)的判别和处理方法

[实际应用] 转换数据框 指定列数据类型
R语言常用数据整理方法
R语言读写中文编码方式

以下这个可真搞死我了呀,>_<
R语言pdf输出中文乱码处理

附录

library(dplyr)
library(purrr)
library(xlsx)


# ----------读取数据----------
# Sys.setlocale("LC_ALL","Chinese") 
setwd("D:/lagua/CODING/R-learn/R-code/Chap2-DataPreparation")

bankLoan = read.csv("bankloan.csv", header=TRUE,
                     fileEncoding ="GBK")


# ----------数据观察:数据空值检查----------
# ----------列检查----------
# 注意:需要检查一下数据是否有列是NA,
# 使用:以下查看
colnames(bankLoan)
length(colnames(bankLoan))
# 如果是,
# 1,手动将看到的最后几列(这里是3列)删除,无论是否看见有数据
# 2. 使用na.omit()直接将所有的具有空的行或者列删除。有风险!!!
# 参考:[R语言 -- 删除 dataFrame/matrix 中含有NA或全为NA的行或列]
# (https://www.jianshu.com/p/26edb1b1e6c7)

# ----------行检查----------
# 行中是否有空的值也需要查看,使用summary(bankLoan)查看
colnames(bankLoan) = c("Age", "Edu", "WorkAge",
                       "Address", "Income",
                       "DebtRatio", "CreditDebt",
                       "OtherDebt", "Default")

# ----------列检查----------
summary(bankLoan)

# 调整数据框列的类型
bankLoan = bankLoan %>% 
  mutate_at(.vars = vars("Address"),
            .fun = as.factor) %>%
  mutate_at(.vars = vars("Age", "WorkAge", "Income", 
                      "DebtRatio","CreditDebt","OtherDebt"),
            .fun = as.numeric) %>%
  mutate_at(.vars = vars("Age", "Edu", "WorkAge"),
            .fun = as.integer)


# ----------查看数据----------
# 找出列变量的所有整数型或者数值型的数据
loan.nvars <- bankLoan[,lapply(bankLoan,class)=="integer"
                       | lapply(bankLoan,class)=="numeric"]
summary(loan.nvars)


# ----------查看数据描述----------
descrip <- function(nvar)
{
  nmiss <- length(which(is.na(nvar)))
  mean <- mean(nvar,na.rm=TRUE)
  std <- sd(nvar,na.rm=TRUE)
  min <- min(nvar,na.rm=TRUE)
  Q1 <- quantile(nvar,0.25,na.rm=TRUE)
  median <- median(nvar,na.rm=TRUE)
  Q3 <- quantile(nvar,0.75,na.rm=TRUE)
  max <- max(nvar,na.rm=TRUE)
  return(c(nmiss,mean,std,min,Q1,median,Q3,max))
}

loan_nvars_description <- lapply(loan.nvars,descrip) %>% 
  as.data.frame() %>% t()

colnames(loan_nvars_description) <- c("nmiss","mean","std","min","Q1",
                                      "median","Q3","max")
loan_nvars_description


# ----------异常值检测----------
library(vioplot)
# 主要使用直方图来查看异常值的大致分布
for (col in colnames(bankLoan)[-c(4, 9)]){
  # vioplot(bankLoan[[col]], ylab=col)
  hist(bankLoan[[col]], xlab=col,
       main=paste("Histogram of ", col, sep=""))
}

# a = cut(bankLoan$Age, breaks = seq(10, 60, 10)) %>% unique()
# hist(cut(bankLoan$Age, breaks = seq(10, 60, 10)))


# ----------极值处理:(观察)数值变量直方图输出----------
# ----------查看极值----------
library(showtext)
library(sysfonts)
library(showtextdb)
font_add("SIMHEI","SIMHEI.ttf")
font_add("SIMSUN","SIMSUN.TTC")
font_add("kaishu","simkai.ttf")
par(family='STKaiti')
# 设置family='GB1'
pdf("./ch2_case2-2_histogram.pdf",family='GB1')

par(c(3, 3))
for (i in 1:length(loan.nvars)){
  hist(loan.nvars[,i],
       xlab=names(loan.nvars)[i],
       main=paste("Histogram of",names(loan.nvars)[i]),
       col = "grey")
}
dev.off()


# ----------极值处理----------
colnames(bankLoan)
colnames(loan.nvars)

library(MASS)
par(c(1, 3))
# log.vars = c("Income", "CreditRatio", "OtherDebt") # 需要处理的极值
log.vars = c(4, 6, 7)
# new_col = list()
for (i in log.vars){
  var.names = colnames(loan.nvars)
  cur_name = paste(var.names[i],  '.', 1, sep = '')
  new_col = log(loan.nvars[, i] + 1)
  loan.nvars[[cur_name]] = new_col
  hist(loan.nvars[[cur_name]],
       xlab=paste(var.names[i],  '.', 1, sep = ''),
       main=paste("Histogram of",cur_name),
       col = "grey")
}

loanNew = cbind(bankLoan, loan.nvars[,9:11])
loanNew = loanNew[, -c(5, 7, 8)]
colnames(loanNew)


# ----------数据分箱----------
# TODO


# ----------变量选择----------
##删除冗余变量,生成新数据集loanNew
# > colnames(loanNew)
# [1] "Age"          "Edu"          "WorkAge"      "Address"     
# [5] "Income"       "DebtRatio"    "CreditDebt"   "OtherDebt"   
# [9] "Default"      "Income.1"     "CreditDebt.1" "OtherDebt.1" 
# ----------第一步:数值型变量筛选:卡方检验----------
chisq.test(table(loanNew$Address, loanNew$Default))


# ----------变量筛选第一步:画相关系数图----------
cor(loanNew[,-c(4)])
cor.test(loanNew[,-c(4)])

library(corrplot)
corrplot(corr=cor(loanNew[,-c(4)]))
corrplot(corr=cor(loanNew[,-c(4)]), method="number")

# ----------变量筛选第二步:进行t检验----------
test_vars = c("Age", "Edu", "Income.1", "OtherDebt.1")
t.test(loanNew$Age ~ loanNew$Default)
t.test(loanNew$Edu ~ loanNew$Default)
t.test(loanNew$Income.1 ~ loanNew$Default)
t.test(loanNew$OtherDebt.1 ~ loanNew$Default)


# ----------欠采样与过采样----------
##进行欠抽样使得响应者的比例达到1/3
loan1 <- loanNew[loanNew$Default==1,]
loan0 <- loanNew[loanNew$Default==0,]
n1 <- dim(loan1)[1]
n0 <- 2*n1
# 响应观测数是非响应观测数的1/2
loan0 <- loan0[sample(1:dim(loan0)[1],n0),]
loanNew1 <- rbind(loan1,loan0)


# ----------存储数据----------
write.csv(loan_nvars_description,"static/loan_nvars_description.csv")
write.csv(loanNew,"static/loanNew.csv",row.names=FALSE)
write.csv(loanNew1,"static/loanNew1.csv",row.names=FALSE)


--------
##进行欠抽样使得响应者的比例达到1/3
loan1 <- loanNew[loanNew$Default==1,]
loan0 <- loanNew[loanNew$Default==0,]
n1 <- dim(loan1)[1]
n0 <- 2*n1
# 响应观测数是非响应观测数的1/2
loan0 <- loan0[sample(1:dim(loan0)[1],n0),]
loanNew1 <- rbind(loan1,loan0)


# ----------存储数据----------
write.csv(loan_nvars_description,"static/loan_nvars_description.csv")
write.csv(loanNew,"static/loanNew.csv",row.names=FALSE)
write.csv(loanNew1,"static/loanNew1.csv",row.names=FALSE)

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值