KNN算法(KNN, K-Nearest Neighbors)
iris.arff数据集包含了150条关于花的数据,这些数据被等分为3类Iris物种:Setosa、Versicolor和Virginica,每朵花的数据描述有四项特征:花萼长度、花萼宽度、花瓣长度和花瓣宽度。
问题:简述K近邻分类算法的思想和优缺点,并通过KNN算法预测测试数据的物种分类,请写出详细的算法过程。
K近邻(K Nearest Neighbors)算法又称为KNN算法,是一种非常直观并且容易理解和实现的有监督分类算法。该算法的基本思想是寻找与待分类的样本在特征空间中距离最近的K个已标记样本(即K个近邻),以这些样本的标记为参考,通过投票等方式,将占比最高的类别标记赋给待标记样本。【该方法被形象地描述为“近朱者赤,近墨者黑”】
K近邻算法的优点:
K近邻算法的缺点:
import numpy as np
import operator as opt
import matplotlib.pyplot as plt
import collections as clt
from sklearn import datasets
# K-近邻算法 鸢尾花数据测试
# KNN分类算法
# 算法描述:
# 1.参数说明:待分类向量x、训练数据集(特征向量组)A、标签向量、参数(k)
# 2.计算x与A中所有向量的距离,并返回排序索引数组
# 3.标签向量使用2中的索引数组,取出前k个标签名,出现次数最多的就是x的标签
def KNN(x, dataSet, lable, k):
assert 1 <= k <= dataSet.shape[0] ," k must be valid "
assert dataSet.shape[0]==lable.shape[0],"数据集和标签集不对等"
assert x.shape[0] == dataSet.shape[1],"待测数据与数据集特征数不相等"
# 计算距离
# 计算测试数据集rows(数据量)
dataSetSize = dataSet.shape[0]
# 将x扩展为dataSet同大小的矩阵,
# 使用numpy中的universal function对矩阵元素分别进行计算的原则,避免使用循环
X = np.tile(x, (dataSetSize, 1)) # 复制dataSetSize-1个x向量
# 计算距离
distances = (((X-dataSet)**2).sum(axis=1))**0.5
# 根据距离进行排序,并返回索引数组
index_SortByDistance = distances.argsort()
# 获取距离最近的三个标签
hyperLables = []
for i in range(k):
hyperLables.append(lable[index_SortByDistance[i]])
# 获取出现次数最多的标签
return clt.Counter(hyperLables).most_common(1)[0][0]
# 获取鸢尾花数据集
iris = datasets.load_iris()
# 训练数据:每种花选取25个数据,注意标签要和数据一一对应
datasets = np.vstack(
(iris.data[0:25, ...], iris.data[50:75, ...], iris.data[100:125, ...]))
lable = np.hstack(
(iris.target[0:25], iris.target[50:75], iris.target[100:125]))
# 遍历剩下的待分类数据
a = [i for i in range(150) if ((i >= 25) and (i < 50)) or (
(i >= 75) and (i < 100)) or ((i >= 125) and (i < 150))]
success_num = 0
fail_num = 0
for i in a:
x = iris.data[i, ...]
xtarget = KNN(x, datasets, lable, 1)
if(iris.target_names[xtarget] == iris.target_names[iris.target[i]]):
# print("分类成功")
success_num += 1
else:
# print("分类失败")
fail_num += 1
print("分类完成:成功({});失败({})".format(success_num, fail_num))
使用已经封装好的KNN算法
import numpy as np
from sklearn.neighbors import KNeighborsClassifier as KNN
from sklearn import datasets
# 获取鸢尾花数据集
iris = datasets.load_iris()
# 训练数据:每种花选取25个数据,注意标签要和数据一一对应
dataSet = np.vstack((iris.data[0:25, ...], iris.data[50:75, ...], iris.data[100:125, ...]))
lable = np.hstack((iris.target[0:25], iris.target[50:75], iris.target[100:125]))
# 创建KNN分类器
# 1.sklearn 中的算法都被包装成面向对象风格,因此使用算法时,要先实例化
KNN_classifier = KNN(n_neighbors=6) #规定 k = 6
# 2.fit 为训练模型的过程,由于KNN本质上无模型,但是为了和别的算法统一,将训练数据集当作模型
KNN_classifier.fit(dataSet,lable)
# 3.进行预测(分类)
X = np.vstack((iris.data[25:50, ...], iris.data[75:100, ...], iris.data[125:150, ...]))
result = KNN_classifier.predict(X)
print(result)
在Scikit-learn模块中,分类模型是一个python 对象,它实现了fit(X,y)和predict(T)等方法。
# 导入iris数据集
from sklearn.datasets import load_iris
# 分割数据模块
from sklearn.model_selection import train_test_split
# K最近邻(KNN,K-Nearest Neighbor)分类算法
from sklearn.neighbors import KNeighborsClassifier
# 加载iris数据集
iris = load_iris()
X = iris.data
y = iris.target
# 分割数据
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=4)
2.建立模型进行训练和预测
# 建立模型
knn = KNeighborsClassifier()
# 训练模型
knn.fit(X_train, y_train)
# 预测模型
knn.predict(X_test)