不同算法的比较

实验目的

  1. 复习多种分类算法
  2. 比较多种分类算法,了解各个的优缺点
  3. 学会灵活使用各种分类算法

KNN算法

一、KNN算法的优点

1、KNN是一种在线技术,新数据可以直接加入数据集而不必进行重新训练

2、KNN理论简单,容易实现

二、KNN算法的缺点

1、对于样本容量大的数据集计算量比较大。

2、样本不平衡时,预测偏差比较大。如:某一类的样本比较少,而其它类样本比较多。

3、KNN每一次分类都会重新进行一次全局运算。

4、k值大小的选择。

支持向量机(SVM)

一、 SVM优点

1、解决小样本下机器学习问题。

2、解决非线性问题。

3、无局部极小值问题。(相对于神经网络等算法)

4、可以很好的处理高维数据集。

5、泛化能力比较强。

二、SVM缺点

1、对于核函数的高维映射解释力不强,尤其是径向基函数。

2、对缺失数据敏感。

决策树

一、 决策树优点

1、决策树易于理解和解释,可以可视化分析,容易提取出规则。

2、可以同时处理标称型和数值型数据。

3、测试数据集时,运行速度比较快。

4、决策树可以很好的扩展到大型数据库中,同时它的大小独立于数据库大小。

二、决策树缺点

1、对缺失数据处理比较困难。

2、容易出现过拟合问题。

3、忽略数据集中属性的相互关联。

4、ID3算法计算信息增益时结果偏向数值比较多的特征。

三、改进措施

1、对决策树进行剪枝。可以采用交叉验证法和加入正则化的方法。

2、使用基于决策树的combination算法,如bagging算法,randomforest算法,可以解决过拟合的问题

四、应用领域

企业管理实践,企业投资决策,由于决策树很好的分析能力,在决策过程应用较多。

人工神经网络

一、 神经网络优点

1、分类准确度高,学习能力极强。

2、对噪声数据鲁棒性和容错性较强。

3、有联想能力,能逼近任意非线性关系。

二、神经网络缺点

1、神经网络参数较多,权值和阈值。

2、黑盒过程,不能观察中间结果。

3、学习过程比较长,有可能陷入局部极小值。

三、人工神经网络应用领域

目前深度神经网络已经应用与计算机视觉,自然语言处理,语音识别等领域并取得很好的效果。

实验步骤

数据集记录的是泰坦尼克号乘客的存活情况。数据集包括乘客的等级(class)、年龄(age)、性别(sex)和存活情况(survive),最终希望通过分析乘客的等级、年龄和性别建立模型,对乘客是否能够存活进行分类。

以下是使用read.table()函数读取的数据集情况,可以看到class的3/4分位数和最大值、age的最小值和1/4分位数以及sex的1/4分位数和中位值分别相等,判断数据集可能已经离散化。

> data <- read.table("./titanic_s.txt", header = TRUE, sep = ",")  
> summary(data)  
     class                 age                 sex                survive         
 Min.   :-1.8700000   Min.   :-0.228000   Min.   :-1.9200000   Min.   :-1.0000    
 1st Qu.:-0.9230000   1st Qu.:-0.228000   1st Qu.: 0.5210000   1st Qu.:-1.0000    
 Median : 0.0214000   Median :-0.228000   Median : 0.5210000   Median :-1.0000    
 Mean   :-0.0007595   Mean   : 0.000202   Mean   :-0.0002494   Mean   :-0.3539    
 3rd Qu.: 0.9650000   3rd Qu.:-0.228000   3rd Qu.: 0.5210000   3rd Qu.: 1.0000    
 Max.   : 0.9650000   Max.   : 4.380000   Max.   : 0.5210000   Max.   : 1.0000

将数据全部转换为因子类型。可以看到经过转换后,class有四类(贵族、高、中、低)、age有两类(孩子和成人)、sex有两类(男和女)、survive有两类(存活和未存活)。

> data$class <- as.factor(data$class)
> data$age <- as.factor(data$age)
> data$sex <- as.factor(data$sex)
> data$survive <- as.factor(data$survive)
> summary(data)
    class         age          sex       survive  
 -1.87 :325   -0.228:2092   -1.92: 470   -1:1490  
 -0.923:285   4.38  : 109   0.521:1731   1 : 711  
 0.0214:706                                       
 0.965 :885

使用table()函数可查看未存活和存活人数分别为1490人、711人,二者数据量相差较大;如果用这样的数据集建模,可能影响分类结果。

> table(data$survive)  

  -1    1   
1490  711

为此,对数据量较少的存活人员样本进行重抽样,使得二者的样本数量一致。

