从今天开始学习K最近邻算法(K-Nearest Neighbors),简称KNN算法。KNN算法的原理也很简单,用一句话来说就是"近朱者赤,近墨者黑"。首先来说,KNN算法属于监督学习模型中的分类算法(但是KNN也可以用于回归分析),原理简单易懂,算法容易理解,实在是居家必备,装逼秀操作的好算法。
原理介绍:
那么问题来了,如何判断球球的的类别呢?很多同学可能都想得到,它离谁比较近,就归哪一类呗。其实这就是KNN算法的基本原理:如果要判断球球属于哪一类别,首先计算球球和所有数据的距离(可以理解成相似度,距离用的是闵可夫斯基距离),然后筛选出距离最近的五个(这个可以根据数据的类型自行选择)数据,把类别出现频率最高的那个赋给球球,作为其类别。所以KNN算法可以用在很多分类领域发挥它的用途,比如说手写体数字的识别,花的种类识别啊等等。但是呢,KNN算法很勤快,它一般不会保存训练模型,每一次都是现场运算。其次KNN算法不适合不均衡的数据集,主要原因就好比说男生只有一个,女生有十个,问另一个不知性别的小朋友的性别,这时候明显即使是位男生,也无力反驳自己不是女生了。最重要的是KNN算法的计算量很大,对于较大的数据集也是不合适的,所以通常进行数据归一化是必须的!以上是对KNN算法的简要介绍。
上面给出的就是KNN模型的原理,可以说是最简单的算法了。下面我们就来具体实战了。首先老样子,从Sklearn,Tensorflow和自行搭建三个角度完成KNN算法。数据集下载提取码 qt2a
数据集的样子
User ID Gender Age EstimatedSalary Purchased
0 15624510 Male 19 19000 0
1 15810944 Male 35 20000 0
2 15668575 Female 26 43000 0
3 15603246 Female 27 57000 0
4 15804002 Male 19 76000 0
.. ... ... ... ... ...
395 15691863 Female 46 41000 1
396 15706071 Male 51 23000 1
397 15654296 Female 50 20000 1
398 15755018 Male 36 33000 0
399 15594041 Female 49 36000 1
[400 rows x 5 columns]
#数据表示的是性别,年龄和工资状况对是否购买某一产品的影响
1、Sklearn的KNN模型
from sklearn.model_selection import train_test_split#导入数据集拆分
from sklearn.preprocessing import StandardScaler as SS#导入归一化
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier as nn#导入KNN模型
from sklearn.preprocessing import LabelEncoder as LE#导入编码字符
from sklearn.preprocessing import OneHotEncoder as OE#导入OneHot编码
from sklearn.metrics import confusion_matrix#导入混淆矩阵
dataset=pd.read_csv(path)
x=dataset.iloc[:,1:4].values
y=dataset.iloc[:,4].values
le=LE().fit(x[:,0])
x[:,0]=le.fit_transform(x[:,0])#对男女性别进行编码
#oe=OE(categorical_features=[0])
#x=oe.fit_transform(x).toarray()
ss=SS()
x=ss.fit_transform(x)#数据归一化处理
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=0)#拆分数据集
knn=nn(n_neighbors=5,n_jobs=-1,weights='distance')#设定KNN模型参数,第一个表示选取的范围,第二个表示调用cpu的数量,第三个是对距离进行加权,距离越大得分越小
knn.fit(x_train,y_train)
y_pre=knn.predict(x_test)#进行预测
confusion=confusion_matrix(y_test,y_pre)#用混淆矩阵表示精确度
print(confusion)#正对角线表示判断正确数量,负对角线表示错误数量
以上就是对KNN模型的Sklearn的实现。下面就是自己动手操作写一写KNN模型
2、Numpy的KNN模型
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler as SS
import pandas as pd
from sklearn.preprocessing import LabelEncoder as LE
from sklearn.metrics import confusion_matrix
import operator
dataset=pd.read_csv(path)
x=dataset.iloc[:,1:4].values
y=dataset.iloc[:,4].values
le=LE().fit(x[:,0])
x[:,0]=le.fit_transform(x[:,0])
ss=SS()
x=ss.fit_transform(x)
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=0)
#以上步骤是对数据进行预处理
def knn(x_test,x,y):
shape=x.shape#获取训练集x的形状
X=np.tile(x_test,(shape[0],1))#将测试单元扩展为和训练集一样的形状,x_test为一行向量特征,注意理解为什么只取形状中的第一维
sq=np.square(x-X)
distance=np.sum(sq,axis=1)#以上是计算距离
rank=np.argsort(distance)#将距离进行排序,排列的内容就是索引
index=[y[rank[0]],y[rank[1]],y[rank[2]],y[rank[3]],y[rank[4]]]#获取前五个最小的索引
index_set=set(index)#将列表转换为集合,目的是去除重复值
zeros=[]
for i in range(len(index_set)):
zeros.append(0)#生成0列表
index_dict=dict(zip(index_set,zeros))#合并为字典
for i in index:
index_dict[i]+=1#计算类别出现的数目
result=sorted(index_dict.items(),key=operator.itemgetter(1),reverse=True)#对类别出现数量的大小作排序,注意对sorted()函数的使用和operator库中关键词索引,可以理解为字典的排序方法
return result[0][0]#返回出现最多的类别
以上部分便是所有KNN算法的实现,我太菜了,呜呜,TensorFlow还实现不了,所以就只写了这些。但是KNN算法确实太简单了,用TensorFlow反而大材小用了(极力为自己辩护),但是确实是自己实力还不够,我还得要变强。