链接代码,好玩的链接代码

kaitaowang 124 0

链接代码,好玩的链接代码-第1张图片-开淘网

  

  

  

作者:LeihuaYe,UCSantaBarbara   

  

翻译:陈超   

  

校对:冯羽   

  

本文约2300字,建议阅读10分钟   

  

本文介绍了一种针对初学者的K临近算法在R语言中的实现方法。   

  

本文呈现了一种在R语言中建立起KNN模型的方式,其中包含了多种测量指标。   

  

  

  

MathyasKurmann拍摄,来自于Unsplash   

  

“如果你有5分钟时间可以离开比尔·盖茨生活,我敢打赌你很富有。”   

  

背景   

  

在机器学习的世界里,我发现K邻近算法(KNN)分类器是最直观、最容易上手的,甚至不需要引入任何数学符号。   

  

为了决定观测样本的标签,我们观察它的邻近样本们并把邻近样本们的标签贴给感兴趣的观测样本。当然,观察一个邻近样本可能会产生偏差和错误,KNN方法就制定了一系列的规则和流程来决定最优化的邻近样本数量,比如,检验k>1的邻近样本并且采纳取大多数的规则来决定分类。   

  

  

  

“为了决定新观测样本的标签,我们就看最邻近样本。”   

  

距离度量   

  

为了选择最邻近的样本,我们必须定义距离的大小。对于类别数据,有汉明距离和编辑距离。详情请见   

  

https://en.m.wikipedia.org/wiki/Knearest_neighbors_algorithm   

  

,本文将不会过多讨论数学问题。   

  

什么是K折交叉验证?   

  

在机器学习当中,交叉验证(CV)在模型选择中起着关键作用,并且拥有一系列的应用。事实上,CV有着更加直观的设计理念,并且也很直观。   

  

简要介绍如下:   

  

1.将数据分成K个均匀分布的块/层   

  

2.选择一个块/层集作为测试集,剩下的K-1块/层作为训练集   

  

3.基于训练集建立ML模型   

  

4.仅比较测试集当中的预测值和真实值   

  

5.将ML模型应用到测试集,并使用每个块重复测试K次   

  

6.把模型的度量得分加和并求K层的平均值   

  

如何选择K?   

  

如同你注意到的,交叉验证比较的一点是如何为K设置值。我们记总样本量为n。从技术上来看,K可设置从1到n的任意值。   

  

如果k=n,我们取出1个观测值作为训练集并把剩余的n-1个值作为测试集。然后在整个数据集中重复这个过程。这就叫做“留一交叉验证法”(LOOCV)。   

  

留一交叉验证法要求较大的计算力,并且如果你的数据集过大,该法可能会无法终止。   

  

退一步来讲,即使没有最优k值,也不能说k值越大更好。   

  

为了选择最合适的k值,我们必须在偏差和方差之间权衡。如果k很小,我们在估计测试误差时会获得较大的偏差但方差会较小;如果k值比较大,我们的偏差会较小,方差会较大。   

  

  

  

JonTyson拍摄,来自于Unsplash   

  

“你好邻居!快进来吧。”   

  

R语言实现   

  

1.软件准备   

  

#install.packages(“ISLR”)   

  

#install.packages(“ggplot2”)#install.packages(“plyr”)   

  

#install.packages(“dplyr”)#install.packages(“class”)#Loadlibraries   

  

library(ISLR)   

  

library(ggplot2)   

  

library(reshape2)   

  

library(plyr)   

  

library(dplyr)   

  

library(class)#loaddataandcleanthedataset   

  

banking=read.csv(“bank-additional-full.csv”,sep=”;”,header=T)##checkformissingdataandmakesurenomissingdata   

  

banking[!complete.cases(banking),]#re-codequalitative(factor)variablesintonumeric   

  

banking$job=recode(banking$job,“‘admin.’=1;’blue-collar’=2;’entrepreneur’=3;’   

  

housemaid’=4;’management’=5;’retired’=6;’self-employed’=7;’services’=8;   

  

’student’=9;’technician’=10;’unemployed’=11;’unknown’=12”)#recodevariableagain   

  

banking$marital=recode(banking$marital,“‘divorced’=1;’married’=2;’single’=3;’unknown’=4”)   

  

banking$education=recode(banking$education,“‘basic.4y’=1;’basic.6y’=2;’basic.9y’=3;’high.school’=4;’illiterate’=5;’professional.course’=6;’university.degree’=7;’unknown’=8”)   

  

banking$default=recode(banking$default,“‘no’=1;’yes’=2;’unknown’=3”)   

  

banking$housing=recode(banking$housing,“‘no’=1;’yes’=2;’unknown’=3”)   

  

banking$loan=recode(banking$loan,“‘no’=1;’yes’=2;’unknown’=3”)banking$contact=recode(banking$loan,“‘cellular’=1;’telephone’=2;”)   

  

