K近邻法及其实现

KNN(K-Nearest Neighbor) 算法是机器学习算法中最基础的算法之一,它既能用于分类,又能用于回归。有别于其他经典的机器学习算法,其没有显式的学习过程。
模型:利用训练数据划分特征向量空间,其结果就是最终算法模型。
基本思想是:任意 N 维输入向量对应于特征空间的一点,输出为该特征向量所对应的类别标签或者预测值。

KNN 分类

KNN 用于分类,其过程简单的说就是:

  1. 输入需要预测离散值的实例,
  2. 通过指定的距离度量找出离它最近的 k 个训练数据,
  3. 根据这 k 个训练数据的标签,通过一个决策规则来决定输入实例的列类别。

KNN模型的基本要素为:

  • 距离度量:通常使用欧式距离(p=2),或更一般的 L p Lp Lp 距离;
  • k 值的选择:通常取比较小的值(k 值单位是个,所以必须选大于 0 的整数),当 k 取 1 时就是最近邻算法。但要注意,k 值取过小会导致模型过于复杂,方差过大,导致过拟合;k 值取过大会使模型过于简单,偏差较大,导致欠拟合;
  • 分类决策规则:通常使用多数表决的决策规则,即认为 k 个邻近值中最多的标签便是输入值的分类结果。
KNN分类算法的Python实现:

完整代码见 Github

# 环境:Python3.6,测试通过.
# 需要给定训练集和测试集 X_train, y_train; X_test, y_test(类型为ndarray)
import numpy as np
from collections import Counter
# 核心函数
def knn_single_predict(x, k=3, p=2):
    """
    knn分类算法预测函数(单个实例):
    输入 -- 单个实例 X,邻近数 k,距离度量 p
    输出 -- 该输入实例的类别
    """
    # 1. 初始化,用于后续更新。计算出 x 与前三个训练实例点的距离
    knn_list = []  # 存放邻近点的距离和类别
    for i in range(k):
        dist = np.linalg.norm(x - X_train[i], ord=p)
        knn_list.append((dist, y_train[i]))
    # 2. linear scan(kd tree 效率更高). 找到更小的值就更新.
    for i in range(k, len(X_train)):
        max_index = knn_list.index(max(knn_list, key=lambda x: x[0]))
        dist = np.linalg.norm(x - X_train[i], ord=p)
        if knn_list[max_index][0] > dist:
            knn_list[max_index] = (dist, y_train[i])
            
    # 3. 分类决策规则:多数表决
    knn = [k[-1] for k in knn_list]
    count_pairs = Counter(knn)   # 根据列表频数生成字典,key为类别值,values为类别值频数
    # 按values升序排序后取出出现最多的类别
    max_count = sorted(count_pairs.items(), key=lambda x: x[1])[-1][0]  
    return max_count


# 对多个实例
def knn_predict(X):
	"""
	knn预测函数(单个或多个实例)
	"""
    y_pred = []  # 初始化一个列表,存放每个输入实例的预测类
    if X.ndim == 1:   # 单个实例
        y_pred = knn_single_predict(X)
    else:
        for i in range(len(X)):   # 依次判断每个输入实例的类别
            y_pred.append(knn_single_predict(X[i]))
    return y_pred


y_pred = knn_predict(X)
print(y_pred)
def score(y_pred):
    """
    评分:
    计算分类正确的实例数占总数的比例
    """
    y_pred = knn_predict(X_test)
    right_count = (y_pred == y_test).sum()
    rate = right_count / len(y_test)
    return rate

y_pred = knn_predict(X_test)
rate = score(y_pred)
print(rate)
KNN分类算法的sklearn实现

官方文档

class sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, weights=’uniform’, algorithm=’auto’, leaf_size=30, p=2, metric=’minkowski’, metric_params=None, n_jobs=None, **kwargs)[source]

  • n_neighbors:邻近的点个数,默认为 5
  • weights:权重度量,默认为 “uniform”,表示所有 k 个近邻在分类时重要性选取是一样的
  • ……
from sklearn.neighbors import KNeighborsClassifier

clf = KNeighborsClassifier()
clf.fit(X_train, y_train)
# clf.predict(X_test)
clf.score(X_test, y_test)

KNN回归

KNN主要用来分类,但其也能用于回归预测:

  1. 在训练集上寻找与输入实例最相近的 K 个近邻;
  2. 对这 K 个样本的因变量值取均值,作为输入实例的预测值.

参考:
[1] 李航. 《统计学习方法》.
[2] 章华燕. 《机器学习算法各个击破》.
[3] https://github.com/fengdu78/lihang-code/blob/master/code / 第 3 章 k 近邻法 (KNearestNeighbors)/KNN.ipynb

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值