关注微信公共号:小程在线
关注CSDN博客:程志伟的博客
R版本:3.6.1
K-最近邻算法:
a.距离:
闵可夫斯基距离、欧式距离、绝对距离、切比雪夫距离、夹角余弦距离
b.临近个数:
1-邻近法:以一个最近距离表示该类别,错误率不会高于普通贝叶斯的两倍。
旁置法:70%的训练集和30%的测试集,适合样本大的情况。
留一法:抽取一个样本作为测试集,这个过程需要重复N次,取平均值作为误差。在数据不平衡时,误差较大。
setwd('G:\\R语言\\大三下半年\\R语言数据挖掘方法及应用\\')
> ##########KNN分类
> set.seed(12345)
> x1<-runif(60,-1,1)
> x2<-runif(60,-1,1)
> y<-sample(c(0,1),size=60,replace=TRUE,prob=c(0.3,0.7))
> Data<-data.frame(Fx1=x1,Fx2=x2,Fy=y)
Data
Fx1 Fx2 Fy
1 0.441807793 0.583135597 1
2 0.751546386 -0.482631366 1
3 0.521964657 0.971967664 0
4 0.772249132 0.513747487 1
5 -0.087038080 0.959556494 1
......
56 -0.001517959 0.811382272 0
57 0.459543943 0.968052347 1
58 -0.839327911 0.175895947 1
59 -0.128939030 -0.981071897 1
60 -0.526839093 -0.358415862 1
> SampleId<-sample(x=1:60,size=18)
> DataTest<-Data[SampleId,]
> DataTrain<-Data[-SampleId,]
> par(mfrow=c(2,2),mar=c(4,6,4,4))
> plot(Data[,1:2],pch=Data[,3]+1,cex=0.8,xlab="x1",ylab="x2",main="全部样本")
> plot(DataTrain[,1:2],pch=DataTrain[,3]+1,cex=0.8,xlab="x1",ylab="x2",main="训练样本和测试样本")
> points(DataTest[,1:2],pch=DataTest[,3]+16,col=2,cex=0.8)
> library("class")
> errRatio<-vector()
> for(i in 1:30){
+ KnnFit<-knn(train=Data[,1:2],test=Data[,1:2],cl=Data[,3],k=i)
+ CT<-table(Data[,3],KnnFit)
+ errRatio<-c(errRatio,(1-sum(diag(CT))/sum(CT))*100)
+ }
> plot(errRatio,type="l",xlab="近邻个数K",ylab="错判率(%)",main="近邻数K与错判率",ylim=c(0,80))
#旁置法
> errRatio1<-vector()
> for(i in 1:30){
+ KnnFit<-knn(train=DataTrain[,1:2],test=DataTest[,1:2],cl=DataTrain[,3],k=i)
+ CT<-table(DataTest[,3],KnnFit)
+ errRatio1<-c(errRatio1,(1-sum(diag(CT))/sum(CT))*100)
+ }
> lines(1:30,errRatio1,lty=2,col=2)
#留一法
> set.seed(12345)
> errRatio2<-vector()
> for(i in 1:30){
+ KnnFit<-knn.cv(train=Data[,1:2],cl=Data[,3],k=i)
+ CT<-table(Data[,3],KnnFit)
+ errRatio2<-c(errRatio2,(1-sum(diag(CT))/sum(CT))*100)
+ }
> lines(1:30,errRatio2,col=2)
##############KNN回归 #################
> set.seed(12345)
> x1<-runif(60,-1,1)
> x2<-runif(60,-1,1)
> y<-runif(60,10,20)
> Data<-data.frame(Fx1=x1,Fx2=x2,Fy=y)
> SampleId<-sample(x=1:60,size=18)
> DataTest<-Data[SampleId,]
> DataTrain<-Data[-SampleId,]
> mseVector<-vector()
> for(i in 1:30){
+ KnnFit<-knn(train=DataTrain[,1:2],test=DataTest[,1:2],cl=DataTrain[,3],k=i,prob=FALSE)
+ KnnFit<-as.double(as.vector(KnnFit))
+ mse<-sum((DataTest[,3]-KnnFit)^2)/length(DataTest[,3])
+ mseVector<-c(mseVector,mse)
+ }
> plot(mseVector,type="l",xlab="近邻个数K",ylab="均方误差",main="近邻数K与均方误差",ylim=c(0,80))
全部样本:三角和圆圈分别表示0和1
训练样本和测试样本:红色的表示测试样本
邻近数K与错判率:黑线表示全部数据的错误率;红色实现表示留一法错误率;红色虚线表示旁置法。
邻近数K与均方误差:表示回归预测样本的均方误差,K=23时最小
##############天猫成交顾客的分类预测#######################
> library("class")
> Tmall_train<-read.table("G:\\R语言\\大三下半年\\R语言数据挖掘方法及应用\\天猫_Train_1.txt",header=TRUE,sep=",")
> head(Tmall_train)
BuyOrNot BuyDNactDN ActDNTotalDN BuyBBrand BuyHit
1 1 6.38 51.09 2.83 1.57
2 1 8.93 60.87 3.20 2.17
3 1 16.13 33.70 11.63 6.36
4 1 16.22 40.22 11.29 6.25
5 1 3.85 56.52 1.89 1.45
6 1 4.00 54.35 2.13 1.28
> Tmall_train$BuyOrNot<-as.factor(Tmall_train$BuyOrNot)
> Tmall_test<-read.table(file="天猫_Test_1.txt",header=TRUE,sep=",")
> Tmall_test$BuyOrNot<-as.factor(Tmall_test$BuyOrNot)
> set.seed(123456)
> errRatio<-vector()
> for(i in 1:30){
+ KnnFit<-knn(train=Tmall_train[,-1],test=Tmall_test[,-1],cl=Tmall_train[,1],k=i,prob=FALSE)
+ CT<-table(Tmall_test[,1],KnnFit)
+ errRatio<-c(errRatio,(1-sum(diag(CT))/sum(CT))*100)
+ }
> errRatio
[1] 1.707317 2.195122 2.804878 3.170732 3.292683 4.146341 3.292683 4.878049
[9] 5.975610 4.756098 5.365854 6.097561 6.341463 6.341463 6.341463 6.829268
[17] 8.048780 8.048780 8.048780 8.048780 8.048780 6.951220 6.829268 6.707317
[25] 8.048780 7.439024 8.048780 8.048780 8.048780 8.048780
> plot(errRatio,type="b",xlab="近邻个数K",ylab="错判率(%)",main="天猫成交顾客分类预测中的近邻数K与错判率")
根据图形分析,K=7时错误率为3.3%
####天猫数据KNN分类讨论变量重要性
#基于变量重要性的加权K-邻近法的基本原理####
> library("class")
> par(mfrow=c(2,2))
> set.seed(123456)
> errRatio<-vector()
> for(i in 1:30){
+ KnnFit<-knn(train=Tmall_train[,-1],test=Tmall_test[,-1],cl=Tmall_train[,1],k=i,prob=FALSE)
+ CT<-table(Tmall_test[,1],KnnFit)
+ errRatio<-c(errRatio,(1-sum(diag(CT))/sum(CT))*100)
+ }
> plot(errRatio,type="l",xlab="近邻个数K",ylab="错判率(%)",main="近邻数K与错判率")
> errDelteX<-errRatio[7]
> for(i in -2:-5){
+ fit<-knn(train=Tmall_train[,c(-1,i)],test=Tmall_test[,c(-1,i)],cl=Tmall_train[,1],k=7)
+ CT<-table(Tmall_test[,1],fit)
+ errDelteX<-c(errDelteX,(1-sum(diag(CT))/sum(CT))*100)
+ }
> plot(errDelteX,type="l",xlab="剔除变量",ylab="剔除错判率(%)",main="剔除变量与错判率(K=7)",cex.main=0.8)
> xTitle=c("1:全体变量","2:消费活跃度","3:活跃度","4:成交有效度","5:活动有效度")
> legend("topright",legend=xTitle,title="变量说明",lty=1,cex=0.2)
> FI<-errDelteX[-1]+1/4
> wi<-FI/sum(FI)
> GLabs<-paste(c("消费活跃度","活跃度","成交有效度","活动有效度"),round(wi,2),sep=":")
> pie(wi,labels=GLabs,clockwise=TRUE,main="输入变量权重",cex.main=0.8)
> ColPch=as.integer(as.vector(Tmall_test[,1]))+1
> plot(Tmall_test[,c(2,4)],pch=ColPch,cex=0.7,xlim=c(0,50),ylim=c(0,50),col=ColPch,
+ xlab="消费活跃度",ylab="成交有效度",main="二维特征空间中的观测",cex.main=0.8)
近邻数K与误判率为7时,误判率最小。
剔除变量与错误率:逐个剔除变量后错误率的变化,2表示消费活跃度,可以看出剔除之后错误率上升。
输入变量权重:每个变量的权重,可以看出消费活跃度为0.45。
############天猫数据加权KNN分类############
> #基于观测相似性的加权K-邻近法
> library("kknn")
> par(mfrow=c(2,1))
> Tmall_train<-read.table(file="天猫_Train_1.txt",header=TRUE,sep=",")
> Tmall_train$BuyOrNot<-as.factor(Tmall_train$BuyOrNot)
> fit<-train.kknn(formula=BuyOrNot~.,data=Tmall_train,kmax=11,distance=2,kernel=c("rectangular","triangular","gaussian"),na.action=na.omit())
> plot(fit$MISCLASS[,1]*100,type="l",main="不同核函数和近邻个数K下的错判率曲线图",cex.main=0.8,xlab="近邻个数K",ylab="错判率(%)")
> lines(fit$MISCLASS[,2]*100,lty=2,col=1)
> lines(fit$MISCLASS[,3]*100,lty=3,col=2)
> legend("topleft",legend=c("rectangular","triangular","gaussian"),lty=c(1,2,3),col=c(1,1,2),cex=0.4) #给出图例
#利用加权K最近邻
> Tmall_test<-read.table(file="天猫_Test_1.txt",header=TRUE,sep=",")
> Tmall_test$BuyOrNot<-as.factor(Tmall_test$BuyOrNot)
> fit<-kknn(formula=BuyOrNot~.,train=Tmall_train,test=Tmall_test,k=7,distance=2,kernel="gaussian",na.action=na.omit())
> CT<-table(Tmall_test[,1],fit$fitted.values)
> errRatio<-(1-sum(diag(CT))/sum(CT))*100
> errRatio
[1] 2.804878
#利用K-近邻分类
> library("class")
> fit<-knn(train=Tmall_train,test=Tmall_test,cl=Tmall_train$BuyOrNot,k=7)
> CT<-table(Tmall_test[,1],fit)
> errRatio<-c(errRatio,(1-sum(diag(CT))/sum(CT))*100)
> errGraph<-barplot(errRatio,main="加权K近邻法与K近邻法的错判率对比图(K=7)",cex.main=0.8,xlab="分类方法",ylab="错判率(%)",axes=FALSE)
> axis(side=1,at=c(0,errGraph,3),labels=c("","加权K-近邻法","K-近邻法",""),tcl=0.25)
> axis(side=2,tcl=0.25)
> errRatio
[1] 2.804878 3.292683
|
请发表评论