(李航统计方法学习)KNN的Python实现

K-NN(k-nearest neighbor)是一种基本分类与回归的方法,没有训练过程。
分类;
模型:利用训练数据集对特征向量空间进行划分
策略:惰性学习,应该是没有优化策略的
算法:略
k近邻的三个基本要素:k的选择,距离度量,分类决策规则(多数表决规则等价于经验风险最小)


优点:
简单好用,容易理解,精度高,理论成熟,既可以用来做分类也可以用来做回归;
可用于数值型数据和离散型数据;
训练时间复杂度为O(n);无数据输入假定;
对异常值不敏感。
缺点:
数据量大,特征维度大的计算复杂度会很高(kd树存储结构),计算复杂性高;空间复杂性高;
样本不平衡问题(即有些类别的样本数量很多,而其它样本的数量很少);
一般数值很大的时候不用这个,计算量太大。但是单个样本又不能太少,否则容易发生误分。
最大的缺点是无法给出数据的内在含义。

##K-NN实现
##使用欧氏距离,多数投票决策机制
from sklearn.datasets import load_iris
import random
import heapq
iris = load_iris()
import numpy as np
def Preprocessing():
    testset=[]
    test_labels=[]
    trainset=[]
    train_labels=[]
    datas=iris.data[:,0:3]
    label=iris.target
    test_list=np.sort([random.randint(0,149) for _ in range(10)])
    for i in range(150):
        if i in test_list:
            testset.append(datas[i])
            test_labels.append(label[i])
        else:
            trainset.append(datas[i])
            train_labels.append(label[i])

    testset=np.mat(testset)
    test_labels=np.mat(test_labels).transpose()
    trainset = np.mat(trainset)
    train_labels = np.mat(train_labels).transpose()
    return testset, test_labels, trainset, train_labels
# def train(X_train,Y_train,k):
#
#
#
# # def distance(x1,x2):
# #     m,n=np.shape(x1)
# #     result=0
# #     for i in range(n):
# #         result+=(x1[i]-x2[i])**2
# #     return  result**0.5

def Predict(testset,trainset,train_labels,n):
    predict=[]
    k=n
    for test_vec in testset:
        dist_list=[]
        knn_list=[]

        for i in range(len(train_labels)):
            label=train_labels[i]
            train_vec=trainset[i]
            print(train_vec-test_vec)
            dist=np.linalg.norm(train_vec-test_vec)
            dist_list.append((dist,label))
        knn_list=heapq.nsmallest(k,dist_list,key=lambda  x:x[0])
        class_total=3
        class_count=[0 for i in range(class_total)]
        for dist,label in knn_list:
            label=label.tolist()
            class_count[label[0][0]]+=1

        mmax=max(class_count)

        for i in range(class_total):
            if mmax==class_count[i]:
                predict.append(i)
                break
    return predict


def main():
    k=10
    testset,test_labels,trainset,train_labels=Preprocessing()
    predict=Predict(testset,trainset,train_labels,k)
    test_labels=test_labels.tolist()

    error_count=0
    for i in range(10):
        print("testset:", test_labels[i][0], "predict:", predict[i])
        if test_labels[i][0] != predict[i]:
            error_count += 1
    print("error_count:", error_count)

if __name__ == '__main__':
    main()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值