机器学习实战ByMatlab(一)KNN算法

KNN 算法其实简单的说就是“物以类聚”,也就是将新的没有被分类的点分类为周围的点中大多数属于的类。它采用测量不同特征值之间的距离方法进行分类,思想很简单:如果一个样本的特征空间中最为临近(欧式距离进行判断)的K个点大都属于某一个类,那么该样本就属于这个类。这就是物以类聚的思想。

当然,实际中,不同的K取值会影响到分类效果,并且在K个临近点的选择中,都不加意外的认为这K个点都是已经分类好的了,否则该算法也就失去了物以类聚的意义了。

KNN算法的不足点:

1、当样本不平衡时,比如一个类的样本容量很大,其他类的样本容量很小,输入一个样本的时候,K个临近值中大多数都是大样本容量的那个类,这时可能就会导致分类错误。改进方法是对K临近点进行加权,也就是距离近的点的权值大,距离远的点权值小。

2、计算量较大,每个待分类的样本都要计算它到全部点的距离,根据距离排序才能求得K个临近点,改进方法是:先对已知样本点进行剪辑,事先去除对分类作用不大的样本。

适用性:

适用于样本容量比较大的类域的自动分类,而样本容量较小的类域则容易误分

算法描述:

    1、计算已知类别数据集合汇总的点与当前点的距离
    2、按照距离递增次序排序
    3、选取与当前点距离最近的K个点
    4、确定距离最近的前K个点所在类别的出现频率
    5、返回距离最近的前K个点中频率最高的类别作为当前点的预测分类

Python 实现

from numpy import *
import operator

def createDataSet():
    group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    lables = [‘A‘,‘A‘,‘B‘,‘B‘]
    return group,lables

# KNN 分类算法
def classify0(inx,dataSet,labels,k):
    dataSetSize = dataSet.shape[0] # shape[0]获取行 shape[1] 获取列
    # 第一步,计算欧式距离
    diffMat = tile(inx,(dataSetSize,1)) - dataSet  #tile类似于matlab中的repmat,复制矩阵
    sqDiffMat = diffMat ** 2
    sqDistances = sqDiffMat.sum(axis=1)
    distance = sqDistances ** 0.5
    sortedDistIndecies = distance.argsort()  # 增序排序
    classCount = {}
    for i in range(k):
    # 获取类别
        voteIlabel = labels[sortedDistIndecies[i]]
        #字典的get方法,查找classCount中是否包含voteIlabel,是则返回该值,不是则返回defValue,这里是0
        # 其实这也就是计算K临近点中出现的类别的频率,以次数体现
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
        #  对字典中的类别出现次数进行排序,classCount中存储的事 key-value,其中key就是label,value就是出现的次数
        #  所以key=operator.itemgetter(1)选中的事value,也就是对次数进行排序
    sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
        #sortedClassCount[0][0]也就是排序后的次数最大的那个label
    return sortedClassCount[0][0]

调用方式:

import sys;
sys.path.append("/home/llp/code/funcdef")
import KNN 

group,labels = KNN.createDataSet();
relust = KNN.classify0([0,0],group,labels,3)
print ‘the classify relust is :‘ , relust

Matlab 实现

这里以一个完整实例呈现,代码如下:

function relustLabel = KNN(inx,data,labels,k)
%%
%   inx 为 输入测试数据,data为样本数据,labels为样本标签
%%

[datarow , datacol] = size(data);
diffMat = repmat(inx,[datarow,1]) - data ;
distanceMat = sqrt(sum(diffMat.^2,2));
[B , IX] = sort(distanceMat,‘ascend‘);
len = min(k,length(B));
relustLabel = mode(labels(IX(1:len)));

end

可以看到,整个KNN算法的Matlab代码也就只有6行,比Python少很多,这其中要得益于Matlab成熟的矩阵计算和很多成熟的函数。

实际调用中,我们利用一个数据集进行测试,该数据集是由1000个样本的3维坐标组成,共分为3个类

首先可视化我们的数据集,看看它的分布:

第一维和第二维:可以清晰地看到数据大致上分为 3 类

第1维和第3维:从这个角度看,3类的分布就有点重叠了,这是因为我们的视角原因

画出3维,看看它的庐山真面目:

由于我们已经编写了KNN代码,接下来我们只需调用就行。了解过机器学习的人都应该知道,很多样本数据在代入算法之前都应该进行归一化,这里我们将数据归一化在[0,1]的区间内,归一化方式如下:

其中,max为oldData的最大值,min为 oldData 的最小值。

同时,我们对于1000个数据集,采取10%的数据进行测试,90%的数据进行训练的方式,由于本测试数据之间完全独立,可以随机抽取10%的数据作为测试数据,代码如下:

function KNNdatgingTest
%%
clc
clear
close all
%%
data = load(‘datingTestSet2.txt‘);
dataMat = data(:,1:3);
labels = data(:,4);
len = size(dataMat,1);
k = 4;
error = 0;
% 测试数据比例
Ratio = 0.1;
numTest = Ratio * len;
% 归一化处理
maxV = max(dataMat);
minV = min(dataMat);
range = maxV-minV;
newdataMat = (dataMat-repmat(minV,[len,1]))./(repmat(range,[len,1]));

% 测试
for i = 1:numTest
    classifyresult = KNN(newdataMat(i,:),newdataMat(numTest:len,:),labels(numTest:len,:),k);
    fprintf(‘测试结果为:%d  真实结果为:%d\n‘,[classifyresult labels(i)])
    if(classifyresult~=labels(i))
        error = error+1;
    end
