精华内容
下载资源
问答
  • 交叉验证的方法汇总

    2020-12-01 23:25:29
    交叉验证的方法 留一验证 解释: 只从可用的数据集中保留一个数据点,并根据其余数据训练模型。此过程对每个数据点进行迭代,比如有n个数据点,就要重复交叉验证n次。例如下图,一共10个数据,就交叉验证十次 ...

    交叉验证的方法

    1. 留一验证

      • 解释:

        只从可用的数据集中保留一个数据点,并根据其余数据训练模型。此过程对每个数据点进行迭代,比如有n个数据点,就要重复交叉验证n次。例如下图,一共10个数据,就交叉验证十次
        • 图示如下:

        在这里插入图片描述
        • 优点

          • 适合数据集量级较小
          • 因为利用了所有的数据点,因此偏差比较低
        • 缺点

          • 因为重复执行验证,执行时间比较长
          • 因为是数据点进行验证,如果数据点是离群值,那么模型的准确度就会大大受到影响
    2. K折交叉验证

      1.解释:

      进行多次train_test_split划分;每次划分时,在不同的数据集上进行训练、测试评估,从而得出一个评价结果;如果是5折交叉验证,意思就是在原始数据集上,进行5次划分,每次划分进行一次训练、评估,最后得到5次划分后的评估结果,一般在这几次评估结果上取平均得到最后的评分

      • 图示如下:

      在这里插入图片描述

      1. 优点

        1. 适合数据集量级比较大
        2. 提高模型的准确度
        3. 对数据的使用率较高
      2. 缺点

        • 因为是对数据随机均等划分,不适合包含不同类别的数据集,例:(abcde各占20%),抽取出来的也正好是按照类别划分的5类,第一折全是A,第二折全是B……这样就会导致,模型学习到测试集中数据的特点,用BCDE训练的模型去测试A类数据、ACDE的模型测试B类数据,这样准确率就会很低
    3. 分层交叉验证

      • 解释:

        分层是重新将数据排列组合,使得每一折都能比较好地代表整体
        例:在一个二分类问题上,原始数据一共有两类(F和M),F:M的数据量比例大概是 1:3;划分了5折,每一折中F和M的比例都保持和原数据一致(1:3)
        • 图示如下:

          在这里插入图片描述

        • 优点

          • 避免了随机划分可能产生的的情况,像是一折全是F,其他3折都是M
        • 缺点

          • 因为重复执行验证,执行时间比较长
    4. 重复交叉验证

      • 解释:

        如果训练集不能很好地代表整个样本总体,分层交叉验证就没有意义了。这时候,可以使用重复交叉验证
    5. 对抗交叉验证

      • 解释:

        根据特征分布创建一个分类模型,以检查训练集和测试集之间的相似程度

        • 优点

          • 使验证策略在训练集和测试集高度不同的情况下更加可靠
        • 缺点

          • 一旦测试集的分布发生变化,验证集可能不再适合评估模型
    6. 时间序列交叉验证

      • 解释:

        对于时间序列的数据集,不能像上述方法一样随机地划分验证集。为了解决时间序列的预测问题,可以尝试时间序列交叉验证:采用正向链接的策略,即按照时间顺序划分每一折的数据集
        例: 我们有一个时间序列,表示在n年内消费者对某一产品的年需求量
        我们逐步选择新的训练集和测试集。我们从一个最小的训练集开始(这个训练集具有拟合模型所需的最少观测数)逐步地,每次都会更换训练集和测试集。在大多数情况下,不必一个个点向前移动,可以设置一次跨5个点/10个点。在回归问题中,可以使用以下代码执行交叉验证
        • 图示如下:

          在这里插入图片描述
    展开全文
  • 1.数据:R自带inis花数据。用已经学习的分类预测方法(至少两种)采用五折交叉验证的方法做分类预测分析,

    这是一份iris花数据分析的作业。

    Iris花数据分析

    1.数据:R自带inis花数据。用已经学习的分类预测方法(至少两种)采用五折交叉验证的方法做分类预测分析,

    要求

    (1)比较两种方法的分类准确率.

    (2)评价特征变量对分类重要性的影响。

    2.利用去标签的is花数据,要求用所学的聚类方法(至少两种)进行聚类分析,给出最佳聚类结果及其理

    Iris花数据分析

    1.数据:R自带inis花数据。用已经学习的分类预测方法(至少两种)采用五折交叉验证的方法做分类预测分析,

    要求

    (1)比较两种方法的分类准确率.

    (2)评价特征变量对分类重要性的影响。

    2.利用去标签的is花数据,要求用所学的聚类方法(至少两种)进行聚类分析,给出最佳聚类结果及其理

    # write.csv是R语言默认的写入csv方法。
    write.csv(iris,"iris.csv",row.names = TRUE)  
    
    # iris数据集的描述统计
    summary(iris)
    
      Sepal.Length    Sepal.Width     Petal.Length    Petal.Width   
     Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
     1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
     Median :5.800   Median :3.000   Median :4.350   Median :1.300  
     Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199  
     3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
     Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
           Species  
     setosa    :50  
     versicolor:50  
     virginica :50  
    


    str(iris)
    
    'data.frame':	150 obs. of  5 variables:
     $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
     $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
     $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
     $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
     $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
    
    # 查看数据集的属性
    attributes(iris)
    

    这就是iris数据集的大致情况,一共包含5个变量,前4个可以看做预测变量,第5个Species是花的种类

    # 查看分类的种类
    table(iris$Species)
    

        setosa versicolor  virginica 
            50         50         50 
    

    已经学习的分类预测方法(至少两种)采用五折交叉验证的方法做分类预测分析

    我们选择的是决策树,随机森林,SVM

    决策树的安装 install.packages(‘party’)

    SVM的安装 install.packages(‘e1071’)

    随机森林的安装 install.packages(‘randomForest’)

    五折交叉验证 使用caret包中的createFolds()函数,根据标签列将数据分成5 份 。install.packages(‘caret’)

    training <-iris
    #抽样方法
    #ind<-sample(2,nrow(training),replace=TRUE,prob=c(0.7,0.3)) #对数据分成两部分,70%训练数据,30%检测数据nrow(training)行数
    #traindata<- training [ind==1,]  #训练集
    #testdata<- training [ind==2,]  #测试集
     
    # 5-fold cross-validation
    # 就五折交叉验证,用来测试精度,是常用的精度测试方法。
    library("caret")
    library("randomForest")
    folds<-createFolds(y=training$Species,k=5) #根据training的laber-Species把数据集切分成5等份
    
    
    Loading required package: lattice
    Loading required package: ggplot2
    Warning message:
    "package 'ggplot2' was built under R version 3.6.3"randomForest 4.6-14
    Type rfNews() to see new features/changes/bug fixes.
    
    Attaching package: 'randomForest'
    
    The following object is masked from 'package:ggplot2':
    
        margin
    

    re<-{}
    # 随机森林randomForest
    for(i in 1:5){
        traindata<-training[-folds[[i]],]
        testdata<-training[folds[[i]],]
        rf <- randomForest(Species~ ., data=training, ntree=100, proximity=TRUE) #Species是因变量  Species~ .等同于Species ~Sepal.Length + Sepal.Width + Petal.Length + Petal.Width 
        re=c(re,length(training$Species[which(predict(rf)==training$Species)])/length(training$Species))
    }
    print(paste("随机森林的分类准确率", as.character(mean(re))))#取k折交叉验证结果的均值作为评判模型准确率的结果
    
    
    [1] "随机森林的分类准确率 0.954666666666667"
    
    rf
    
    

    Call:
     randomForest(formula = Species ~ ., data = training, ntree = 100,      proximity = TRUE) 
                   Type of random forest: classification
                         Number of trees: 100
    No. of variables tried at each split: 2
    
            OOB estimate of  error rate: 4.67%
    Confusion matrix:
               setosa versicolor virginica class.error
    setosa         50          0         0        0.00
    versicolor      0         47         3        0.06
    virginica       0          4        46        0.08
    
    #测试集
    pre_rf <- predict(rf,iris)
    obs_p_rf = data.frame(prob=pre_rf,obs=iris$Species)
    ###输出混淆矩阵
    table(iris$Species,pre_rf,dnn=c("真实值","预测值"))
    
    
    
                预测值
    真实值       setosa versicolor virginica
      setosa         50          0         0
      versicolor      0         50         0
      virginica       0          0        50
    
    library(pROC) #绘制ROC曲线 
    ###绘制ROC曲线
    rf_roc <- roc(iris$Species,as.numeric(pre_rf))
    plot(rf_roc, print.auc=TRUE, auc.polygon=TRUE, grid=c(0.1, 0.2),grid.col=c("green", "red"), max.auc.polygon=TRUE,auc.polygon.col="skyblue", print.thres=TRUE,main='随机森林模型ROC曲线')
    
    
    
    Warning message:
    "package 'pROC' was built under R version 3.6.3"Type 'citation("pROC")' for a citation.
    
    Attaching package: 'pROC'
    
    The following objects are masked from 'package:stats':
    
        cov, smooth, var
    
    Warning message in roc.default(iris$Species, as.numeric(pre_rf)):
    "'response' has more than two levels. Consider setting 'levels' explicitly or using 'multiclass.roc' instead"Setting levels: control = setosa, case = versicolor
    Setting direction: controls < cases
    

    library(kknn)
    
    
    Warning message:
    "package 'kknn' was built under R version 3.6.3"
    Attaching package: 'kknn'
    
    The following object is masked from 'package:caret':
    
        contr.dummy
    

    res<-{}
    # kknn 
    for(i in 1:5){
        traindata<-training[-folds[[i]],]
        testdata<-training[folds[[i]],]
        knn <- kknn(Species~.,traindata,testdata ,k=4)
        res=c(res,length(training$Species[which(predict(knn)==training$Species)])/length(training$Species))
    }
    print(paste("KNN的分类准确率", as.character(mean(res))))  #取k折交叉验证结果的均值作为评判模型准确率的结果
    
    
    [1] "KNN的分类准确率 0.34"
    
    #测试集
    pre_knn <- fitted(knn) 
    
    
    pre_knn
    
    
    ###输出混淆矩阵
    table(testdata$Species,pre_knn,dnn=c("真实值","预测值"))
    
    
                预测值
    真实值       setosa versicolor virginica
      setosa         10          0         0
      versicolor      0          9         1
      virginica       0          1         9
    
    library(e1071)
    r <- {}
    # e1071 SVM
    for(i in 1:5){
        traindata<-training[-folds[[i]],]
        testdata<-training[folds[[i]],]
        #先定义公式,Species作为因变量,其余作为自变量
        SVM<- svm(Species~ ., data=training)
        r=c(r,length(training$Species[which(predict(SVM)==training$Species)])/length(training$Species))
    }
    print(paste("SVM的分类准确率", as.character(mean(r))))#取k折交叉验证结果的均值作为评判模型准确率的结果
    
    
    [1] "SVM的分类准确率 0.973333333333333"
    
    SVM
    
    

    Call:
    svm(formula = Species ~ ., data = training)
    

    Parameters:
       SVM-Type:  C-classification 
     SVM-Kernel:  radial 
           cost:  1 
    
    Number of Support Vectors:  51
    
    #测试集
    pre_svm <- predict(SVM,iris)
    obs_p_svm = data.frame(prob=pre_svm,obs=iris$Species)
    ###输出混淆矩阵
    table(iris$Species,pre_svm,dnn=c("真实值","预测值"))
    
    
    
                预测值
    真实值       setosa versicolor virginica
      setosa         50          0         0
      versicolor      0         48         2
      virginica       0          2        48
    

    比较随机森林和svm两种方法的分类准确率. 随机森林全部预测成功,SVM有两个误差

    library(pROC) #绘制ROC曲线 
    ###绘制ROC曲线
    svm_roc <- roc(iris$Species,as.numeric(pre_svm))
    plot(svm_roc, print.auc=TRUE, auc.polygon=TRUE, grid=c(0.1, 0.2),grid.col=c("green", "red"), max.auc.polygon=TRUE,auc.polygon.col="skyblue", print.thres=TRUE,main='SVM模型ROC曲线')
    
    
    Warning message in roc.default(iris$Species, as.numeric(pre_svm)):
    "'response' has more than two levels. Consider setting 'levels' explicitly or using 'multiclass.roc' instead"Setting levels: control = setosa, case = versicolor
    Setting direction: controls < cases
    

    head(training)
    
    
    Sepal.LengthSepal.WidthPetal.LengthPetal.WidthSpecies
    5.1 3.5 1.4 0.2 setosa
    4.9 3.0 1.4 0.2 setosa
    4.7 3.2 1.3 0.2 setosa
    4.6 3.1 1.5 0.2 setosa
    5.0 3.6 1.4 0.2 setosa
    5.4 3.9 1.7 0.4 setosa

    评价特征变量对分类重要性的影响。

    我们计算变量之间的相关系数矩阵,相关系数是用以反映变量之间相关关系密切程度的统计指标

    cor(iris[ , 1:4]) # 计算变量之间的相关系数矩阵
    
    
    Sepal.LengthSepal.WidthPetal.LengthPetal.Width
    Sepal.Length 1.0000000-0.1175698 0.8717538 0.8179411
    Sepal.Width-0.1175698 1.0000000-0.4284401-0.3661259
    Petal.Length 0.8717538-0.4284401 1.0000000 0.9628654
    Petal.Width 0.8179411-0.3661259 0.9628654 1.0000000
    # 下面我们分别绘制四个变量和类别的 箱型图  如果分层明显,说明区分类别很明显  如果三个出现重叠现象则不明显
    boxplot(Sepal.Length~Species, data=iris) 
    
    

    # Sepal.Length中 versicolor和Virginica出现重叠  Sepal.Length不是很重要
    
    
    boxplot(Sepal.Width	~Species, data=iris) 
    
    

    #Sepal.Width  versicolor和Virginica出现重叠  Sepal.Width不是很重要
    
    
    boxplot(Petal.Length~Species, data=iris) 
    
    

    boxplot(Petal.Width~Species, data=iris) 
    
    

    Petal.Length和Petal.Width 分层比较明显 Petal.Length和Petal.Width 很重要,是分类的重要指标

    # 绘制Petal.Length和Petal.Width  的散点图,color用类区分
    with(iris, plot(Petal.Length, Petal.Width, col=Species, pch=as.numeric(Species))) #针对每个Species水平绘制两个变量的散点图,并用颜色和点状区分
    
    

    # 2.利用去标签的iris花数据,要求用所学的聚类方法(至少两种)进行聚类分析,给出最佳聚类结果及其理
    
    # 我们使用knn包进行Kmean聚类分析,将列newiris$Species置为空
    newiris <- iris
    newiris$Species <- NULL
    
    #   kmeans() 内置的stats
    kc <- kmeans(newiris, 3)  
    
    kc
    
    K-means clustering with 3 clusters of sizes 62, 38, 50
    
    Cluster means:
      Sepal.Length Sepal.Width Petal.Length Petal.Width
    1     5.901613    2.748387     4.393548    1.433871
    2     6.850000    3.073684     5.742105    2.071053
    3     5.006000    3.428000     1.462000    0.246000
    
    Clustering vector:
      [1] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
     [38] 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
     [75] 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 2 2 2 1 2 2 2 2
    [112] 2 2 1 1 2 2 2 2 1 2 1 2 1 2 2 1 1 2 2 2 2 2 1 2 2 2 2 1 2 2 2 1 2 2 2 1 2
    [149] 2 1
    
    Within cluster sum of squares by cluster:
    [1] 39.82097 23.87947 15.15100
     (between_SS / total_SS =  88.4 %)
    
    Available components:
    
    [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
    [6] "betweenss"    "size"         "iter"         "ifault"      
    
    # 创建一个连续表,在三个聚类中分别统计各种花出现的次数
    table(iris$Species, kc$cluster) 
    

                  1  2  3
      setosa      0  0 50
      versicolor 48  2  0
      virginica  14 36  0
    
    # 根据最后的聚类结果画出散点图,数据为结果集中的列"Sepal.Length"和"Sepal.Width",颜色为用1,2,3表示的缺省颜色
    plot(newiris[c("Sepal.Length", "Sepal.Width")], col = kc$cluster)
    # 在图上标出每个聚类的中心点
    
    points(kc$centers[,c("Sepal.Length", "Sepal.Width")], col = 1:3, pch = 8, cex=2)
    

    # 第二个聚类我们  选择 K-中心点聚类(K-Medoids)
    # K-Mediods函数跟Kmeans函数基本类似,不同的是,Kmeans是选择簇中心来表示聚类簇,而K-Mediods选择靠近簇中心的对象来表示聚类簇。
    # 安装install.packages("cluster")
    library(cluster)
    newiris.pam<-pam(newiris,3)
    
    newiris.pam
    
    Medoids:
          ID Sepal.Length Sepal.Width Petal.Length Petal.Width
    [1,]   8          5.0         3.4          1.5         0.2
    [2,]  79          6.0         2.9          4.5         1.5
    [3,] 113          6.8         3.0          5.5         2.1
    Clustering vector:
      [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
     [38] 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
     [75] 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 3 3 3 3 2 3 3 3 3
    [112] 3 3 2 2 3 3 3 3 2 3 2 3 2 3 3 2 2 3 3 3 3 3 2 3 3 3 3 2 3 3 3 2 3 3 3 2 3
    [149] 3 2
    Objective function:
        build      swap 
    0.6709391 0.6542077 
    
    Available components:
     [1] "medoids"    "id.med"     "clustering" "objective"  "isolation" 
     [6] "clusinfo"   "silinfo"    "diss"       "call"       "data"      
    
    table(iris$Species,newiris.pam$clustering)
    

                  1  2  3
      setosa     50  0  0
      versicolor  0 48  2
      virginica   0 14 36
    
    plot(newiris.pam)
    
    

    #---基于密度的聚类分析  dbscan
    library(fpc)
    iris2<-iris[-5]
    ds<-dbscan(iris2,eps=0.42,MinPts = 5)
    table(ds$cluster,iris$Species)
     
    #打印出ds和iris2的聚类散点图
    plot(ds,iris2)
    

        setosa versicolor virginica
      0      2         10        17
      1     48          0         0
      2      0         37         0
      3      0          3        33
    

    最后结果 Kmean聚类分析和K-中心点聚类都是

    而密度的聚类分析 dbscan

    个人觉得 基于密度的聚类分析 dbscan 的效果比上面两种好

    展开全文
  • 一、对比训练模型前,不同拆分数据集方法 sklearn.model_selection.KFold() 交叉采样,将实验数据划分得到若干个互斥子集。 sklearn.model_selection.StratifiedKFold() 根据数据标签各类型占比进行交叉采样,将...

    一、对比训练模型前,不同拆分数据集方法

    1. sklearn.model_selection.KFold()
      交叉采样,将实验数据划分得到若干个互斥子集。
    2. sklearn.model_selection.StratifiedKFold()
      根据数据标签各类型占比进行交叉采样,将实验数据划分得到若干个互斥子集。
    3. sklearn.cross_validation.train_test_split()
      按特定比例,将实验数据随机拆分为实验数据和测试数据。

    此外还有sklearn.cross_validation.cross_val_score(),其作用在于利用所选的模型对实验数据进行交叉验证,并输出评分(根据cv的分组)。
    参考:cross_val_score用法

    二、具体用法比较
    结合不同的问题选取相应的采样或数据拆分方法,一般而言在分类问题中,对数据进行交叉采样时选择StratifiedKFold可能比较合适,如果是回归问题则可选择另外两种方法。
    1、KFold交叉采样
    将训练/测试数据集划分n_splits个互斥子集,每次只用其中一个子集当做测试集,剩下的(n_splits-1)作为训练集,进行n_splits次实验并得到n_splits个结果。

    from sklearn.model_selection import KFold
    kfolder=sklearn.model_selection.KFold(n_splits=3,shuffle=False,random_state=None)
    
    

    2、StratifiedKFold分层采样
    与KFold最大的差异在于,StratifiedKFold方法是根据标签中不同类别占比来进行拆分数据的。

    from sklearn.model_selection import StratifiedKFold
    sfolder=sklearn.model_selection.StratifiedKFold(n_splits=3,shuffle=False,random_state=None)
    
    

    n_splits:表示将数据划分几等份
    shuffle:在每次划分时,是否进行洗牌
    若为False,其效果相当于random_state为整数(含零),每次划分的结果相同
    若为True,每次划分的结果不一样,表示经过洗牌,随机取样的
    random_state:随机种子数,当设定值(一般为0)后可方便调参,因为每次生成的数据集相同;若设为None,则每次拆分结果可能不同
    StratifiedKFold和KFold用法区别

    3、train_test_split拆分数据
    按照设定的比例,随机将样本集合划分为训练集和测试集,并返回划分好的训练集和测试集数据。

    from sklearn.cross_validation import train_test_split
    X_train,X_test, y_train, y_test =
    cross_validation.train_test_split(X,y,test_size=0.4, random_state=0)
    
    

    X:待划分的样本特征集合
    y:待划分的样本标签
    test_size:若在0~1之间,为测试集样本数目与原始样本数目之比;若为整数,则是测试集样本的数目。
    random_state:随机数种子
    X_train:划分出的训练集数据
    X_test:划分出的测试集数据
    y_train:划分出的训练集标签
    y_test:划分出的测试集标签

    import numpy as np
    from sklearn.model_selection import train_test_split
     
    X,y=np.arange(10).reshape((5,2)),range
    X=np.array([[0,1],[2,3],[4,5],[6,7],[8,9]])
    y=[0,1,2,3,4]
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
    print(X_train,'\n')
    print(y_train,'\n')
    print(X_test,'\n')
    print(y_test)
    >>>
    [[2 3]
     [6 7]
     [8 9]] 
    
    [1, 3, 4] 
    
    [[4 5]
     [0 1]] 
    
    [2, 0]
    
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,358
精华内容 1,343
关键字:

交叉验证的方法