【machine learning】KNN算法

适逢学习机器学习基础知识,就将书中内容读读记记,本博文代码参考书本Machine Learning in Action(《机器学习实战》)。

一、概述

kNN算法又称为k近邻分类(k-nearest neighbor classification)算法。

kNN算法则是从训练集中找到和新数据最接近的k条记录,然后根据他们的主要分类来决定新数据的类别。该算法涉及3个主要因素:训练集、距离或相似的衡量、k的大小。

二、算法要点

1、指导思想

kNN算法的指导思想是“近朱者赤,近墨者黑”,由你的邻居来推断出你的类别。

计算步骤如下:

1)算距离:给定测试对象,计算它与训练集中的每个对象的距离

2)找邻居:圈定距离最近的k个训练对象,作为测试对象的近邻

3)做分类:根据这k个近邻归属的主要类别,来对测试对象分类

2、距离或相似度的衡量

什么是合适的距离衡量?距离越近应该意味着这两个点属于一个分类的可能性越大。

距离衡量包括欧式距离、夹角余弦等。

对于文本分类来说,使用余弦(cosine)来计算相似度就比欧式(Euclidean)距离更合适。

3、类别的判定

投票决定:少数服从多数,近邻中哪个类别的点最多就分为该类,属于以频率为标准。

加权投票法:根据距离的远近,对近邻的投票进行加权,距离越近则权重越大(权重为距离平方的倒数),属于以量化为标准。

三、优缺点

1、优点

简单,易于理解,易于实现,无需估计参数,无需训练

适合对稀有事件进行分类(例如当流失率很低时,比如低于0.5%,构造流失预测模型)

特别适合于多分类问题(multi-modal,对象具有多个类别标签),例如根据基因特征来判断其功能分类,kNN比SVM的表现要好

2、缺点

懒惰算法,对测试样本分类时的计算量大,内存开销大,评分慢

可解释性较差,无法给出决策树那样的规则。

四、利用KNN进行手写识别

假如存在训练数据,都是二值得灰度图,来源于手写面板的采集图像数据。如下表示数字‘0’,所在文件夹下包括表示0~9的文件,文件夹命名A_B.txt,A表示真实数字,B表示该数字的第B个样本(一般数据越多有有利于接近预测值)

在另一个文件夹中,也存在同样命名的数据文件,用于检验有监督学习下的准确率,我们称为测试数据。

在代码中,我们需要三个函数

def classify0(inX, dataSet, labels, k)——用于对输入单个样本inX进行分类,dataSet为训练数据,labels为训练数据的类别,K为近邻范围

def img2vector(filename)——将文件filename中的数据规格由32X32转换为1X1024的向量

def handwritingClassTest()——利用测试数据进行测试,得出错误率

我这里只用了0~9分别20个训练数据而已,提高速度。需要源代码可以到机器学习实战的配套代码中取http://vdisk.weibo.com/s/uEZesAafcjQgx?sudaref=www.baidu.com

代码中用到了numpy库,numpy库用在数据量大的计算较高效

numpy用法小抄:

>>> tile([0, 0], (1, 2))

array([[0, 0, 0, 0]])

>>> tile([0, 0], (2, 1))

array([[0, 0],

[0, 0]])

第一个是矩阵A

第二个参数是要 只有一个数字时,表示 对 A中元素重复的次数

两个参数时(x, y) y表示对A中元素重复的次数, x表示 对前面的操作执行x次。

>>> b= np.arange(12).reshape(3,4)

>>> b

array([[ 0, 1, 2, 3],

[ 4, 5, 6, 7],

[ 8, 9, 10, 11]])

>>> b.sum(axis=0) # 计算每一列的和,注意理解轴的含义,参考数组的第一篇文章

array([12, 15, 18, 21])

>>> b.min(axis=1) # 获取每一行的最小值

array([0, 4, 8])

>>> b.cumsum(axis=1) # 计算每一行的累积和

array([[ 0, 1, 3, 6],

[ 4, 9, 15, 22],

[ 8, 17, 27, 38]])

需要用到再另外写博客进行补充。

KNN.py

#! /usr/bin/env python
#coding=utf-8

from numpy import *
import operator
from os import listdir

def classify0(inX, dataSet, labels, k):
    #inX------[x,x,x,x]
    #dataSet------array([[x,x,x,x],[x,x,x,x]])
    #labels------[x,x]
    #k------n
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inX, (dataSetSize,1)) - dataSet
    sqDiffMat = diffMat**2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5
    sortedDistIndicies = distances.argsort()
    classCount={}
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1

    #将字典按value值大小降序排序,结果为二维列表
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

def img2vector(filename):
    returnVect = zeros((1,1024))
    fr = open(filename,'r')
    for i in range(32):
        lineStr = fr.readline()
        for j in range(32):
            returnVect[0,32*i+j] = int(lineStr[j])
    return returnVect

trainFile = 'F:\\python\\pyproject\\ML\\codes\\machinelearninginaction\\Ch02\\training20\\'
testFile = 'F:\\python\\pyproject\\ML\\codes\\machinelearninginaction\\Ch02\\testDigits\\'

