数据挖掘——KNN算法预测测试数据的物种分类

KNN算法(KNN, K-Nearest Neighbors)

iris.arff数据集包含了150条关于花的数据,这些数据被等分为3类Iris物种:Setosa、Versicolor和Virginica,每朵花的数据描述有四项特征:花萼长度、花萼宽度、花瓣长度和花瓣宽度。

问题:简述K近邻分类算法的思想和优缺点,并通过KNN算法预测测试数据的物种分类,请写出详细的算法过程。

K近邻(K Nearest Neighbors)算法又称为KNN算法,是一种非常直观并且容易理解和实现的有监督分类算法。该算法的基本思想是寻找与待分类的样本在特征空间中距离最近的K个已标记样本(即K个近邻),以这些样本的标记为参考,通过投票等方式,将占比最高的类别标记赋给待标记样本。【该方法被形象地描述为“近朱者赤,近墨者黑”

  • KNN分类决策需要待标记样本与所有训练样本作比较,不具有显示的参数学习过程,在训练阶段仅仅是将样本保存起来,训练时间为零,可以看做直接预测。
  • KNN算法需要确定K值、距离度量和分类决策规则。
  • 随着K取值的不同,会获得不同的分类结果。
  • 一般地,K值过小时,只有少量的训练样本对预测起作用,容易发生过拟合,或者受含噪声训练数据的干扰导致预测错误;反之,K值过大时,过多的训练样本对预测起作用,当不同类别样本数量不均衡时,结果将偏向数量占优的样本,也容易产生预测错误。
  • 实际应用中,K值一般取较小的奇数。
  • 一般以分类错误率或者平均误差等作为评价标准,采用交叉验证法选取最优的K值。当K = 1时,该算法又称为最近邻算法。

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)等方法。

  • fit方法实现了模型的训练
  • predict方法实现了模型的预测
  • 模型的构造函数以相应模型的参数作为参数,目前我们只需将KNN分类模型视为黑箱即可。
  1. 数据的导入
# 导入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)
  • 分类决策通常采用多数表决。当分类决策目标是最小化分类错误率时,多数表决规则等价于经验风险(即误分率)最小化。 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(数据挖掘,数据挖掘,机器学习)