KNN 最邻近算法 机器学习实战

'''
python--version << 3.7
需要文件 可以联系我

k- 临近算法

优点: 精度高,对异常值不敏感,无数据输入假定
缺点: 计算复杂度高,空间复杂度高,适用数据范围:数值型,标称型
原理: 存在一个样本数据集合,并且每个数据都存在一个标签,输入一个没有数据标签的新数据,和样本中的进行比较,
       然后提取一个相近的分类标签, 一般来说选取前K个最相似的数据,通常k是不大于20的整数

一般流程:
	1.收集数据
	2.准备数据: 距离计算所需要的数值,最好是格式化的数据格式
	3.分析数据
	4.训练算法:此步骤不适合用于k临近算法
	5.测试算法:计算错误率
    6.使用算法:首先输入样本数据和结构化的输出结果,然后运行k临近算法判定输入数据分别属哪个分类,最后对计算出的分类执行后续处理

使用k临近算法将每组数据划分到某个类中 伪代码:
	1.计算已知类别数据集中的点与当前点之间的距离
	2.按照距离递增次序排列
	3.选区与当前点距离最小的k个点
	4.确定前k个点所在类别出现的概率
    5.返回前k个点出现频率最高的类别作为当前点的预测分类
'''

from numpy import *
import operator

def createData():
    group = array([[1.0, 1.1],
        [1.0, 1.0],
        [0, 0],
        [0, 0.1]])
    labels = ['A', 'A', 'B', 'B']
    return group, labels

def classify0(inX, dataSet, labels, k):
    #输入向量, 样本训练向量, 标签向量,最邻近项目
    dataSetSize = dataSet.shape[0]#多少个样本
    diffMat = tile(inX, (dataSetSize, 1)) - dataSet #把输入的向量扩展成 dataSetSize * 1 的样子,并且和样本数据做差 x0-x1 y0-y1
    sqDiffMat = diffMat**2 #将差值进行平方 (x0-x1)^2  (y0-y1)^2
    sqDistances = sqDiffMat.sum(axis = 1) #将计算好的平方值进行求和 (x0-x1)^2 + (y0-y1)^2
    distances = sqDistances**0.5 #开方求距离  sqrt((x0-x1)^2 + (y0-y1)^2)
    sortedDistIndicies = distances.argsort() #将距离从小到大进行排序,排序后的值是排序前从小到大值的下标
    classCount = {} #
    for i in range(k): #求前K个临近值
        voteIlabel = labels[sortedDistIndicies[i]] #前K个相近的标签
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 #返回指定标签, 如果没有择是0+1 如果有就+1
    sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse=True )#从大到小排序,根据次数进行排序
    return sortedClassCount[0][0]#返回第一个lable

group , labels = createData()
print("group :", group)
print('labels :', labels)

label = classify0([0,0], group, labels, 3)
print('[0,0], label is :', label)

print('--------------------------------------------------------------------')
'''
    ::示例  ::
    改进约会网站的配对效果
    数据规模:1000行
    数据特征:每年飞行里程数,玩视频游戏消耗时间百分比,每周吃多少公斤的冰淇淋,  最后一列是标签
'''

import matplotlib
import matplotlib.pyplot as plt

def file2matrix(filename):
    #打开文件,解析数据
    fr = open(filename) #打开文件
    array0lines = fr.readlines()# 读取每一行
    number0fLines = len(array0lines) #得到文件的行数
    returnMat = zeros((number0fLines, 3)) #创建返回的numpy矩阵 
    classLabelVector = []
    index = 0
    for line in array0lines:
        line = line.strip()#删除头尾指定字符,默认空格回车
        listFormLine = line.split('\t')# 以制表符(tab)分隔
        returnMat[index, :] = listFormLine[0:3]# 复制 转换成二维数组
        classLabelVector.append(int(listFormLine[-1])) #标签
        index += 1
    return returnMat, classLabelVector
def create_scatter(datingDataMat, datingLabels):
    #显示中文
    plt.rcParams['font.sans-serif'] = ['SimHei']
    fig = plt.figure() #创建一个画板
    ax = fig.add_subplot(211) #将画板分成2x1 将图放在第一个
    ax.scatter(datingDataMat[:, 1], datingDataMat[:, 2], 15.0*array(datingLabels), 15.0*array(datingLabels)) #x轴 ,y轴,并且将每一个类别画上颜色
    plt.xlabel('玩游戏视频消耗时间所占百分比')
    plt.ylabel('每周吃多少公斤的冰淇淋')

    bx = fig.add_subplot(212)
    bx.scatter(datingDataMat[:, 0], datingDataMat[:,1 ], 15.0*array(datingLabels), 15.0*array(datingLabels))
    plt.xlabel('每年飞行里程数')
    plt.ylabel('玩游戏视频消耗时间所占百分比')

    plt.show()
def autoNorm(dataSet):
    #归一化特征值 将值 映射到0-1  (oldvalue-min)/max-min
    minVals = dataSet.min(0) #axis = 0 每列的最小值  axis = 1 每列的最大值
    maxVals = dataSet.max(0) #axis = 0 每列的最小值
    ranges = maxVals - minVals #最大值减去最小值  max-min
    normDataSet = zeros(shape(dataSet)) #创建一个和dataSet相同的0矩阵
    m = dataSet.shape[0] #每行数据大小
    normDataSet = dataSet - tile(minVals, (m, 1)) # 原向量减去最小值  oldvalue-min
    normDataSet = normDataSet / tile(ranges, (m, 1))  #(oldvalue-min)/(max-min)

    return normDataSet, ranges, minVals  #归一化特征值, 最大值减去最小值, 最小值

def datingClassTest():
    #分类器测试
    hoRatio = 0.10
    datingDataMat, datingLabels = file2matrix('C:/Users/lvcun/Desktop/datingTestSet2.txt')  #解析数据
    normMat, ranges, minVals = autoNorm(datingDataMat) #归一化特征值
    m = normMat.shape[0] # 向量数量
    numTestVecs = int(m*hoRatio)  #百分之10 用来测试
    errorCount = 0.0 #错误率
    for i in range(numTestVecs): #对于每个测试数据
        classifierResult = classify0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3) #计算距离 k-临近值
        print('the classifier came back with: %d, the real answer is: %d'%(classifierResult, datingLabels[i]))
        if (classifierResult != datingLabels[i]) :
            errorCount += 1.0
    print('The total error rate is : %f'%(errorCount/float(numTestVecs)))
def classifyPerson():
    reusltList = ['not at all', 'in small doses', 'in large doses']
    percentTats = float(input('Percentage of time spent playing video games?'))
    ffMiles = float(input('frequent flier miles earned per year ?'))
    iceCream = float(input('liters of ice cream consumed per year'))
    datingDataMat, datingLabels = file2matrix('C:/Users/lvcun/Desktop/datingTestSet2.txt')
    normMat, ranges, minVals = autoNorm(datingDataMat) #归一化特征值
    inArr = array([ffMiles, percentTats, iceCream])
    classifierResult = classify0((inArr - minVals)/ ranges, normMat, datingLabels, 3)
    print('you will probably like this person:', reusltList[classifierResult - 1])
    
classifyPerson()

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值