Machine Learning in Action/机器学习实践:kNN算法之约会问题

因为自己比较忙,就没有太多时间去学习python的基础知识,所以简单的看了一点py的语法,就直接上书开始敲代码了,中间遇到比较多的问题,所以就加了很多注释(用的python3)

from numpy import * #导入科学计算包Numpy
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

'''
    (1)计算已知类别数据集中的点与当前点的距离
    (2)按照距离递增次序排列
    (3)选取与当前点距离最小的k个点
    (4)确定前k个点所属类别出现的频率
    (5)返回频率最高的类别,作为当前点的预测分类
'''
def classify0(inX, dataSet, labels, k):
    #set.shape[0] 求数组的行数。 set.shape[1]求数组的列数。求出源数据的行数
    dataSetSize = dataSet.shape[0]
    #tile(inX,(dataSetSize,1))将inX复制成一个dataSetSize行的数列, inX用于分类的向量,dataSet用于训练的向量,diffMat,用于分类的点,到各个点的向量
    diffMat = tile(inX, (dataSetSize, 1)) - dataSet

    sqDiffMat = diffMat**2
    #.sum(axis=1)矩阵的每一行相加的和
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5
    #argsort()将数组排序之后的下标,由大到小返回
    sortedDistIndicies = distances.argsort()
    classCount = {}
    for i in range(k):
        #从1到k读取第一到第k元素的标签
        voteIlabel = labels[sortedDistIndicies[i]]
        #对读取到的标签加一
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
        #排序后输出标签数最大的那个  
    sortedClassCount = sorted(classCount.items(),key = operator.itemgetter(1), reverse = True)
    return sortedClassCount[0][0]

#创建file2matrix讲txt文件中的数据转化为矩阵的形式,并返回
def file2matrix(filename):
#打开filename文件,并返回文件指针
    fr = open(filename)
    #读取文件的所有行并作为一个列表放回,包含所有的行结束符
    arrayOLines = fr.readlines()
#获取文件的行数
    numberOfLines = len(arrayOLines)
#创建一个列为3,行为数据行数的矩阵,用于储存数据
    returnMat = zeros((numberOfLines,3))
    classLabelVector = []
    index = 0
    for line in arrayOLines:
        #line.strip()删除行中的空白字符
        line = line.strip()
        #通过制表字符\t对line切片
        listFromLine = line.split('\t')
#将数据读取到returnMat矩阵中
        returnMat[index,:] = listFromLine[0:3]
#将标签读取到classLabelVecor矩阵中
        classLabelVector.append(int(listFromLine[-1]))
        index += 1
    return returnMat,classLabelVector
#将数据归一化
def autoNorm(dataSet):
    #找到最大和最小的数据
    minVals = dataSet.min(0)
    maxVals = dataSet.max(0)

    ranges = maxVals - minVals
    #创建一个行数和dataSet相同的空矩阵
    normDataSet = zeros(shape(dataSet))
    #获取数据集合的行数
    m = dataSet.shape[0]
    #将数据集合的每个数据都减去最小值
    normDataSet = dataSet - tile(minVals,(m,1))
    #将减之后的数据,处以范围
    normDataSet = dataSet/tile(ranges,(m,1))
    #返回归一化之后的数据,数据的极差,数据的最小值
    return normDataSet, ranges, minVals

#test
def datingClassTest():
    #测试的数据和总数据的占比
    hoRatio = 0.10
    #通过文件读取约会数
    datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
    #归一化约会数据
    normMat, ranges, minVals = autoNorm(datingDataMat)
    #获取归一化数据后的行数
    m = normMat.shape[0]
    #得到需要测试的数据大小
    numTestVecs = int(m*hoRatio)
    #用于计算预测失误的数量
    errorCount = 0.0
    #遍历测试数据
    for i in range(numTestVecs):
        #将数据带入函数进行比较,k取3
        classifierResult = classify0(normMat[i,:], normMat[numTestVecs:m,:], datingLabels[numTestVecs:m],3)
        #打印测试结果,和真实结果
        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():
    #创建结果集合
    resultList = ['not at all', 'in small does', 'in large doess']
    #对数据进行输出 py3将raw_input改为input
    percentTats = float(input("percenttage 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("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 man:%s" %(resultList[classifierResult-1]))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值