> balance <- function(data,yval) {  
+   y.vector <- with(data,get(yval))  
+   index.0 <- which(y.vector==-1)  
+   index.1 <- which(y.vector==1)  
+   index.1 <- sample(index.1, length(index.0), replace = TRUE)  
+   result <- data[sample(c(index.0,index.1)),]  
+   result  
+ }  
>   
> sdata <- balance(data, "survive")  
> table(sdata$survive)  

  -1    1   
1490 1490

将重抽样后的数据分为训练数据集和样本数据集,比例默认按7:3分配。

> apart.data <- function(data, percent = 0.7) {  
+   train.index <- sample(c(1:nrow(data)),round(percent*nrow(data)))  
+   data.train <- data[train.index,]  
+   data.test <- data[-c(train.index),]  
+   result <- list(train = data.train, test = data.test)  
+   result  
+ }  
> p.data <- apart.data(sdata)  
> data.train <- p.data$train  
> data.test <- p.data$test

分类算法1:朴素贝叶斯分类,注意要加载e1071库。应用测试数据集对效果进行评估,结果真正率tpr(也就是“预测活着也真活着的人数”/“实际活着的人数”)为54%,真负率tnr(也就是“预测没活也真没活的人数”/“实际没活的人数”)81%。看来预测“没活”的情况比较准。

> install.packages("e1071")  
> library(e1071)  
> nb.sol <- naiveBayes(mod.formula, data.train);nb.sol
> nb.predict <- predict(nb.sol, newdata = data.test)  
> tb <- table(nb.predict, data.test$survive)  
> tpr <- tb[2,2]/(tb[2,2]+tb[1,2]);tpr
[1] 0.540724
> tnr <- tb[1,1]/(tb[1,1]+tb[2,1]);tnr
[1] 0.8097345

其中算法的具体输出结果为:

Naive Bayes Classifier for Discrete Predictors

Call:
naiveBayes.default(x = X, y = Y, laplace = laplace)

A-priori probabilities:
Y
       -1         1 
0.4976031 0.5023969 

Conditional probabilities:
    class
Y         -1.87     -0.923     0.0214      0.965
  -1 0.08477842 0.10886320 0.34778420 0.45857418
  1  0.27099237 0.17748092 0.26431298 0.28721374

    age
Y        -0.228       4.38
  -1 0.96628131 0.03371869
  1  0.91698473 0.08301527

    sex
Y         -1.92      0.521
  -1 0.08381503 0.91618497
  1  0.50190840 0.49809160

分类算法2:支持向量机(SVM)分类。应用测试数据集对效果进行评估,结果也是真正率tpr较低,真负率tnr较高。

> svm.sol <- svm(mod.formula, data.train);svm.sol  
> svm.predict <- predict(svm.sol, data.test)  
> tb <- table(svm.predict, data.test$survive)  
> tpr <- tb[2,2]/(tb[2,2]+tb[1,2]);tpr
[1] 0.4434389
> tnr <- tb[1,1]/(tb[1,1]+tb[2,1]);tnr
[1] 0.8849558

算法的具体输出结果为:

Call:
svm(formula = mod.formula, data = data.train)


Parameters:
   SVM-Type:  C-classification 
 SVM-Kernel:  radial 
       cost:  1 
      gamma:  0.1666667 

Number of Support Vectors:  1210

测试集上的分类效果为:

svm.predict  -1   1
         -1 400 246
         1   52 196

分类算法3:人工神经网络(ANN)分类,注意加载nnet包。应用测试数据集对效果进行评估,结果也是真正率tpr较低,真负率tnr较高。

> library(nnet)  
> nnet.sol <- nnet(mod.formula, data.train, size =7, maxit = 1000);nnet.sol  
> pred.prob <- predict(nnet.sol, data.test)  
> pred.class <- ifelse(pred.prob>0.5, 1,0)  
> table(pred.class, data.test$survive)  
> tb <- table(pred.class, data.test$survive)  
> tpr <- tb[2,2]/(tb[2,2]+tb[1,2]);tpr
[1] 0.4434389
> tnr <- tb[1,1]/(tb[1,1]+tb[2,1]);tnr
[1] 0.8849558

算法的具体输出结果为:

# weights:  50
initial  value 1627.541677 
iter  10 value 1136.082045
iter  20 value 1109.261101
iter  30 value 1107.529732
iter  40 value 1107.405774
iter  50 value 1107.386480
iter  60 value 1107.383362
iter  70 value 1107.382923
final  value 1107.382846 
converged
a 5-7-1 network with 50 weights
inputs: class-0.923 class0.0214 class0.965 age4.38 sex0.521 
output(s): survive 
options were - entropy fitting

测试集上的分类效果为:

pred.class  -1   1
         0 400 246
         1  52 196

results matching ""

    No results matching ""