def handwritingClassTest():
    hwLabels = []
    trainingFileList = listdir(trainFile)           #load the training set
    m = len(trainingFileList)
    trainingMat = zeros((m,1024))
    for i in range(m):
        fileNameStr = trainingFileList[i]
        fileStr = fileNameStr.split('.')[0]     #take off .txt
        classNumStr = int(fileStr.split('_')[0])
        hwLabels.append(classNumStr)
        path = trainFile + '%s'
        trainingMat[i,:] = img2vector(path % fileNameStr)
    testFileList = listdir(testFile)        #iterate through the test set
    errorCount = 0.0
    mTest = len(testFileList)
    for i in range(mTest):
        fileNameStr = testFileList[i]
        fileStr = fileNameStr.split('.')[0]     #take off .txt
        classNumStr = int(fileStr.split('_')[0])
        path = testFile + '%s'
        vectorUnderTest = img2vector(path % fileNameStr)
        classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
        print "the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr)
        if (classifierResult != classNumStr): errorCount += 1.0
    print "\nthe total number of errors is: %d" % errorCount
    print "\nthe total error rate is: %f" % (errorCount/float(mTest))

再在test.py中调用KNN.handwritingClassTest(),则程序开始运行

test.py

#! /usr/bin/env python
#coding=utf-8

import KNN
KNN.handwritingClassTest()

可看到错误率10.68%,挺高的,增加训练数据量就应该会减小一些。

时间: 2024-08-10 21:19:31

【machine learning】KNN算法的相关文章

[Machine :Learning] kNN近邻算法

from numpy import * import operator def createDataSet() : group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 1.1]]) labels = ['A', 'A', 'B', 'B'] return group, labels ''' tile(array, (intR, intC): 对矩阵进行组合,纵向复制intR次, 横向复制intC次 比如 : tile([1,2,3], (3, 2

Machine Learning:机器学习算法

原文链接:https://riboseyim.github.io/2018/02/10/Machine-Learning-Algorithms/ 摘要 机器学习算法分类:监督学习.半监督学习.无监督学习.强化学习 基本的机器学习算法:线性回归.支持向量机(SVM).最近邻居(KNN).逻辑回归.决策树.k平均.随机森林.朴素贝叶斯.降维.梯度增强 目录 监督学习(Supervised learning) 监督学习 原文地址:https://www.cnblogs.com/Antiver/p/99

[Machine Learning]kNN代码实现(Kd tree)

具体描述见<统计学习方法>第三章. 1 // 2 // main.cpp 3 // kNN 4 // 5 // Created by feng on 15/10/24. 6 // Copyright © 2015年 ttcn. All rights reserved. 7 // 8 9 #include <iostream> 10 #include <vector> 11 #include <algorithm> 12 #include <cmath&

Machine Learning In Action 第二章学习笔记: kNN算法

本文主要记录<Machine Learning In Action>中第二章的内容.书中以两个具体实例来介绍kNN(k nearest neighbors),分别是: 约会对象预测 手写数字识别 通过“约会对象”功能,基本能够了解到kNN算法的工作原理.“手写数字识别”与“约会对象预测”使用完全一样的算法代码,仅仅是数据集有变化. 约会对象预测 1 约会对象预测功能需求 主人公“张三”喜欢结交新朋友.“系统A”上面注册了很多类似于“张三”的用户,大家都想结交心朋友.“张三”最开始通过自己筛选的

【用Python玩Machine Learning】KNN * 序

这段时间工作太忙,很久没学习了.这两天,工作之余,偶尔在家翻翻书,权且当做休息了. 我一直是c/c++的忠实用户,尤其是c的粉丝--概念简洁.运行高效--计算机专业的人,不用c语言,不了解程序底层的运行机制和过程,那和那些外专业的只会调用接口.函数的同学有什么区别呢?不过,最近一年还是慢慢去了解.尝试python了.原因很简单,开发成本太低了.c/c++就像复杂的吸尘器.洗碗机,优点是高效,缺点是笨重,且对不同的场景要不同的适配:python就像是一块脏抹布,哪儿都能用,用完就扔,再用的时候再捡

机器学习算法之旅A Tour of Machine Learning Algorithms

In this post we take a tour of the most popular machine learning algorithms. It is useful to tour the main algorithms in the field to get a feeling of what methods are available. There are so many algorithms available and it can feel overwhelming whe

机器学习---用python实现感知机算法和口袋算法(Machine Learning PLA Pocket Algorithm Application)

之前在<机器学习---感知机(Machine Learning Perceptron)>一文中介绍了感知机算法的理论知识,现在让我们来实践一下. 有两个数据文件:data1和data2,分别用于PLA和Pocket Algorithm.可在以下地址下载: 先回顾一下感知机算法: 1,初始化w 2,找出一个分类错误点 3,修正错误,假设迭代次数为t次(t=1,2,...),那么修正公式为: 4,直至没有分类错误点,返回最终的w 接下来让我们安照算法步骤,一步一步进行. 首先导入需要用到的库,其中

【用Python玩Machine Learning】KNN * 测试

样本我就用的<machine learning in action>中提供的数据样例,据说是婚恋网站上各个候选人的特征,以及当前人对这些人的喜欢程度.一共1k条数据,前900条作为训练样本,后100条作为测试样本. 数据格式如下: 46893 3.562976 0.445386 didntLike 8178 3.230482 1.331698 smallDoses 55783 3.612548 1.551911 didntLike 1148 0.000000 0.332365 smallDos

[Machine Learning] 国外程序员整理的机器学习资源大全

本文汇编了一些机器学习领域的框架.库以及软件(按编程语言排序). 1. C++ 1.1 计算机视觉 CCV —基于C语言/提供缓存/核心的机器视觉库,新颖的机器视觉库 OpenCV—它提供C++, C, Python, Java 以及 MATLAB接口,并支持Windows, Linux, Android and Mac OS操作系统. 1.2 机器学习 MLPack DLib ecogg shark 2. Closure Closure Toolbox—Clojure语言库与工具的分类目录 3