KNN算法总结-python实现

K最近邻(kNN,k-NearestNeighbor)分类算法所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。用的是近朱者赤近墨者黑的思想。KNN没有显式的学习过程,也就是说没有训练阶段,数据集事先已有了分类和特征值,待收到新样本后直接进行处理。

思路是:如果一个样本在特征空间中的k个最邻近的样本中的大多数属于某一个类别,则该样本也划分为这个类别。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。

我们要确定绿点属于哪个颜色(红色或者蓝色),要做的就是选出距离目标点距离最近的k个点,看这k个点的大多数颜色是什么颜色。当k取3的时候,我们可以看出距离最近的三个,分别是红色、红色、蓝色,因此得到目标点为红色。

KNN执行过程

1)计算测试数据与各个训练数据之间的距离;

2)按照距离的递增关系进行排序;

3)选取距离最小的K个点;

4)确定前K个点所在类别的出现频率;

5)返回前K个点中出现频率最高的类别作为测试数据的预测分类

KNN伪代码

Input: 训练数据data、待预测样本x、k
	Ouput:待预测样本所属类别y
		# 1. 计算待预测样本和所有训练数据的距离/相似度
		D = []
		idx = 0
		for train_x in data.x:
			# a. 使用欧式距离公式计算两个样本之间的距离
			distince = calc_distince(train_x, x)
			# b. 距离保存
			D.append((distince, idx))
			idx += 1
				
		
		# 2. 从所有训练数据中,获取距离最近/相似度最大的K个邻近样本
		sorted(D) # 排序,默认为升序
		N = D[:k] # 获取这个距离最近的K个
		
		# 3. 将这K个邻近样本中出现数目最多的类别作为当前待预测样本的预测值。
		# a. 统计各个类别出现的次数
		label_2_count = {}
		for distince,idx in N:
			label = data.y[idx]
			label_2_count[label] = label_2_count.get(label,0) + 1
		# b. 从统计结果中获取出现次数最多的那个类别
		max_count = 0
		y = None
		for label, count in label_2_count.items():
			if count > max_count:
				y = label
				count = max_count
		
		return y

如上代码的缺陷:消耗空间大,需要保存所有的距离吗,是不是可以直接保存前k小的距离就可以,在保存距离的时候用插入法,从小到大排序,如果有比最后一个数小的距离,则插入到列表,删除最后最后一个数据。

KNN缺陷

  1. 计算开销大,分类效率低;   -->解决方案:KDTree
  2. K值难以确认,不同近邻样本数,对分类准确程度影响较大;(K过大->欠拟合, K过小->过拟合)  --> 一般情况20~50之间居多,具体的会通过GridSearchCV来选择
  3. 样本向量以及距离的度量公式之间的选择

KDTree构建过程

1.采用m个样本中的n个属性进行划分
2.分别计算n个属性特征的方差,进行从大到小的排序
3.选取方差最大的属性作为划分,选取样本的中位数点nkv,以此样本点为根节点,将该属性特征小于Nvk的样本的放在左子树上,大于的放在右子树上。
4.根据方差第二大的属性进行左,右子树的划分,同上述过程。
5.循环迭代,数据集划分完毕

a、KDTree是如何解决KNN的缺陷的
      KDTree解决了KNN中在大数据量的情况下,求解K个近邻样本计算量过大的问题。在构建KDTree的时候,选择的是方差最大的特征属性的特征属性中值作为数据分割点,将数据分割为左右两个数据子集,然后再左右两个数据子集中继续按照这种方式进行划分;这样构建出来的KDTree在查询数据的时候可以保障尽可能少的搜索分支(因为方差大表示数据比较离散)

b、除了KDTree之外,还有没有其他方式来解决该问题?

     BallTree

c、KDTree除了可以用于KNN解决KNN的问题外,KDTree还可以应用到哪些场景?
     KDTree的主要功能实际上是加速数据的检索。
        eg:
            人脸识别(人脸打卡、人脸支付....)
            聊天机器人(检索式)

python实现KNN

from collections import Counter
import numpy as np


class KnnScratch(object):

    def fit(self, x_train, y_train):
        self.x_train = x_train
        self.y_train = y_train
    

    def predict_once(self, x_test, k): #预测单个样本
        lst_distance = []
        lst_predict = []

        for i in xrange(len(self.x_train)):
            # euclidean distance
            distance = np.linalg.norm(x_test - self.x_train[i, :])

        lst_distance = sorted(lst_distance)

        for i in xrange(k):
            idx = lst_distance[i][1]
            lst_predict.append(self.y_train[idx])

        return Counter(lst_predict).most_common(1)[0][0]

    def predict(self, x_test, k): # 批量预测
        lst_predict = []
        for i in xrange(len(x_test)):
            lst_predict.append(self.predict_once(x_test[i, :], k))

        return lst_predict

if __name__ == '__main__':
    x_train = np.array([[1, 1, 1], [2, 2, 2], [10, 10, 10], [13, 13, 13]])
    y_train = ['aa', 'aa', 'bb', 'bb']
    x_test = np.array([[3, 2, 4], [9, 13, 11]])

    knn = KnnScratch()
    knn.fit(x_train, y_train)

    print knn.predict_once(x_test[0], 2)
    # aa

    print knn.predict(x_test, 2)
    # ['aa', 'bb']

sklearn实现KNN

#-*- coding: UTF-8 -*-
from sklearn import neighbors
from sklearn import datasets
from sklearn.model_selection import train_test_split