end
  fprintf(‘准确率为:%f\n‘,1-error/(numTest))
end

当我们选择K为4的时候,准确率为:0.970000

时间: 2024-10-16 08:21:27

机器学习实战ByMatlab(一)KNN算法的相关文章

机器学习实战笔记——基于KNN算法的手写识别系统

本文主要利用k-近邻分类器实现手写识别系统,训练数据集大约2000个样本,每个数字大约有200个样本,每个样本保存在一个txt文件中,手写体图像本身是32X32的二值图像,如下图所示: 首先,我们需要将图像格式化处理为一个向量,把一个32X32的二进制图像矩阵通过img2vector()函数转换为1X1024的向量: def img2vector(filename): returnVect = zeros((1,1024)) fr = open(filename) for i in range(

机器学习实战笔记——利用KNN算法改进约会网站的配对效果

一.案例背景 我的朋友海伦一直使用在线约会网站寻找合适自己的约会对象.尽管约会网站会推荐不同的人选,但她并不是喜欢每一个人.经过一番总结,她发现曾交往过三种类型的人: (1)不喜欢的人: (2)魅力一般的人: (3)极具魅力的人: 尽管发现了上述规律,但海伦依然无法将约会网站推荐的匹配对象归入恰当的分类,她觉得可以在周一到周五约会那些魅力一般的人,而周末则更喜欢与那些极具魅力的人为伴.海伦希望我们的分类软件可以更好地帮助她将匹配对象划分到确切的分类中.此外,海伦还收集了一些约会网站未曾记录的数据

机器学习实战(一)k-近邻算法

转载请注明源出处:http://www.cnblogs.com/lighten/p/7593656.html 1.原理 本章介绍机器学习实战的第一个算法--k近邻算法(k Nearest Neighbor),也称为kNN.说到机器学习,一般都认为是很复杂,很高深的内容,但实际上其学习门栏并不算高,具备基本的高等数学知识(包括线性代数,概率论)就可以了,甚至一些算法高中生就能够理解了.kNN算法就是一个原理很好理解的算法,不需要多好的数学功底,这是一个分类算法(另一个大类是回归),属于监督学习的范

《机器学习实战》Logistic回归算法(1)

===================================================================== <机器学习实战>系列博客是博主阅读<机器学习实战>这本书的笔记也包含一些其他python实现的机器学习算法 算法实现均采用python github 源码同步:https://github.com/Thinkgamer/Machine-Learning-With-Python ==================================

机器学习实战精读--------K-近邻算法

对机器学习实战的课本和代码进行精读,帮助自己进步. #coding:utf-8 from numpy import * import operator #运算符模块 from os import listdir  #os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表.这个列表以字母顺序. 它不包括 '.' 和'..' 即使它在文件夹中. #创建数据集和标签 def createDataSet():     group = array([[1.0,1.1],[1.0,

机器学习实战笔记-K近邻算法1(分类动作片与爱情片)

K近邻算法采用测量不同特征值之间的距离方法进行分类 K近邻算法特点: 优点:精度高.对异常值不敏感.无数据输入假定. 缺点:计算复杂度高.空间复杂度高. 适用数据范围:数值型和标称型. K近邻算法原理: 存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系.输人没有标签的新数据后,将新数据的每个特征与样本集中数据对应的 特征进行比较,然后算法提取样本集中特征最相似数据(最近 邻)的分类标签.一般来说,我们只选择样本数据集中前k个最

机器学习实战ByMatlab(二)PCA算法

PCA 算法也叫主成分分析(principal components analysis),主要是用于数据降维的. 为什么要进行数据降维?因为实际情况中我们的训练数据会存在特征过多或者是特征累赘的问题,比如: 一个关于汽车的样本数据,一个特征是"km/h的最大速度特征",另一个是"英里每小时"的最大速度特征,很显然这两个特征具有很强的相关性 拿到一个样本,特征非常多,样本缺很少,这样的数据用回归去你和将非常困难,很容易导致过度拟合 PCA算法就是用来解决这种问题的,其

机器学习实战ByMatlab(三)K-means算法

K-means算法属于无监督学习聚类算法,其计算步骤还是挺简单的,思想也挺容易理解,而且还可以在思想中体会到EM算法的思想. K-means 算法的优缺点: 1.优点:容易实现 2.缺点:可能收敛到局部最小值,在大规模数据集上收敛较慢 使用数据类型:数值型数据 以往的回归算法.朴素贝叶斯.SVM等都是有类别标签y的,因此属于有监督学习,而K-means聚类算法只有x,没有y 在聚类问题中,我们的训练样本是 其中每个Xi都是n维实数. 样本数据中没有了y,K-means算法是将样本聚类成k个簇,具

机器学习实战ByMatlab(四)二分K-means算法

前面我们在是实现K-means算法的时候,提到了它本身存在的缺陷: 1.可能收敛到局部最小值 2.在大规模数据集上收敛较慢 对于上一篇博文最后说的,当陷入局部最小值的时候,处理方法就是多运行几次K-means算法,然后选择畸变函数J较小的作为最佳聚类结果.这样的说法显然不能让我们接受,我们追求的应该是一次就能给出接近最优的聚类结果. 其实K-means的缺点的根本原因就是:对K个质心的初始选取比较敏感.质心选取得不好很有可能就会陷入局部最小值. 基于以上情况,有人提出了二分K-means算法来解