机器学习:K近邻算法及其代码实现

一、K近邻算法简介

    1.K近邻算法

    当输入一个测试数据,我们在训练数据集当中找到K个与输入数据最相近的,通常这个可以用欧几里得距离来衡量(当然其他距离也可以)。然后观察这K个邻居中他们的标签(类别),最多的是哪一类,最后把输入的测试数据的标签设定为投票数最多的类别即完成目标。

    通常K近邻算法是用来完成分类任务的,所以它可以被视为分类算法。但是实际上该算法思想也可以用来完成回归任务,比如把输入数据的y值设定为K个邻居的y值的平均数,即可完成回归任务。事实上,sklearn中除了有KNeighborsClassifier,也有KNeighborsRegressor,用来完成回归任务。

    2.优点:

    精度高,因为是经过了所有训练数据的投票。

    对异常值不敏感,因为个别异常值在投票中占少数。

    不用对模型进行训练,直接计算即可。

    无数据输入假定。

    3.缺点

    计算复杂度高,空间复杂度高(当数据量上万时,速度会很慢)

二、代码实现

import scipy.io as scio
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import numpy as np

def load_data():
    print("[INFO]: loading MNIST (full) dataset...")
    dataset = scio.loadmat(
        r"~\mnist-original.mat"   #换成你的数据所在路径,数据可以搜索名字,下载
    )
    data = dataset['data'].astype("float") /255.0
    return train_test_split(data.T,dataset['label'].T)

def classify(x, dataset, labels, k):
    # np.tile 让x在第一个维度上重复dataset.shape[0]次,在第二个维度上重复一次,
    # 最后形状跟dataset一样
    diff_matrix=np.tile(x, (dataset.shape[0],1)) - dataset
    square_diff_matrix = diff_matrix ** 2
    distances = np.sqrt(square_diff_matrix.sum(axis=1))
    sorted_idx = distances.argsort()
    class_count = {}
    for i in range(k):
        vote_label = labels[sorted_idx[i]][0]
        class_count[vote_label] = class_count.get(vote_label, 0) + 1
    sorted_class_count = sorted(class_count.items(), key=lambda x: x[1], reverse=True)
    return sorted_class_count[0][0]

def fit(testX,dataset,labels,k):
    result = []
    for each in testX:
        result.append(classify(each,dataset,labels,k))
    return result

(trainX, testX, trainY, testY) = load_data()
predictions = fit(testX[0:50], trainX[0:1000], trainY[0:1000], 10)
print(classification_report(testY[0:50], predictions))

三、调用sklearn中的KNeighborsClassifier

    事实上,sklearn中已经有该算法的实现,我们需要的时候可以直接调用,而不需要自己编写。

from sklearn.neighbors import KNeighborsClassifier
#这里的load_data函数与上面的一致
(trainX, testX, trainY, testY) = load_data()
model = KNeighborsClassifier(n_neighbors=10, n_jobs=-1)
model.fit(trainX[0:1000], trainY[0:1000])
print(classification_report(testY[0:50], model.predict(testX[0:50])))
原创文章 26 获赞 33 访问量 1899

猜你喜欢

转载自blog.csdn.net/qq_40765537/article/details/105851566