【机器学*与R语言】2-懒惰学*K*邻(kNN)
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)的更多相关文章
- 学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装
在这一系列的前一篇文章学了C语言,如何为下载狂人写一个磁盘剩余容量监控程序?中,我们为下载狂人写了一个程序来监视磁盘的剩余容量,防止下载的东西撑爆了硬盘.可是,这两天,他又抱怨他的下载程序不好用,让我 ...
- 通过R语言统计考研英语(二)单词出现频率
通过R语言统计考研英语(二)单词出现频率 大家对英语考试并不陌生,首先是背单词,就是所谓的高频词汇.厚厚的一本单词,真的看的头大.最近结合自己刚学的R语言,为年底的考研做准备,想统计一下最近考研英语( ...
- R语言缺点
R的优点:免费,开源,体积小.缺点:对大文本处理差,另外一个也在于开源,package如果出错,烦死你.当你跑比较大的simulation,对效率有要求的时候,有时还是不得不用C,这可能是10小时和1 ...
- 《R语言实战》读书笔记--为什么要学
本人最近在某咨询公司实习,涉及到了一些数据分析的工作,用的是R语言来处理数据.但是在应用的过程中,发现用R很不熟练,所以再打算学一遍R.曾经花一个月的时间看过一遍<R语言编程艺术>,还用R ...
- 中部:执具 | R语言数据分析(北京邮电大学)自整理笔记
第5章工欲善其事.必先利其器 代码,是延伸我们思想最好的工具. 第6章基础编程--用别人的包和函数讲述自己的故事 6.1编程环境 1.R语言的三段论 大前提:计算机语言程序=算法+数据结构 小前提:R ...
- 不懂指针就不要说自己学过C语言!
不懂指针就不要说自己学过C语言! 1.掌握了指针,就掌握了C语言的精髓!计算机中绝大部分数据都放到内存中的,不同的数据放到不同的内存区域中. 内存角度没有数据类型,只有二进制:数据以字节(8位二进制) ...
- 学了C语言,如何利用cURL写一个程序验证某个网址的有效性?
在<C程序设计伴侣>以及这几篇关于cURL的文章中,我们介绍了如何利用cURL写一个下载程序,从网络下载文件.可是当我们在用这个程序下载文件时,又遇到了新问题:如果这个网址是无效的,那么我 ...
- 学了C语言,如何写个程序计算出每个月的第一个星期一对应的日期
在前面,我们分别利用泰勒公式和C标准库中的mktime()函数推算了某个特定日期所对应的星期几,刚做完这些,就又遇到了一个与日期相关的新任务: 老板把每个月例会的时间定在了每个月的第一个星期一,他让我 ...
- R语言进行机器学习方法及实例(一)
版权声明:本文为博主原创文章,转载请注明出处 机器学习的研究领域是发明计算机算法,把数据转变为智能行为.机器学习和数据挖掘的区别可能是机器学习侧重于执行一个已知的任务,而数据发掘是在大数据中寻找有 ...
随机推荐
- SpringCloud微服务实战——搭建企业级开发框架(七):自定义通用响应消息及统一异常处理
平时开发过程中,无可避免我们需要处理各类异常,所以这里我们在公共模块中自定义统一异常,Spring Boot 提供 @RestControllerAdvice 注解统一异常处理,我们在GitEgg ...
- the Agiles Scrum Meeting 7
会议时间:2020.4.15 21:00 1.每个人的工作 根据项目进度,我们将原先的完善组和debug组合并,成为团队项目增量开发组,原增量组成为个人结对项目增量开发组. 今天已完成的工作 个人结对 ...
- linux与windows下文件编码问题
注:转换操作均在Linux终端进行操作 DOS与Unix格式转换 安装工具:dos2unix.unix2dos # ubuntu apt-get install dos2unix apt-get in ...
- Prometheus重新标记
Prometheus重新标记 一.背景 二.简化的指标抓取的生命周期 1.配置参数详解 1.`action:`存在的值 1.替换标签值 2.删除指标 3.创建或删除标签 2.删除标签注意事项 3.几个 ...
- CSS 奇技淫巧 | 巧妙实现文字二次加粗再加边框
本文将通过一个实际的业务需求,讲解如何实现 极端场景下文字加粗加边框效果 文字多重边框的效果 需求背景 - 文字的二次加粗 今天遇到这样一个有意思的问题: 在文字展示的时候,利用了 font-weig ...
- 从零开始的DIY智能家居 - 基于 ESP32 的土壤湿度传感器
前言 自从上次做了那个 甲醛传感器 和 水浊度传感器 之后开始尝到智能家居的甜头了,这两东西有没有用我不知道,但是没事的时候掏出手机瞄两眼,看着就让人很安心( ̄︶ ̄). 于是懒惰的我开始琢磨把给植物浇 ...
- Python 调用上级目录的文件
程序结构如下: – src |-- mod1.py |-- lib | |-- mod2.py |-- sub | |-- test.py 具体代码如下: 在test.py里调用mod1 mod2 i ...
- DeWeb 简介
DeWeb是一个可以直接将Delphi程序快速转换为网页应用的工具! 使用DeWeb, 开发者不需要学习HTML.JavaScript.Java.PHP.ASP.C#等新知识,用Delphi搞定一切. ...
- Centos 7 编译安装llvm 8.0.0
参考连接:https://www.cnblogs.com/BinBinStory/p/7499527.html https://blog.csdn.net/llwy1428/article/detai ...
- Apache Solr应用服务器存在远程代码执行漏洞👻
Apache Solr应用服务器存在远程代码执行漏洞 1.描述 Apache Solr是一个开源的搜索服务,使用Java语言开发,主要基于HTTP和Apache Lucene实现的. Solr是一个高 ...