【李航-统计机器学习】【原理与代码】【第三章】K近邻法 python C++

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/github_36923418/article/details/89024508

一、原理

     什么是K近邻?就是KNN,当N=1的时候就是最近邻了。

     k近邻算法简单、直观:给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例多数属于某个类,就把该输入实例分为这个类。

                        

     上面这个公式,就是找出投票最多的那一类!!!

                                               

二、几大要点

1、k近邻法没有显式的学习过程。

2、个基本要素:

距离度量:

                 

                

k值的选择:

      选择较小的k值,就相当于用较小的邻域中的训练实例进行预测,“学习”的近似误差(approximation error)会减小,只有与输入实例较近的(相似的)训练实例才会对预测结果起作用。但缺点是“学习”的估计误差(estimation error)会增大,预测结果会对近邻的实例点非常敏感[2]。如果邻近的实例点恰巧是噪声,预测就会出错。换句话说,k值的减小就意味着整体模型变得复杂,容易发生过拟合。
      如果选择较大的k值,就相当于用较大邻域中的训练实例进行预测。其优点是可以减少学习的估计误差。但缺点是学习的近似误差会增大。这时与输入实例较远的(不相似的)训练实例也会对预测起作用,使预测发生错误。k值的增大就意味着整体的型变得简单。
      如果k=N,那么无论输入实例是什么,都将简单地预测它属于在训练实例中最多的类。这时,模型过于简单,完全忽略训练实例中的大量有用信息,是不可取的。在应用中,k值一般取一个比较小的数值。通常采用交叉验证法来选取最优的k值

分类决策规则:

       绕来绕去,没看明白~~~~

三、代码

import numpy as np
import pandas as pd
import math
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from collections import Counter
#对距离度量进行定义
#定义距离度量
def distance_(x1,x2,p=2):
    x1=np.array(x1)
    x2=np.array(x2)
    assert x1.shape==x2.shape   
    sum_=0
    for i in range(x1.shape[0]):
        sum_+=math.pow((x1[0]-x2[0]),p)
    return math.pow(sum_,1./p)
#制作训练数据
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']
df
#     花萼长度      花萼宽度    花瓣长度    花瓣宽度   类别   
#数据进行可视化
plt.scatter(df[:50]['sepal length'], df[:50]['sepal width'], c='r',label='0')
plt.scatter(df[50:100]['sepal length'], df[50:100]['sepal width'],c='y' ,label='1')
#plt.scatter(df[100:150]['sepal length'], df[100:150]['sepal width'],c='g' ,label='2')
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()
#取数据,并且分成训练和测试集合
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,num_k,p,X_train,Y_train):
        self.p=p
        self.k=num_k
        self.X_train=X_train
        self.Y_train=Y_train
    def get_preds(self,input_data):
        dist_=np.zeros((self.X_train.shape[0],2))
        for i in range(self.X_train.shape[0]):
            dist_[i]=distance_(input_data,self.X_train[i],p=2),self.Y_train[i]
            #print(dist_[i])
        #dist_=dist_[np.lexsort(dist_[:,::-1].T)]
        dist_ = dist_[dist_[:,0].argsort()]
        res=dist_[:self.k,:]
        #print(res)
        sortbin=res[:,1].astype(np.int32)
        #print(np.argmax(np.bincount(sortbin)))
        return np.argmax(np.bincount(sortbin))
            
#运行模型并eval
model=KNN(num_k=10,p=2,X_train=X_train,Y_train=y_train)
count=0
for i in range(X_test.shape[0]):
    pred=model.get_preds(X_test[i])
    if pred == y_test[i] :
        count+=1
print("acc:",float(float(count)/y_test.shape[0]))

猜你喜欢

转载自blog.csdn.net/github_36923418/article/details/89024508