#机器学习之K近邻算法#
##欧氏距离##
欧式距离(Euclidean Distance)计算公式:两个n维向量a(x11,x12,…,x1n)a(x11,x12,…,x1n)与b(x21,x22,…,x2n)b(x21,x22,…,x2n)间的欧氏距离:
注:除欧氏距离外,还有其他距离,如夹角余弦,汉明距离,曼哈顿距离,闵可夫斯基距离等
##Python代码实现##
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 23 11:22:24 2019
@author: LinQH
"""
import numpy as np
import operator
#创建数据集#
def creatdatasets():
data = np.array([[2.4,33],[2.1,22],[5.6,32],[3.3,16]])
labels = ["dog","cat","bag","suit"]
return data,labels
#knn算法#
def knn_classify(x_test, datasets, labels, k):
"""
x_test: 测试集
datasets:特征值数据
labels: 数据标签
k:最邻近参数
"""
#求解未知点到已知点的欧氏距离#
dataSetSize = datasets.shape[0] # shape[0]返回dataSet的行数
diffMat = np.tile(x_test, (dataSetSize,1)) - datasets # tile(inX,(a,b))函数将inX重复a行,重复b列
sqDiffMat = diffMat**2 #作差后平方
sqDistances = sqDiffMat.sum(axis=1)#sum()求和函数,sum(0)每列所有元素相加,sum(1)每行所有元素相加
distances = sqDistances**0.5 #开平方,求欧式距离
#得到欧氏距离之后进行从小到大排序#
sortedDistIndicies = distances.argsort() #argsort函数返回的是数组值从小到大的索引值
classCount={}
#取出前k个距离对应的标签 #
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
#计算每个类别的样本数。字典get()函数返回指定键的值,如果值不在字典中返回默认值0
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
#reverse降序排列字典
#python2版本中的iteritems()换成python3的items()
#key=operator.itemgetter(1)按照字典的值(value)进行排序
#key=operator.itemgetter(0)按照字典的键(key)进行排序
return sortedClassCount[0][0] #返回字典的第一条的key,也即是测试样本所属类别
#执行函数#
if __name__ == '__main__':
#未知类别数据
testdata = [1.8,25]
k=3
#获取数据集
x,y = creatdatasets()
y_predict = knn_classify(testdata,x,y,k)
print(y_predict)
#结果#
cat
#KNN算法实例(利用sklearnAPI)##
*鸢尾花数据集分类Python代码实现:
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 23 09:26:12 2019
@author: LinQH
"""
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import pandas as pd
import numpy as np
def knn_class():
iris_data = load_iris()
#print(iris_data.data[0:10])
#print(iris_data.target[0:10])
#print(iris_data.feature_names)
#print(iris_data.target_names)
#合并数据,设置标签
#iris_data = pd.DataFrame(iris_data.data,index = (iris_data.target),columns = (iris_data.feature_names))
#print(iris_data.head(200))
#standardscale
SS = StandardScaler()
x = SS.fit_transform(iris_data.data)
#非标准化数据
#x = iris_data.data
y = iris_data.target
#划分数据集
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size = 0.25)
#输入训练(KNN模型)
KNN = KNeighborsClassifier(n_neighbors = 5)
KNN.fit(x_train,y_train)
#预测模型
y_predict = KNN.predict(x_test)
print(y_predict)
score = KNN.score(x_test,y_test)
print(score)
if __name__ == "__main__ ":
score = knn_class()
利用sklearn中KNeighborsClassifierAPI实现100%正确识别率
##KNN算法总结:##
1.k值取值
k值取很小时:容易受到异常点(离群点)影响
k值取很大时:容易受到类别数量影响(相近的类别有多个)
2.KNN算法
优点:算法简单,易于实现
缺点:样本数据量大时,计算速度极慢,结果容易受到k取值影响
3.注意:
使用KNN分类前,一般要对数值数据进行标准化处理