3.1.1 数据预处理

泰坦尼克号数据集共有1309个样本,11个字段。各字段说明如表3-1所示。

表3-1 字段说明

063-2

经过数据预处理后会产生feature(共有9个特征字段)与label标签字段(标明是否生存。1为是,2为否)。

首先,我们利用readxl包的read_excel()函数将数据集导入R语言中。由于字段name(姓名)、ticket(船票号码)、cabin(舱位号码)与要预测的结果survived(是否生存)关联不大,在数据导入后将删除这些字段。

> # 导入titanic数据集
> if(!require(readxl)) install.packages("readxl")
> titanic <- read_excel('../data/titanic3.xls')
> # 删除name、ticket、cabin字段
> titanic <- titanic[,!colnames(titanic) %in% c('name','ticket','cabin')]
> head(titanic,2)
# A tibble: 2 x 8
  pclass   survived  sex      age     sibsp   parch    fare    embarked
   <dbl>   <dbl>     <chr>    <dbl>   <dbl>   <dbl>    <dbl>   <chr>
1  1       1         female   29      0       0        211.    S
2  1       1         male     0.917   1       2        152.    S

利用mice包的md.pattern()函数查看各字段缺失值情况,如图3-2所示。

> # 查看各字段缺失值情况
> if(!require(mice)) install.packages("mice")
> md.pattern(titanic)
       pclass  survived sex  sibsp  parch  fare  embarked age
1043      1        1     1     1      1     1       1     1     0
263       1        1     1     1      1     1       1     0     1
2         1        1     1     1      1     1       0     1     1
1         1        1     1     1      1     0       1     1     1
          0        0     0     0      0     1       2    263   266
065-1

图3-2 titanic数据集各字段缺失值情况

从图3-2可知,字段age数据缺失的样本数为263,fare有1个样本数据缺失,embarked有2个样本数据缺失。接下来我们对缺失数据进行插补。由于age和fare属于数值型变量,采用均值插补,embarked属于字符型变量,采用类别水平随机插补。通过以下代码实现。

> # 缺失值插补
> titanic[is.na(titanic$age),'age'] <- mean(titanic$age,na.rm = T)
> titanic[is.na(titanic$fare),'fare'] <- mean(titanic$fare,na.rm = T)
> titanic[is.na(titanic$embarked),'embarked'] <- sample(unique(titanic$embarked),
+                                                     sum(is.na(titanic$embarked)),
+                                                     replace = T)

由于sex的因子水平为字符,所以必须转换为0与1,这样后续才能进行深度学习训练,执行以下代码将female转换为0,male转换为1。

> # 对sex进行重新编码处理
> titanic['sex'] <- ifelse(titanic$sex=='female',0,1)

现在,还剩embarked是字符型变量,通过以下代码对其进行独热编码转换。

> # 对embarked进行独热编码转换
> if(!require(caret)) install.packages("caret")
> dmy <- dummyVars(~.,data = titanic)
> titanic <- data.frame(predict(dmy,newdata = titanic))

利用caret包的createDataPartition()函数对清洗后的数据集按照字段survived(是否生存)进行等比例拆分,其中80%作为训练集,剩下的20%作为测试集,并对训练集和测试集进行自变量(feature)和因变量(label)拆分。实现代码如下。

> # 数据拆分
> index <- createDataPartition(titanic$survived,p = 0.8,list = F)
> train <- titanic[index,] # 训练集
> test <- titanic[-index,] # 测试集
> x_train <- as.matrix(train[,colnames(train) != 'survived'])
> y_train <- train$survived
> x_test <- as.matrix(test[,colnames(test) !='survived'])
> y_test <- test$survived

注意,不同feature的取值范围不同,我们在训练模型前还需要对feature进行标准化处理。实现代码如下。

> # 数据标准化处理
> x_train_scale <- scale(x_train)
> col_means_train_scale <- attr(x_train_scale,"scaled:center")
> col_std_train_scale <- attr(x_train_scale,"scaled:scale")
> x_test_scale <- scale(x_test,center = col_means_train_scale,
+                       scale = col_std_train_scale)

到此已经完成数据的预处理,接下来我们就可以使用Keras建立深度学习网络、训练模型并进行预测了。