KNN代码

import numpy as np
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier  #导入knn
from sklearn.model_selection import train_test_split  #导入训练集测试集划分
# KNN算法 全部用sklearn的包实现-

# 当我们有一个数据集data,data是包含数据和标签的,我们得先把他们分开

x = data.iloc[:,:-1]  #iloc方法,选择所有行,列不包括最后一个行列(假设最后一列是target)
y = data.iloc[:,-1]   #iloc方法,选所有行,仅选择最后一列(假设最后一列是target)
#还有一个loc的用法,loc是靠columns选择数据的
Xtrain,Xtest,Ytrain,Ytest = train_test_split(x,y,test_size=0.2,random_state=420)  #这里数据集划分要牢记【先x后y】

clf = KNeighborsClassifier(n_neighbors=3)  #n_neighbors表示k的个数
clf = clf.fit(Xtrain,Ytrain)  #开始拟合
score = clf.score(Xtest,Ytest)  #评分
result = clf.predict()  #当然也可以有预测


# 当然平常时候我们不知道k取多少,这时候可以绘制一个学习曲线(循环20次),看看k为多少的时候score最高
import matplotlib.pyplot as plt
score = [ ] 
krange = range(1,20) 
for i in krange:
	clf = KNeighborsClassifier(n_neighbors=i) 
	clf = clf.fit(Xtrain,Ytrain) 
	score.append(clf.score(Xtest,Ytest)) 
plt.plot(krange,score) 
plt.show()
print(score.index(max(score))+1)  #输出一下score最高值对应的k为多少

又出现一些新问题了,当我们划分数据集的时候,由于是随机划分的,得分最高的k值肯定也不一样,这是我们要引入交叉检验了(k折检验)

from sklearn.model_selection import cross_val_score as CVS
Xtrain,Xtest,Ytrain,Ytest = train_test_split(x,y,test_size=0.2,random_state=420)
clf = KNeighborsClassifier(n_neighbors=3)
cvs = CVS(clf,Xtrain,Ytrain,cv = 5)   #训练集对折五次,一共五个结果输出
print(cvs.mean())  #均值,查看模型的平均效果
print(cvs.var())  #方差,查看模型是否稳定

好了,这时候我们可以总结一下

score = [ ] 
var = [ ]
krange = range(1,20) 
for i in krange:
	clf = KNeighborsClassifier(n_neighbors=i) 
	cvs = CVS(clf,Xtrain,Ytrain,cv = 5)
	score.append(cvs.mean())
	var.append(cvs.var())
plt.plot(krange,score,color='k') 
plt.plot(krange,np.array(score)+np.array(var)*2,c='red',linestyle='--') 
plt.plot(krange,np.array(score)-np.array(var)*2,c='red',linestyle='--')
# 把图像画出来,另外多画两条,一条是均值+方差,一条均值-方差,这里主要是看近等评分下,那个k更加稳定

接下来又有一个问题,由于knn的计算涉及到距离,这时候要是各个指标的量纲差距过大,这听起来一点也不好,所以我们得【归一化】

(Normalization,又称 Min-Max Scaling)

这里有个值得注意的一点,【先划分数据集和测试集,在进行归一化!】

from sklearn.preprocessing import MinMaxScaler as mms
Xtrain,Xtest,Ytrain,Ytest = train_test_split(x,y,test_size=0.2,random_state=420)

MMS_01=mms().fit(Xtrain) #求训练集最大/小值 
MMS_02=mms().fit(Xtest) #求测试集最大/小值

#转换 
X_train=MMS_01.transform(Xtrain) 
X_test =MMS_02.transform(Xtest)

score = [ ] 
var = [ ]
krange = range(1,20) 
for i in krange:
	clf = KNeighborsClassifier(n_neighbors=i) 
	cvs = CVS(clf,X_train,Y_train,cv = 5)
	score.append(cvs.mean())
	var.append(cvs.var())
plt.plot(krange,score,color='k') 
plt.plot(krange,np.array(score)+np.array(var)*2,c='red',linestyle='--') 
plt.plot(krange,np.array(score)-np.array(var)*2,c='red',linestyle='--')
print(score.index(max(score))+1)  #输出一下score最高值对应的k为多少

现在又有一个额外的小问题,

knn的方法采取的是一点一票的方法,看在一个范围内哪个阵营的人多,

但是按常理来讲,一个未知的点肯定和距离他更近的点更加相似,

假如k为8时,一个点的5个邻居离他较远,3个邻居离他很近,

这时候knn会将他判断为5人组里,但是生活中我们肯定会判断给三人组

这时候就要加上【距离惩罚】,但是优化效果得在实际中慢慢斟酌,

适合那些异常点较多的数据集里

用法:加入weights = ‘distance’,表示加上距离惩罚

score = [ ] 
var = [ ]
krange = range(1,20) 
for i in krange:
	clf = KNeighborsClassifier(n_neighbors=i,weights='distance') 
	cvs = CVS(clf,X_train,Y_train,cv = 5)
	score.append(cvs.mean())
	var.append(cvs.var())
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值