机器学习 02 K近邻模型

机器学习02 K近邻模型
K近邻的主要思想就是首先将数据分为训练数据集和测试数据集。然后用训练数据集来建立模型。通过判断测试数据到其他训练数据集中的欧式距离然后排序,选取离测试数据点最近的K个数据,然后根据这K个数据的类别及多数表决原则,来决定此测试点的数据类别。
接下来是具体实例:
这里仅用一个测试点来说明问题。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import matplotlib as mpl
from collections import Counter
#data加载数据
iris=load_iris()
df=pd.DataFrame(iris.data,columns=iris.feature_names)
df['label']=iris.target
df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
plt.scatter(df[:50]['sepal length'],df[:50]['sepal width'],label='0')
plt.scatter(df[50:100]['sepal length'],df[50:100]['sepal width'],label='1')
plt.xlabel=('sepal length')
plt.ylabel=('sepal width')
plt.legend()
plt.show()
data=np.array(df.iloc[:100,[0,1,-1]])
X,y=data[:,:-1],data[:,-1]
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2)

class KNN:
    def __init__(self, X_train, y_train, n_neighbors=3, p=2):
        """
        parameter: n_neighbors 临近点个数
        parameter: p 距离度量
        """
        self.n = n_neighbors
        self.p = p
        self.X_train = X_train
        self.y_train = y_train

    def predict(self, X):
        # 取出n个点
        knn_list = []
        for i in range(self.n):
            #np.linalg.norm用来进行范数运算,ord=2表示二范数
            dist = np.linalg.norm(X - self.X_train[i], ord=self.p)
            #将测试点与取出的n个数之间的距离,以及这n个数的类别存储在knn_list中
            knn_list.append((dist, self.y_train[i]))

#再从剩下的X_train-n个数据中进行依次距离计算,
#将这些数据中与测试点距离小于刚刚取出来的k个数据中的距离时,进行替换。
#达到取出来的k个数据到测试点的距离为最短距离的目的。

        for i in range(self.n, len(self.X_train)):
        #max(knn_list,key=lambda x:x[0])是把knn_list中的数据按照x[0]第一位素(距离)进行比较取最大值,再取其索引赋值给max_index。
            max_index = knn_list.index(max(knn_list, key=lambda x: x[0]))
            #计算测试点到剩余数据的距离
            dist = np.linalg.norm(X - self.X_train[i], ord=self.p)
            #如果knn_list中的最大距离的点的距离大于其余点计算的距离,
            if knn_list[max_index][0] > dist:
                knn_list[max_index] = (dist, self.y_train[i])

        # 统计
        #将knn_list中的k[-1](即,点的类别)进行统计。
        knn = [k[-1] for k in knn_list]
        #Counter()可以用于计数,会返回一个key为列表的值,value为该值出现个数,的对
        count_pairs = Counter(knn)
#         max_count = sorted(count_pairs, key=lambda x: x)[-1]
        #将count_pairs中的数据排序,最终将[-1][0]即出现次数最多的类别给max_count
        max_count = sorted(count_pairs.items(), key=lambda x: x[1])[-1][0]
        return max_count

    def score(self, X_test, y_test):
        right_count = 0
        n = 10
        #zip即打包为元组
        for X, y in zip(X_test, y_test):
            label = self.predict(X)
            if label == y:
                right_count += 1
        return right_count / len(X_test)
#clf即classifier的缩写
clf = KNN(X_train, y_train)
clf.score(X_test, y_test)
test_point = [5.0,3.5]
#输出测试点的分类
print('Test Point: {}'.format(clf.predict(test_point)))
plt.scatter(df[:50]['sepal length'], df[:50]['sepal width'], label='0')
plt.scatter(df[50:100]['sepal length'], df[50:100]['sepal width'], label='1')
plt.plot(test_point[0], test_point[1], 'bo', label='test_point')
plt.legend()
plt.show()


至此我们可以简单了解了KNN模型的原理。但是为了提高K近邻搜索的效率,可以考虑用特殊的结构来存储训练数据。即KD树。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值