banking$month=recode(banking$month,“‘mar’=1;’apr’=2;’may’=3;’jun’=4;’jul’=5;’aug’=6;’sep’=7;’oct’=8;’nov’=9;’dec’=10”)   

  

banking$day_of_week=recode(banking$day_of_week,“‘mon’=1;’tue’=2;’wed’=3;’thu’=4;’fri’=5;”)   

  

banking$poutcome=recode(banking$poutcome,“‘failure’=1;’nonexistent’=2;’success’=3;”)#removevariable“pdays”,b/cithasnovariation   

  

banking$pdays=NULL#removevariable“duration”,b/citiscollinearwiththeDV   

  

banking$duration=NULL   

  

在加载并清空初始数据集之后,通常的做法是将变量的分布可视化,检查季节性,模式,异常值,等等。   

  

#EDAoftheDV   

  

plot(banking$y,main="Plot1:DistributionofDependentVariable")   

  

  

  

如图所示,结果变量(银行服务订阅)并不满足均匀分布,“否”比“是”多得多。   

  

当我们尽力想正确分类标签的时候,监督学习是不太方便的。正如意料之中,如果大量的少数案例被分类为多数标签,假阳性的比率会变高。   

  

事实上,不均匀分布可能会更偏好非参数ML分类器,在我的另一篇文章(使用5个分类器对罕见事件进行分类,https://medium.com/m/global-identity?   

  

redirectUrl=https%3A%2F%2Ftowardsdatascience.com%2Fclassifying-rare-events-using-five-machine-learning-techniques-fab464573233)中介绍了KNN在与其他ML方法进行比较之后表现得更好。这个可能是参数和非参数模型中潜在的数学和统计假设导致的。   

  

2.数据分组   

  

如上所述,我们需要将数据集进行分组,分为训练集和测试集,并采取k层交叉验证来选择最佳的ML模型。根据经验法则,我们通常使用“80-20”比:我们用80%的数据训练ML用剩余20%进行测试。而时间序列数据略有不同,我们将比例改为90%对10%。   

  

#splitthedatasetintotrainingandtestsetsrandomly,butweneedtosetseedsoastogeneratethesamevalueeachtimewerunthecodeset.seed(1)#createanindextosplitthedata:80%trainingand20%test   

  

index=round(nrow(banking)*0.2,digits=0)#samplerandomlythroughoutthedatasetandkeepthetotalnumberequaltothevalueofindex   

  

test.indices=sample(1:nrow(banking),index)#80%trainingset   

  

banking.train=banking[-test.indices,]#20%testset   

  

banking.test=banking[test.indices,]#SelectthetrainingsetexcepttheDV   

  

YTrain=banking.train$y   

  

XTrain=banking.train%>%select(-y)#SelectthetestsetexcepttheDV   

  

YTest=banking.test$y   

  

XTest=banking.test%>%select(-y)   

  

到目前为止,我们已经完成了数据准备并开始模型选择。   

  

3.训练模型   

  

让我们编写一个新的函数(“calc_error_rate”)来记录错误分类率。该函数计算当使用训练集得到的预测标签与真正的结果标签不相匹配的比率。它测量了分类的正确性。   

  

#defineanerrorratefunctionandapplyittoobtaintest/trainingerrorscalc_error_rate<-function(predicted.value,true.value){   

  

return(mean(true.value!=predicted.value))   

  

}   

  

然后,我们需要另外一个函数“do.chunk()”来做k层交叉验证。该函数返回层的可能值的数据框。这一步的主要目的是为KNN选择最佳的K值。   

  

nfold=10   

  

set.seed(1)#cut()dividestherangeintoseveralintervals   

  

folds=seq.int(nrow(banking.train))%>%   

  

cut(breaks=nfold,labels=FALSE)%>%   

  

sampledo.chunk<-function(chunkid,folddef,Xdat,Ydat,k){   

  

train=(folddef!=chunkid)#trainingindexXtr=Xdat[train,]#trainingsetbytheindexYtr=Ydat[train]#truelabelintrainingsetXvl=Xdat[!train,]#testsetYvl=Ydat[!train]#truelabelintestsetpredYtr=knn(train=Xtr,test=Xtr,cl=Ytr,k=k)#predicttraininglabelspredYvl=knn(train=Xtr,test=Xvl,cl=Ytr,k=k)#predicttestlabelsdata.frame(fold=chunkid,#kfolds   

  

train.error=calc_error_rate(predYtr,Ytr),#trainingerrorperfold   

  

val.error=calc_error_rate(predYvl,Yvl))#testerrorperfold   

  

}#seterror.foldstosavevalidationerrors   

  

error.folds=NULL#createasequenceofdatawithanintervalof10   

  

