zoukankan      html  css  js  c++  java
  • 【机器学*与R语言】2-懒惰学*K*邻(kNN)

    1.理解使用KNN进行分类

    KNN特点

    • 近邻分类器:一种懒惰学习器,即把未标记的案例归类为与它们最相似的带有标记的案例所在的类。当一个概念很难定义,但你看到它时知道它是什么,就适合用KNN分类。
    • KNN优点:简单有效;数据分布无要求;训练快
    • KNN缺点:不产生模型(发现特征间关系能力有限);分类慢;内存大;名义变量和缺失值需要处理
    • KNN算法将特征处理为一个多维特征空间内的坐标。如标记配料为水果、蔬菜和蛋白3种类型,每种配料有脆度crunshiness和甜度sweetness 2个维度特征,体现在坐标内就是x轴、y轴。

    KNN步骤

    1)计算距离

    距离函数度量:如欧氏距离(最短的直线距离),曼哈顿距离(类似城市街区路线)。欧氏距离公式:
    p,q为比较的案例,n为特征

    假设我们已知葡萄、绿豆、坚果、橙子等食品的分类和特征(脆度和甜度),现在想知道已知特征(甜度=6,脆度=4)的西红柿属于哪一类?计算与它的几个近邻之间的欧氏距离:
    image.png
    若K=1,西红柿和orange最近,归类为水果;
    若K=3,3个近邻为orange,grape,nuts,三者之间投票表决,2/3归为水果,因而西红柿归类为水果。

    2)选择合适的K

    • 偏差-方差权衡:过拟合与欠拟合之间的平衡。选择一个大的K会减少噪音数据对模型的影响,但过大会导致模型总是预测数量占大多数的那个类(几乎每个训练案例都会投票表决),而非最近的邻居;较小的K值会给出更复杂的决策边界,可更精细的拟合训练数据,但K过小则会使得噪音数据或异常值过度影响案例的分类(比如贴错标签)。
      image.png

    实际上,K的选取取决于学习概念的难度和训练集中案例的数量。一般,K为3-10。

    • 常见的方法是将k设为训练集中案例数量的平方根。
    • 另一种方法是基于多个测试数据集来测试多个K值,选择一个最好分类性能的K值。
    • 还有一种不常见的方法就是选择一个较大的K,再按距离远近来给一个权威投票。

    3)数据准备

    • 特征标准化:将特征转换为一个标准范围内,使得特征对距离公式的贡献相对平均。如不转换,距离度量会被较大的特征值支配
    • min-max标准化(0-1范围):特征的每一个值(x-min(x))/(max(x)-min(x))
    • z-score标准化(mean=0,sd=1,无边界):(x-mean(x))/(sd(x))
    • 名义变量的距离计算:利用哑变量编码,如男/女=1/0,不需要标准化(若是有序且步长相等的名义特征,则需要转换)
    • 懒惰学习算法(基于实例的学习/机械学习):没有抽象化步骤,跳过了抽象过程和一般化过程。仅仅存储训练集,所以训练很快,但预测较慢。是非参数学习方法,即没有需要学习的数据参数。

    2.用KNN诊断乳腺癌

    1)收集数据

    数据:569例细胞活检案例,每个案例32个特征(其中包含一个编号,一个癌症诊断结果:良性B/恶性M),使用KNN算法来识别肿瘤是恶性还是良性?
    获取途径1:http://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/
    获取途径2:以下链接下载wisc_bc_data.csv

    链接: https://pan.baidu.com/s/1Kdj6T8mp7YKraRLxEg3u1g 提取码: 9auq

    2)探索和准备数据

    查看数据,注意去除ID特征。
    构造训练集和测试集最好都是来自数据全集的一个有代表性的子集(事先随机顺序)。

    ## Example: Classifying Cancer Samples ----
    ## Step 2: Exploring and preparing the data ---- 
    
    # import the CSV file
    wbcd <- read.csv("wisc_bc_data.csv", stringsAsFactors = FALSE)
    
    # examine the structure of the wbcd data frame
    str(wbcd)
    
    # drop the id feature
    wbcd <- wbcd[-1]
    
    # table of diagnosis
    table(wbcd$diagnosis)
    
    # recode diagnosis as a factor
    wbcd$diagnosis <- factor(wbcd$diagnosis, levels = c("B", "M"),
                             labels = c("Benign", "Malignant"))
    
    # table or proportions with more informative labels
    round(prop.table(table(wbcd$diagnosis)) * 100, digits = 1)
    
    # summarize three numeric features
    summary(wbcd[c("radius_mean", "area_mean", "smoothness_mean")])
    
    # create normalization function
    normalize <- function(x) {
      return ((x - min(x)) / (max(x) - min(x)))
    }
    
    # test normalization function - result should be identical
    normalize(c(1, 2, 3, 4, 5))
    normalize(c(10, 20, 30, 40, 50))
    
    
    # normalize the wbcd data
    wbcd_n <- as.data.frame(lapply(wbcd[2:31], normalize))
    
    # confirm that normalization worked
    summary(wbcd_n$area_mean)
    
    # create training and test data
    wbcd_train <- wbcd_n[1:469, ]
    wbcd_test <- wbcd_n[470:569, ]
    
    # create labels for training and test data
    
    wbcd_train_labels <- wbcd[1:469, 1]
    wbcd_test_labels <- wbcd[470:569, 1]
    

    3)训练模型

    K最好使用奇数,这样会减少各个类票数相等的情况发生的可能性(如西红柿示例中K=2时)。

    ## Step 3: Training a model on the data ----
    
    # load the "class" library
    library(class)
    
    wbcd_test_pred <- knn(train = wbcd_train, 
                          test = wbcd_test,
                          cl = wbcd_train_labels, 
                          k = 21)  #训练集案例的平方根floor(sqrt(469))
    

    4)评估模型的性能

    即评估预测分类与测试分类中已知值得匹配程度。预测设计假阳性FP比率和假阴性FN比率之间的平衡。

    乳腺癌分类的假阴性比假阳性付出的代价更大,即把恶性判断为良性。

    ## Step 4: Evaluating model performance ----
    
    # load the "gmodels" library
    library(gmodels)
    
    # Create the cross tabulation of predicted vs. actual
    CrossTable(x = wbcd_test_labels, y = wbcd_test_pred,
               prop.chisq = FALSE)
    

    image.png

    5)提高模型性能

    ①尝试将min-max标准化改为z-score标准化

    ## Step 5: Improving model performance ----
    
    # use the scale() function to z-score standardize a data frame
    wbcd_z <- as.data.frame(scale(wbcd[-1]))
    
    # confirm that the transformation was applied correctly
    summary(wbcd_z$area_mean)
    
    # create training and test datasets
    wbcd_train <- wbcd_z[1:469, ]
    wbcd_test <- wbcd_z[470:569, ]
    
    # re-classify test cases
    wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test,
                          cl = wbcd_train_labels, k = 21)
    
    # Create the cross tabulation of predicted vs. actual
    CrossTable(x = wbcd_test_labels, y = wbcd_test_pred,
               prop.chisq = FALSE)
    

    image.png

    正确分类从98%降为95%,且假阴性从2%提升到了5%,效果更差。

    ②尝试不同的K值

    # try several different values of k
    wbcd_train <- wbcd_n[1:469, ]
    wbcd_test <- wbcd_n[470:569, ]
    
    wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test, cl = wbcd_train_labels, k=1)
    CrossTable(x = wbcd_test_labels, y = wbcd_test_pred, prop.chisq=FALSE)
    
    wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test, cl = wbcd_train_labels, k=5)
    CrossTable(x = wbcd_test_labels, y = wbcd_test_pred, prop.chisq=FALSE)
    
    wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test, cl = wbcd_train_labels, k=11)
    CrossTable(x = wbcd_test_labels, y = wbcd_test_pred, prop.chisq=FALSE)
    
    wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test, cl = wbcd_train_labels, k=15)
    CrossTable(x = wbcd_test_labels, y = wbcd_test_pred, prop.chisq=FALSE)
    
    wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test, cl = wbcd_train_labels, k=21)
    CrossTable(x = wbcd_test_labels, y = wbcd_test_pred, prop.chisq=FALSE)
    
    wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test, cl = wbcd_train_labels, k=27)
    CrossTable(x = wbcd_test_labels, y = wbcd_test_pred, prop.chisq=FALSE)
    

    以上结果中,虽然K=1时的假阴性率最低,但是以增加假阳性结果为代价的。注意不能为了过于准确预测测试集来随意调整方法。

    尽管kNN算法简单,但它能处理复杂的任务。


    机器学习与R语言系列推文汇总:
    【机器学习与R语言】1-机器学习简介
    【机器学习与R语言】2-K近邻(kNN)
    【机器学习与R语言】3-朴素贝叶斯(NB)
    【机器学习与R语言】4-决策树
    【机器学习与R语言】5-规则学习
    【机器学习与R语言】6-线性回归
    【机器学习与R语言】7-回归树和模型树
    【机器学习与R语言】8-神经网络
    【机器学习与R语言】9-支持向量机
    【机器学习与R语言】10-关联规则
    【机器学习与R语言】11-Kmeans聚类
    【机器学习与R语言】12-如何评估模型的性能?
    【机器学习与R语言】13-如何提高模型的性能?

  • 相关阅读:
    配置域名服务器报错named[822]: dns_rdata_fromtext /etc/bind/db.asertest.com mail not a valid number
    Cookie/Session机制详解
    java中一个数组不能放不同数据类型的值
    javascript中 (function(){})();如何理解?
    图表实现基于SVG或Canvas
    千层饼图 年轮图
    element select下拉框绑定number类型
    Vue和JQuery相比,除了节省了开发成本,还有什么优点?
    前端领域的BEM到底是什么
    js数组操作find查找特定值结合es6特性
  • 原文地址:https://www.cnblogs.com/jessepeng/p/13586543.html
Copyright © 2011-2022 走看看