# 加载数据
iris = datasets.load_iris()
# 数据划分
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.5, random_state=2)
# 模型加载
knn = neighbors.KNeighborsClassifier()
knn.fit(X_train, y_train)

# 模型评估

print("训练集准确率:",knn.score(X_train,y_train))
print("测试集准确率:",knn.score(X_test,y_test))

# 预测
predicted = knn.predict(X_test)
print(predicted)

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: knn算法(k-近邻算法)是一种分类和回归的算法,被广泛应用于模式识别、数据挖掘、图形识别等领域。其原理是根据数据本身的特征,将测试集中的每一个样本按照特征相似度进行分类。其中,k的值表示选择多少个最相似的邻居作为判断依据,通常采用欧氏距离来计算相似度。 在knn算法实现过程中,需要先将数据集分为训练集和测试集。接着,通过计算测试集中每一个样本与训练集中每一个样本的欧氏距离(或曼哈顿距离等),选择距离最近的k个邻居。最后,采用“多数表决”的方式选择样本类别,并将该类别赋给测试集中的样本。 在Python中,可以使用scikit-learn库实现knn算法。以下是一个简单的代码示例: from sklearn.neighbors import KNeighborsClassifier # 创建训练集和测试集 train_x = [[0], [1], [2], [3]] train_y = [0, 0, 1, 1] test_x = [[1.5]] # 创建knn分类器(k=2) knn = KNeighborsClassifier(n_neighbors=2) # 拟合模型 knn.fit(train_x, train_y) # 进行预测 print(knn.predict(test_x)) 以上代码中,第一行引用了scikit-learn库下的KNeighborsClassifier类,用于创建一个knn分类器。接着,分别创建了训练集和测试集,并针对训练集中的两类样本对应标签进行了标记。接下来,创建k值为2的knn分类器,并使用fit()方法对训练集进行拟合。最后,通过predict()方法进行实际的预测,并输出测试样本的分类结果。 总体来说,knn算法是一种简单易用的分类和回归算法,具有可解释性强、不受算法实现形式的特点,同时能够适应各种数据类型和特征。在Python中,采用scikit-learn库实现knn算法也非常方便。 ### 回答2: KNN算法是一种基于实例的学习方法,通过计算样本之间的距离来确定新样本的类别。KNN算法是一种简单而有效的分类方法,尤其适用于小数据集。算法原理是基于这样一种思想:样本空间中的每个样本都可以用它最近的K个邻居来代表。其中K是一个正整数,是预定的参数。当K=1时,为最近邻分类算法,即只考虑最近的一个邻居。 具体实现步骤: 1.读入数据集,并将其分为训练集和测试集。 2.对数据集进行归一化处理。 3.对每个测试实例,计算其与训练集中所有实例之间的距离。 4.按照距离的大小降序排列。 5.选取前K个距离最小的实例,得到它们所属的类别中出现次数最多的那个类别作为该测试实例的预测类别。 6.计算预测结果与实际结果的差异。 在Python实现KNN算法需要用到一些基本的库:Numpy和Scikit-learn。具体步骤如下: 1.导入Numpy库。 2.导入数据集并将其分为训练集和测试集。 3.使用Scikit-learn库中的MinMaxScaler函数进行数据归一化处理。 4.使用Scikit-learn库中的KNeighborsClassifier函数进行训练,设定参数k和metric。 5.使用Scikit-learn库中的predict函数进行预测,得到预测结果。 6.计算预测结果与实际结果的差异,得到预测准确率。 KNN算法的优点是简单易懂,精度高;缺点是计算复杂度高,对数据的大小敏感。当数据维度较高时,其计算复杂度会变得极高,而且KNN算法对数据的距离非常敏感,如果数据特征选取不当,会导致预测精度大幅下降。因此,在使用KNN算法的时候需要注意数据特征的选取和K值的选择。 ### 回答3: K近邻(k-NN)算法是最简单的基于实例的学习算法之一,它的主要思想是使用距离度量来对特征空间中的样本进行分类。KNN算法中的K代表选择邻居的数量,邻居是指在训练集中与测试数据距离最近的样本点。KNN算法的基本步骤如下: 1. 计算测试数据与所有训练数据之间的距离。 2. 根据距离度量,对距离最近的K个样本进行投票。 3. 根据投票结果,决定测试数据属于哪一类别。 KNN算法的优点是简单易用,能够处理多分类和回归问题;缺点是计算量大,对训练数据敏感,需要进行归一化处理,并需要选择合适的距离度量和K值。 Python实现KNN算法需要使用Scikit-learn或Numpy等相关库。下面给出一个简单的Python代码实现,该代码实现了一个基于欧氏距离的KNN分类器: ``` import numpy as np from sklearn.neighbors import KNeighborsClassifier # 生成训练数据 X_train = np.array([[1, 2], [3, 4], [5, 6], [7, 8]]) y_train = np.array([0, 0, 1, 1]) # 创建KNN分类器,选择K=3 clf = KNeighborsClassifier(n_neighbors=3) # 训练分类器 clf.fit(X_train, y_train) # 测试数据,预测其所属类别 X_test = np.array([[2, 3], [4, 5], [6, 7]]) y_test = clf.predict(X_test) print(y_test) ``` 该代码中,通过Numpy库生成了一个4个样本点的训练数据集,其中前两个样本属于类别0,后两个样本属于类别1。同时,也生成了3个测试数据点。然后使用Scikit-learn库中的KNN分类器,在训练数据上训练模型,选择K=3。最后,对测试数据进行分类,并输出分类结果。 以上就是KNN算法的基本原理和Python实现,希望对读者有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值