kvec=c(1,seq(10,50,length.out=5))set.seed(1)for(jinkvec){   

  

tmp=ldply(1:nfold,do.chunk,#applydo.functiontoeachfold   

  

folddef=folds,Xdat=XTrain,Ydat=YTrain,k=j)#requiredarguments   

  

tmp$neighbors=j#trackeachvalueofneighbors   

  

error.folds=rbind(error.folds,tmp)#combinetheresults   

  

}#melt()inthepackagereshape2meltswide-formatdataintolong-formatdata   

  

errors=melt(error.folds,id.vars=c(“fold”,”neighbors”),value.name=“error”)   

  

接下来的一步是为了找到使得验证错误最小化的k值。   

  

val.error.means=errors%>%   

  

#selectallrowsofvalidationerrors   

  

filter(variable==“val.error”)%>%   

  

#grouptheselecteddatabyneighbors   

  

group_by(neighbors,variable)%>%   

  

#cacluateCVerrorforeachk   

  

summarise_each(funs(mean),error)%>%   

  

#removeexistinggrouping   

  

ungroup()%>%   

  

filter(error==min(error))#thebestnumberofneighbors   

  

numneighbor=max(val.error.means$neighbors)   

  

numneighbor##[20]   

  

在使用10层交叉验证之后,最优的邻近值数为20。   

  

  

  

NickYoungson   

  

4.一些模型的度量   

  

#trainingerror   

  

set.seed(20)   

  

pred.YTtrain=knn(train=XTrain,test=XTrain,cl=YTrain,k=20)   

  

knn_traing_error<-calc_error_rate(predicted.value=pred.YTtrain,true.value=YTrain)   

  

knn_traing_error   

  

[1]0.101214   

  

训练误差为0.1。   

  

#testerror   

  

set.seed(20)   

  

pred.YTest=knn(train=XTrain,test=XTest,cl=YTrain,k=20)   

  

knn_test_error<-calc_error_rate(predicted.value=pred.YTest,true.value=YTest)   

  

knn_test_error   

  

[1]0.1100995   

  

测试误差为0.11。   

  

#confusionmatrixconf.matrix=table(predicted=pred.YTest,true=YTest)   

  

  

  

基于以上的混淆矩阵(confusionmatrix),我们可以计算以下的值并且准备好画出ROC曲线。   

  

Accuracy=(TP+TN)/(TP+FP+FN+TN)   

  

TPR/Recall/Sensitivity=TP/(TP+FN)   

  

Precision=TP/(TP+FP)   

  

Specificity=TN/(TN+FP)   

  

FPR=1—Specificity=FP/(TN+FP)   

  

F1Score=2*TP/(2*TP+FP+FN)=Precision*Recall/(Precision+Recall)   

  

#Testaccuracyratesum(diag(conf.matrix)/sum(conf.matrix))[1]0.8899005#Testerrorrate1-sum(drag(conf.matrix)/sum(conf.matrix))[1]0.1100995   

  

你可能会注意到,测试正确率+测试错误率=1,我也提供了多种方法来计算每个值。   

  

#ROCandAUC   

  

knn_model=knn(train=XTrain,test=XTrain,cl=YTrain,k=20,prob=TRUE)prob<-attr(knn_model,“prob”)prob<-2*ifelse(knn_model==“-1”,prob,1-prob)—1pred_knn<-prediction(prob,YTrain)performance_knn<-performance(pred_knn,“tpr”,“fpr”)#AUCauc_knn<-performance(pred_knn,”auc”)@y.valuesauc_knn[1]0.8470583plot(performance_knn,col=2,lwd=2,main=”ROCCurvesforKNN”)   

  

  

  

综上所述,我们学习了什么是KNN并且在R语言当中建立了KNN模型。更重要的是,我们已经学到了K层交叉验证法背后的机制以及如何在R语言中实现交叉验证。   

  

作者简介:   

  

雷华·叶(@leihua_ye)是加州大学圣巴巴拉分校的博士生。他在定量用户体验研究、实验与因果推理、机器学习和数据科学方面有5年以上的研究和专业经验。   

  

原文标题:   

  

Beginner’sGuidetoK-NearestNeighborsinR:fromZerotoHero   

  

原文链接:   

  

https://www.kdnuggets.com/2020/01/beginners-guide-nearest-neighbors-r.html   

  

编辑:于腾凯   

  

校对:谭佳瑶   

  

译者简介   

  

  

  

陈超,北京大学应用心理硕士在读。本科曾混迹于计算机专业,后又在心理学的道路上不懈求索。越来越发现数据分析和编程已然成为了两门必修的生存技能,因此在日常生活中尽一切努力更好地去接触和了解相关知识,但前路漫漫,我仍在路上。   

  

—完—   

  

关注清华-青岛数据科学研究院官方微信公众平台“THU数据派”及姊妹号“数据派THU”获取更多讲座福利及优质内容。   

  

  

抱歉,评论功能暂时关闭!