机器学习成长之路——kNN算法(k-近邻算法)1

本章节主要介绍k近邻算法(k-nearst neighbors,简称为kNN算法)的使用及使用场景,以及相关的使用示例。把kNN算法放在第一个讲解算法示例,是因为KNN算法使用的数学知识很少,只有简单的欧式距离公式就可以进行相关算法编写。

一、什么是kNN算法

kNN算法是采用不同特征值之间的距离进行分类,正所谓“物以类聚,人以群分”其实表达的也是这个意思。k近邻算法中的k表示意思是在样本集中与目标变量最接近的k个元素,其中k的值一般为奇数;然后在k个元素中选择类型最多的一种元素为目标变量的分类类型。

举个简单例子:

我们使用matplotlib画二位扩散图,因此需要引入matplotlib包

二、kNN算法实例讲解 

用户需求:使用kNN算法实现一个按照不同工作年限及用户综合评价进行等级划分

 

import matplotlib
import matplotlib.pyplot as plt
from numpy import *
import numpy as np
# 按照个人能力进行等级分类
'''
样本特征:
    工作年限为X轴坐标:位浮点数
    用户评价为Y坐标:最高为100分
目标向量:初级、中级、高级
'''
# 定义一个矩阵,用于存储相关数据坐标,存储每一个样本特征
row_data_x = array([[1,10],
                   [2,25],
                   [7,90],
                   [6,85],
                   [1,10.5],
                   [2.5,20],
                   [8,85],
                   [3,50],
                   [4,55],
                   [3.5,45],
                   [4.5, 40],
                   [2,30]])
#记录每一个样本的类别
row_data_y = ['初级','初级','高级','高级','初级','初级','高级','中级','中级','中级','中级','初级']

#生成向量值
#记录训练级的样本x
x_train = np.array(row_data_x)
#记录训练级的分类y
y_train = np.array(row_data_y)
"""
下面代码解析一下:
y_train=='初级':读取在y_train列表中'初级'的所有index数
x_train[y_train=='初级',0]:x_train[index,0]读取第index元素的第一列元素值
x_train[y_train=='初级',1]:x_train[index,1]读取第index元素的第二列元素值
plt.scatter(X,Y,color='g'):X坐标,Y坐标,颜色
"""
plt.scatter(x_train[y_train=='初级',0],x_train[y_train=='初级',1],color='g')
plt.scatter(x_train[y_train=='中级',0],x_train[y_train=='中级',1],color='r')
plt.scatter(x_train[y_train=='高级',0],x_train[y_train=='高级',1],color='b')

plt.show()

运行结果:

结果验证:如果有一个同事工作6年,用户评价为80分。则用户应该定义为那种类别呢?

我们把数据绘画到图上,使用黄色标记,代码如下:

# 如果有一个同事工作6年,用户评价为80分。则用户应该定义为那种类别呢
plt.scatter(6,80,color='y')

使用kNN算法进行判断[6,80]这个数据到底属于哪一个分类?

from numpy import *
import operator
#调用k近邻算法
def kNN(inX, dataSet, labels, k):
    """
    近邻算法调用,并求出相应的结果值
    :param inX: 输入向量,测试样本数据变量
    :param dataSet: 训练样本集数据
    :param labels:  标签向量,其中的元素数通常与训练样本集中的矩阵的行数相同,标签向量与训练样本要一一对应
    :param k: 选择最近邻居数目,数值不能大于标签向量的元素数
    :return: 返回标签向量中的一个值
    """
    dataSetSize = dataSet.shape[0]
    # 新数据与样本数据每一行的值相减  [[x-x1,y-y1],[x-x2,y-y2],[x-x3,y-y3],.....]
    diffMat = tile(inX, (dataSetSize,1)) - dataSet
    # 数组每一项进行平方[[(x-x1)^2,(y-y1)^2],........]
    sqDiffMat = diffMat**2
    # 数组每个特证求和[[(x-xi)^2+(y-yi)^2],......]
    sqDistances = sqDiffMat.sum(axis=1)
    # 数组每个值 开根号   ,,欧式距离公式 完成。。。。
    distances = sqDistances**0.5
    # argsort函数返回的是数组值从小到大的索引值
    sortedDistIndicies = distances.argsort()
    # 以下是选取 距离最小的前k个值的索引,从k个中选取分类最多的一个作为新数据的分类
    classCount={}
    # 统计前k个点所属的类别
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    """
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
    如果报:AttributeError: 'dict' object has no attribute 'iteritems'异常原因:
    Python3.5中:iteritems变为items,需要把语句改成:
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    """
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]# 返回前k个点中频率最高的类别

resultStr = kNN([6,80],row_data_x,row_data_y,3)
print(resultStr)

执行结果:

三、错误率

错误率是为了验证算法是否符合我们预期的要求,本篇到此结束,下一篇再讲剩余的部分。 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值