机器学习实战<学习笔记>--KNN

简单的KNN算法

#添加编码方式
# -*- coding: utf-8 -*-
from numpy import *
import operator

# 准备数据
def createDataSet():
    group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
    labels = ['A', 'A', 'B', 'B']
    return group, labels

# 使用KNN找出距离最近的类别标签
# inX:待预测的样本向量
# dataSet:训练样本集
# labels:训练样本集对应的类别标签,长度与dataSet的长度一致
# k:从dataSet中找出离inX距离最近的k个样本
def classifyKNN(inX, dataSet, labels, k):
    dataSetNum = dataSet.shape[0]  # 样本数,dataSet是个矩阵/二维数组,shape属性返回矩阵的形状,即行数列数信息,行数即为样本个数
    diffMat = tile(inX, (dataSetNum, 1)) - dataSet  # tile是numpy库中的拼接函数,(dataSetNum,1)表示副本的行列数,这样做是为了让inX与dataSet的每一行做运算
    sqDiffMat = diffMat ** 2  #inX与每个训练样本对应特征差值的平方
    sqDistances = sqDiffMat.sum(axis=1)  
    distances = sqDistances ** 0.5  #按列对平方差值矩阵求和,之后再开方,即为inX与每个训练样本的欧式距离
    sortedDistanceIdx = distances.argsort()  # 距离从小到大的索引值,sortedDistanceIdx中存放的是值从小到大的distances的索引值
    classCount = {}  #统计类别数
    for i in range(k):  #0~k-1
        voteLabel = labels[sortedDistanceIdx[i]] #sortedDistanceIdx中存放的是distances的索引值,其与训练集的labels是相对应的,只不过sortedDistanceIdx存储的是距离从小到大的索引,若此时i=0,则sortedDistanceIdx[i]值为离inX最近的训练样本的索引值,labels[sortedDistanceIdx[i]]值为这个离的最近的训练样本的类别
        classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 #类别字典对应key的value增1
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)  #sorted是python内置的排序方法,classCount.iteritems()得到字典的key-value对列表,用来迭代,key指使用哪个特征来排序,reverse表示降序or升序
    return sortedClassCount[0][0]  #因为是降序排列,sortedClassCount[0][0]表示出现次数最多的类别,sortedClassCount[0][1]表示最多类别的出现次数


# 执行
g, l = createDataSet()
print classifyKNN((0, 0), g, l, 3)

小测试

a = (4, 1, 3)
b = operator.itemgetter(2, 0)
print b(a)

结果为(3, 4)

students = [('carl', 'c', 66), ('sarah', 'a', 93), ('bill', 'c', 71)]
s = sorted(students, key=lambda student: student[2], reverse=True)      #lambda表达式
t = sorted(students, key=operator.itemgetter(0), reverse=False)     #operator.itemgetter
print s, '\n', t

结果为[('sarah', 'a', 93), ('bill', 'c', 71), ('carl', 'c', 66)]
[('bill', 'c', 71), ('carl', 'c', 66), ('sarah', 'a', 93)]
,其中,students是list,lamdba表达式是用第2个特征来做排序的,operator.itemgetter是用第0个特征来排序,排序结果都是list。

students = {'carl': 66, 'sarah': 93, 'bill': 71}
s = sorted(students.iteritems(), key=lambda student: student[1], reverse=False)
t = sorted(students.iteritems(), key=operator.itemgetter(1), reverse=False)
print s, '\n', t

结果为[('carl', 66), ('bill', 71), ('sarah', 93)]
[('carl', 66), ('bill', 71), ('sarah', 93)]
,其中,students是字典dict,要先使用iteritems方法获取key-value的迭代对象,这里的key都是用第1个特征排序,lambda表达式和operator.itemgetter的效果一样,排序结果都是list。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值