1.理解使用KNN进行分类

KNN特点

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

KNN步骤

1)计算距离

距离函数度量:如欧氏距离(最短的直线距离),曼哈顿距离(类似城市街区路线)。欧氏距离公式:

假设我们已知葡萄、绿豆、坚果、橙子等食品的分类和特征(脆度和甜度),现在想知道已知特征(甜度=6,脆度=4)的西红柿属于哪一类?计算与它的几个近邻之间的欧氏距离:



若K=1,西红柿和orange最近,归类为水果;

若K=3,3个近邻为orange,grape,nuts,三者之间投票表决,2/3归为水果,因而西红柿归类为水果。

2)选择合适的K

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

实际上,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)

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)

正确分类从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-如何提高模型的性能?

【机器学*与R语言】2-懒惰学*K*邻(kNN)的更多相关文章

  1. 学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装

    在这一系列的前一篇文章学了C语言,如何为下载狂人写一个磁盘剩余容量监控程序?中,我们为下载狂人写了一个程序来监视磁盘的剩余容量,防止下载的东西撑爆了硬盘.可是,这两天,他又抱怨他的下载程序不好用,让我 ...

  2. 通过R语言统计考研英语(二)单词出现频率

    通过R语言统计考研英语(二)单词出现频率 大家对英语考试并不陌生,首先是背单词,就是所谓的高频词汇.厚厚的一本单词,真的看的头大.最近结合自己刚学的R语言,为年底的考研做准备,想统计一下最近考研英语( ...

  3. R语言缺点

    R的优点:免费,开源,体积小.缺点:对大文本处理差,另外一个也在于开源,package如果出错,烦死你.当你跑比较大的simulation,对效率有要求的时候,有时还是不得不用C,这可能是10小时和1 ...

  4. 《R语言实战》读书笔记--为什么要学

    本人最近在某咨询公司实习,涉及到了一些数据分析的工作,用的是R语言来处理数据.但是在应用的过程中,发现用R很不熟练,所以再打算学一遍R.曾经花一个月的时间看过一遍<R语言编程艺术>,还用R ...

  5. 中部:执具 | R语言数据分析(北京邮电大学)自整理笔记

    第5章工欲善其事.必先利其器 代码,是延伸我们思想最好的工具. 第6章基础编程--用别人的包和函数讲述自己的故事 6.1编程环境 1.R语言的三段论 大前提:计算机语言程序=算法+数据结构 小前提:R ...

  6. 不懂指针就不要说自己学过C语言!

    不懂指针就不要说自己学过C语言! 1.掌握了指针,就掌握了C语言的精髓!计算机中绝大部分数据都放到内存中的,不同的数据放到不同的内存区域中. 内存角度没有数据类型,只有二进制:数据以字节(8位二进制) ...

  7. 学了C语言,如何利用cURL写一个程序验证某个网址的有效性?

    在<C程序设计伴侣>以及这几篇关于cURL的文章中,我们介绍了如何利用cURL写一个下载程序,从网络下载文件.可是当我们在用这个程序下载文件时,又遇到了新问题:如果这个网址是无效的,那么我 ...

  8. 学了C语言,如何写个程序计算出每个月的第一个星期一对应的日期

    在前面,我们分别利用泰勒公式和C标准库中的mktime()函数推算了某个特定日期所对应的星期几,刚做完这些,就又遇到了一个与日期相关的新任务: 老板把每个月例会的时间定在了每个月的第一个星期一,他让我 ...

  9. R语言进行机器学习方法及实例(一)

    版权声明:本文为博主原创文章,转载请注明出处   机器学习的研究领域是发明计算机算法,把数据转变为智能行为.机器学习和数据挖掘的区别可能是机器学习侧重于执行一个已知的任务,而数据发掘是在大数据中寻找有 ...

随机推荐

  1. Linux主机入侵检测

    检查系统信息.用户账号信息 ● 操作系统信息 cat /proc/version 用户信息 用户信息文件 /etc/passwd root:x:0:0:root:/root:/bin/bash 用户名 ...

  2. Qt坐标转换系统的理解

    转 https://blog.csdn.net/hgcprg/article/details/53537106 今天又看了一篇对Qt坐标转换系统以及QTransform的博客,作者讲的非常透彻,链接如 ...

  3. 零基础入门C语言超详细的字符串详解

    本篇文章是对C语言字符串操作进行了详细的总结分析,需要的朋友参考下 1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, ...

  4. 21.7.31 test

    \(NOIP\) 测试 好久没有这种感觉能阿克的冲动了!但还是挂了分 T1 WOJ2608(模拟,拓扑排序) 签到题,直接模拟,有点像拓扑排序. 要给点打标记不然可能被某次操作中弹出多次该点导致WA ...

  5. 确定两串乱序同构 牛客网 程序员面试金典 C++ Python

    确定两串乱序同构 牛客网 程序员面试金典 C++ Python 题目描述 给定两个字符串,请编写程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串.这里规定大小写为不同字符,且考虑字符串中 ...

  6. sublime text c++ makefile

    http://blog.csdn.net/wangdan1600/article/details/43857195 http://blog.csdn.net/artprog/article/detai ...

  7. Harbor仓库搭建及使用

    目录 一.docker配置 二.安装docker-compose 三.安装harbor 四.管理harbor 五.springboot项目配置docker 六.linux服务器上打包并推送至harbo ...

  8. 【Docker】Maven打包SpringBoot项目成Docker镜像并上传到Harbor仓库(Eclipse、STS、IDEA、Maven通用)

    写在前面 最近,在研究如何使用Maven将SpringBoot项目打包成Docker镜像并发布到Harbor仓库,网上翻阅了很多博客和资料,发现大部分都是在复制粘贴别人的东西,没有经过实践的检验,根本 ...

  9. 2016西邮Linux兴趣小组大事记

    2016年还有半个小时就结束了,前面把自己9月做的规划拿出来完善了下,觉得真的是不容易的一年,所有的事情只有自己经历过才会有不一样的感受,世上无难事,只怕有心人. 这是我九月份制定的计划: 下面是20 ...

  10. SpringCloud概念

    SpringCloud概述 1.SpringCloud是什么? 官方解释:  官网: https://spring.io/projects/spring-cloud/  SpringCloud是一系列 ...