笔记——KNN算法实现分类和回归

1. KNN分类

class KNN:
    def __init__(self,k):
        """初始化 """
        self.k=k
    def fit(self,X,y):
        """训练方法
        X:类数组类型(二维)  待训练的样本特征(属性)
        y:(一维)  样本的目标值(标签)"""
        self.X=np.asarray(X)#转化为ndarray数组类型
        self.y=np.asarray(y)
        
    def predict(self,X):
        X=np.asarray(X)
        result=[]
        for x in X:
            #对于测试集中的每一个样本,依次与训练集中的所有样本求距离
            dis=np.sqrt(np.sum((x-self.X)**2,axis=1))
            #返回数组排序后的索引,也是每个元素在原数组(排序之前)中的索引
            index=dis.argsort()
            #只取前K个
            index=index[:self.k]
            #返回数组中每个元素出现的次数。元素必须是非负整数。
            count=np.bincount(self.y[index])
            #返回出现次数最多的元素的索引,该索引就是我们判断的类别.加入resul数组
            result.append(count.argmax())
            
        return np.asarray(result)

    def predict2(self,X):#考虑权重,权重为距离的倒数。
        X=np.asarray(X)
        result=[]
        for x in X:
            #对于测试集中的每一个样本,依次与训练集中的所有样本求距离
            dis=np.sqrt(np.sum((x-self.X)**2,axis=1))
            #返回数组排序后的索引,也是每个元素在原数组(排序之前)中的索引
            index=dis.argsort()
            #只取前K个
            index=index[:self.k]
            #返回数组中每个元素出现的次数。元素必须是非负整数。
            count=np.bincount(self.y[index],weights=1/dis[index])
            #返回出现次数最多的元素的索引,该索引就是我们判断的类别.加入resul数组
            result.append(count.argmax())
            
        return np.asarray(result)

2. KNN回归

class KNN:
    """该算法用于回归预测,用数据集的前三个特征属性,寻找最近的K个邻居,
    然后再根据k个邻居的第四个特征属性,去预测当前样本的第四个特征属性"""
    
    def __init__(self,k):
        self.k=k
        
    def fit(self,X,y):
        self.X=np.asarray(X)
        self.y=np.asarray(y)
        
    def predict(self,X):
        X=np.asarray(X)
        result=[]
        for x in X:
            #计算与训练集中每个X的距离
            dis=np.sqrt(np.sum((x-self.X)**2,axis=1))
            #取前k个
            index=dis.argsort()
            index=index[:self.k]
            #计算前k个的值,取均值返回到结果列表中
            result.append(np.mean(self.y[index]))
            
        return np.array(result)
    
    def predict2(self,X):#考虑权重:权重=(1/每个邻居的距离)/所有的距离倒数之和
        X=np.asarray(X)
        result=[]
        for x in X:
            #计算与训练集中每个X的距离
            dis=np.sqrt(np.sum((x-self.X)**2,axis=1))
            #取前k个
            index=dis.argsort()
            index=index[:self.k]
            #计算所有邻居节点的距离倒数之和。注意:加上0.0001是为了防止距离为0使得分母为0
            s=np.sum(1/(dis[index]+0.0001))
            #求权重:每个距离的倒数/倒数之和
            weight=(1/(dis[index]+0.0001))/s
            #使用邻居节点的标签值*权重,然后进行累加求和,得到预测值
            result.append(np.sum(self.y[index]*weight))
            
        return np.array(result)


3. 对比之前写的KNN算法

import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from collections import Counter
from math import sqrt

class KNNClassfier:
    def __init__(self,k):
        """"初始化KNN分类器"""
        assert k>=1,"k must be valid"
        self.k=k
        self._x_train=None
        self._y_train=None
        
    def fit(self,x_train,y_train):
        assert x_train.shape[0]==y_train.shape[0],"the size must equal"
        assert self.k<=x_train.shape[0]
        self._x_train=x_train
        self._y_train=y_train

        return self
    def predict(self,x_predict):
        assert self._x_train is not None and self._y_train is not None,"must fit before predict!"
        assert x_predict.shape[1]==self._x_train.shape[1],"the size must equal"
        y_predict=[self._predict(x) for x in x_predict]
        return np.array(y_predict)
    def _predict(self,x):
        assert x.shape[0]==self._x_train.shape[1],"must equal!"
        distances = [sqrt(np.sum((x_train - x) ** 2)) for x_train in self._x_train]
        nearest = np.argsort(distances)
        topK_y = [self._y_train[i] for i in nearest[:self.k]]
        votes = Counter(topK_y)
        predict_y = votes.most_common(1)[0][0]
        return predict_y

猜你喜欢

转载自blog.csdn.net/chairon/article/details/107696130