Advertisement

读书笔记-统计学习方法(李航)第三章

阅读量:

第三章 K 近邻算法

  • 3.1 k近邻算法

  • 3.2 k近邻模型

    • 距离度量
    • k值的选择
    • 决策规则
      • 实践:
  • 手动实现

  • sklearn 实现

3.1 k近邻算法

k近邻是一种基本的分类 和 回归 方法

k近邻法的三个基本要素为:
1:k值的选择
2:距离度量
1:分类决策规则

3.2 k近邻模型

距离度量

在这里插入图片描述

k值的选择

1:k值太小:

模型过于复杂(只考虑最近的一个点),过拟合

2:当k参数取值过大时,模型结构过于简单(例如当K的取值等于样本总数N时),导致模型无法有效学习到数据特征。

决策规则

对测试点最近的K个点的类别投票,用多数类别预测 测试点的类别。


实践:

复制代码
    """
    2.给定一个二维空间的数据集T={正实例:(5,4),(9,6),(4,7);负实例:(2,3), (8,1),(7,2)},试基于欧氏距离,找到数据点S(5,3)的最近邻(k=1),并对S点进行分类预测。
    
    (1)用“线性扫描”算法自编程实现。
    
    (2)试调用sklearn.neighbors的KNeighborsClassifier模块,对S点进行分类预测,并对比近邻数k取值不同,对分类预测结果的影响。
    
    (3)思考题:思考“线性扫描”算法和“kd树”算法的时间复杂度。
    """
复制代码
    '\n2.给定一个二维空间的数据集T={正实例:(5,4),(9,6),(4,7);负实例:(2,3), (8,1),(7,2)},试基于欧氏距离,找到数据点S(5,3)的最近邻(k=1),并对S点进行分类预测。\n\n(1)用“线性扫描”算法自编程实现。\n\n(2)试调用sklearn.neighbors的KNeighborsClassifier模块,对S点进行分类预测,并对比近邻数k取值不同,对分类预测结果的影响。\n\n(3)思考题:思考“线性扫描”算法和“kd树”算法的时间复杂度。\n'

手动实现

复制代码
    import numpy as np
    x_train = np.array([[5,4],[9,6],[4,7],[2,3],[8,1],[7,2]])
    y_train = np.array([1,1,1,0,0,0])
    x_test = np.array([[5,3]])
复制代码
    def model(k,x_train,y_train,x_test):
    dis2class = dict()
    for i in range(y_train.shape[0]):
        point = x_train[i]
        dis = 0
        for j in range(2):
            dis += (point[j]-x_test[0][j])**2
        dis = dis ** 0.5
        dis2class[dis] = y_train[i]
    print(dis2class)
    dis_list = list(dis2class.keys())
    dis_list.sort()
    dis_list = dis_list[:k]
    print(dis_list)
    class_list = [dis2class[diss] for diss in dis_list]
    print(class_list)
    class_count = dict()
    for c in set(class_list):
        class_count[class_list.count(c)] = c
    print(class_count)
    print(max(class_count))
    return class_count[max(class_count)]    
    
    
    result = model(1,x_train,y_train,x_test)
    print("result = ",result)
复制代码
    {1.0: 1, 5.0: 1, 4.123105625617661: 1, 3.0: 0, 3.605551275463989: 0, 2.23606797749979: 0}
    [1.0]
    [1]
    {1: 1}
    1
    result =  1

k值过小会造成过拟合,过大则会欠拟合

sklearn 实现

复制代码
    from sklearn.neighbors import KNeighborsClassifier
    """
    n_neighbors : 默认值:5
    weights : 默认:uniform(权重一样) ; distancs(距离越近权重越大)
    algorithm: 默认:auto ; brute(暴力求解即线性扫描) ; kd_tree ; ball_tree  (当数据量较小时会自动变成暴力求解)
    leaf_size : 默认:30 (叶子节点数量的阈值)
    p : 默认是2(即欧氏距离)
    metric:默认 mincowski
    n_jobs:并行搜索 ,1表示一个进程,-1表示所%alias进程
    """
    for k in range(1,6,2):
    #构建实例
    clf = KNeighborsClassifier(n_neighbors=k,n_jobs=1,)
    #训练
    clf.fit(x_train,y_train)
    #预处
    res = clf.predict(x_test)
    print("当k值为{}时,测试点的分类结果为:".format(k) ,res)
复制代码
    当k值为1时,测试点的分类结果为: [1]
    当k值为3时,测试点的分类结果为: [1]
    当k值为5时,测试点的分类结果为: [1]

全部评论 (0)

还没有任何评论哟~