数据清洗工作是数据分析必不可少,非常繁琐而又很重要的工作,在这里对初期数据清洗工作做个简单的总结。

预备知识

我觉得非常好数据清洗训练是coursera上的课程,比如 Getting and Cleaning Data

  1. 参考资料
    • Hadley Wickham 的论文 tidy data
    • R包 swirl,太棒了,交互式学习R的各个小块内容!
  2. 字符串处理和正则表达式,常用函数 grep, grepl, sub, gsub

Ch1: 初步数据清洗

1-1 清洗的一般标准

数据清晰需要个标准,https://www.kaggle.com/c/house-prices-advanced-regression-techniques/data,我觉得数据如果能够清洗成这个样子会很不错,还要个data_discription文件。大致来说就是要:

  • 缺失值设置成NA(NA是缺失值的专有代码,可以当成数值运算, 有时候也设置为 NaN)。
  • 每个特征的取值只能一个属性,比如土地类型有时候既是果园,又是山地,优势农地,就要分解成多个变量。
  • 取值只有一个层次,或者NA的数量太多,或者变化(方差)太少的特征需要去掉。
  • 预测变量需要做很多基本分析,比如正态性分析。
  • 层次太多的因子变量要处理,然后去掉,因为它会导致过拟合。

需要特别注意是,因子变量一定不要和数值变量弄混了,否则会出现不必要的模型偏差。因此,我建议数据清洗时候避免把因子变量的层次设置成数字,建议设置成有实际意义的字符串。

1-2 清洗的常用函数和代码

为了得到标准的清洗数据,我们有写常见的任务,代码和函数如下:

  1. 查看层次较多的因子变量
dim(dat)
## 查看每个变量不同取值的个数
temp <- sapply(dat, function(x) length(unique(x))); str(temp)
## 查看变量不同取值较多的变量
temp[temp>100]

## 查看每个因子变量不同取值的个数
temp <- sapply(dat, function(x) ifelse(is.numeric(x), NA, length(unique(x)))) %>% na.omit 
str(temp)
## 查看变量不同取值较多的因子变量
temp[temp>100] 
  1. 用众数代替缺失值
replaceNA.by.mode <- function(x){ 
  if (is.numeric(x))
    x[which(is.na(x))] = median(na.omit(x))
  else
    x[which(is.na(x))] = as.factor(names(which(table(x) == max(table(x))))[[1]]) # 因子众数有多个,选取第一个
  x
} # 用样本众数代替NA
temp <- sapply(dat, replaceNA.by.mode) %>% as.data.frame(); str(temp)
  1. 分布的正态性假设检验

很多模型的效果好坏依赖于预测变量是否正态分布,所以有必要确定预测变量的正态性质。

################################################
## 查看数据是否正态分布有很多方法
#################################################

## 1. 图像法
temp <- dat$转让费 %>% (function(x) gsub("[^0-9]", "",x)) %>% as.numeric()
summary(temp)
hist(temp)
hist(log(temp +1))
qqnorm(temp %>% scale);abline(0,1, col = 2, pch =2, lwd = 4)
qqnorm(log(temp +1) %>% scale);abline(0,1, col = 2, pch =2, lwd = 4)

## 2. Kolmogorov-Smirnov正态性检验, 起修正检验Lilliefor检验也行
x <- log(temp +1) %>% scale
ks.test(temp, "pnorm")
ks.test(x, "pnorm")
ks.test(jitter(x), "pnorm")
nortest::lillie.test(temp)
nortest::lillie.test(x)
nortest::ad.test(x)

## 3. 小样本Shapiro-Wilk检验
shapiro.test(temp)
shapiro.test(x)

Ch2: 数据清洗和特征工程

特征工程对于模型预测能力的提升非常,与数据清洗密切相关,有必要做一个简单的知识总结。

Ch3: 标准数据报告

本章将会建立一些简单的函数,用于分析报告数据的清洗情况,以及特征工程的情况。使用本文件的方法如下:

dat <- read.csv("data.csv", header = T)
dim(dat) #  数据维度
## [1] 2271   86
##*************************************************************
## 查看每列缺失值的个数
temp <- sapply(dat, function(x) sum(is.na(x))); str(temp)
##  Named int [1:86] 0 0 0 0 0 0 0 0 0 0 ...
##  - attr(*, "names")= chr [1:86] "网址" "标题" "交易服务费" "转让费" ...
## 若某个特征缺失值太多,就可以去掉,对那种缺失值很少的变量可以采用样本众数替代。

##*************************************************************
## 查看每个变量不同取值的个数
temp <- sapply(dat, function(x) length(unique(x))); str(temp)
##  Named int [1:86] 2271 2249 1 249 258 6 2 2 2 2 ...
##  - attr(*, "names")= chr [1:86] "网址" "标题" "交易服务费" "转让费" ...
## 查看每个因子变量不同取值的个数
temp <- sapply(dat, function(x) ifelse(is.numeric(x), NA, length(unique(x)))) %>% na.omit 
str(temp)
##  atomic [1:6] 2271 2249 282 2271 28 2225
##  - attr(*, "na.action")=Class 'omit'  Named int [1:80] 3 4 5 6 7 8 9 10 11 12 ...
##   .. ..- attr(*, "names")= chr [1:80] "交易服务费" "转让费" "租金" "流转方式" ...
## 查看变量不同取值较多的因子变量
temp[temp>100] 
##     网址     标题 区域位置 地块编号     描述 
##     2271     2249      282     2271     2225
## 如果特征的因子层次很多,通常这种变量需要进一步的处理。

##************************************************************
## 分析预测变量
## 考察预测变量的基本统计,如果预测变量是数值的,可以考察特征是否为或者可以化为正态分布
## 有多种方法可以使用,参考Ch1-2
# summary(data$预测变量)


##************************************************************
## 变化较少的变量
## 分析是否有常数变量
temp <- sapply(dat, function(x) length(unique(x)))
temp[temp ==1]
## 交易服务费 
##          1
## 样本的经验分布
# ecdf(dat$转让费)
# unique(sort(dat$转让费)) %>% head
# sapply(unique(sort(dat$转让费)), ecdf(dat$转让费)) %>% (function(x) diff(c(0,x))) %>% head()
## 这是经验密度函数,由此就可以计算样本的gini系数, 如果某个特征过于接近于1,则需要处理
# (sapply(unique(sort(dat$转让费)), ecdf(dat$转让费)) %>% (function(x) diff(c(0,x))))^2 %>% sum
## 计算样本的gini系数
temp <- sapply(dat, function(x) (sapply(unique(sort(x)), ecdf(x)) %>% (function(x) diff(c(0,x))))^2 %>% sum)
temp[temp > 0.999]
## 交易服务费       厂地     果园地       菜地     养猪场       耕地 
##  1.0000000  0.9991197  0.9991197  0.9991197  0.9991197  0.9991197 
## 人工牧草地  X.火龙果.       山丘 客家文化屋     山边地   荒山岗地 
##  0.9991197  0.9991197  0.9991197  0.9991197  0.9991197  0.9991197 
##     山林地 
##  0.9991197
## 这些变量变化太少,为了防止过拟合,他们是不会包含在模型中的。