机器学习实战之程序清单1-kNN(约会网站)

本文介绍k近邻算法(kNN)的实现过程,并通过约会网站数据集进行演示。从环境搭建、算法实现到数据预处理及分类器测试,详细展示了kNN算法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文记录机器学习实战中案例的实践过程。


配置python开发环境就不在赘述,要注意的是机器学习实战这本书用的是python2,如果像我一样用python3的话有一些代码是需要修改的。

程序清单2-1 k近邻算法(kNN)

#定义k近邻算法的函数,参数分别是:测试样本inX,训练样本集dataSet,训练样本集的标签labels,选择最近邻居的数目k
def classify0(inX,dataSet,labels,k):

    #定义dataSetSize,取值为dataSet第一维的数目,即dataSet内的数据条数
    dataSetSize = dataSet.shape[0]
    #先将测试样本拓展成和dataSet同样的尺寸,然后相减
    diffMat = tile(inX,(dataSetSize,1)) - dataSet
    #将上一步得到的矩阵的每一个数据平方
    sqDiffMat = diffMat**2
    #将上一步得到的矩阵的每一行的元素相加得到一个新的尺寸为dataSetSize*1的矩阵
    sqDistances = sqDiffMat.sum(axis=1)
    #得到距离,即上面的矩阵开根号,这几步用的是数学中计算两点距离的公式 d = √[(x₁-x₂)²+(y₁-y₂)²]
    distances = sqDistances**0.5
    #argsort函数返回的是数组值从小到大的索引值
    sortedDisInddicies = distances.argsort()

    classCount={}
    #找出距离最近的k个点中出现频率最高的分类
    for i in range(k):
        voteIlabel = labels[sortedDisInddicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
        #print i,voteIlabel,classCount
        sortedClassCount = sorted(classCount.items(),#sort
                            key = operator.itemgetter(1),reverse = True)
                            #print sortedClassCount
    return sortedClassCount[0][0] 

程序清单2-2 读入文件,转化成矩阵,用matplotlib做出图像

点这里下载datingTestSet.txt文件

def file2matrix(filename):

    #读文件
    fr = open(filename)
    arrayOlines = fr.readlines()
    numberOfLines = len(arrayOlines)
    #创建numpy矩阵,尺寸为numberOfLines*3,用来存放解析出的数据
    returnMat = zeros((numberOfLines,3))
    #创建上面矩阵的标签向量
    classLabelVector = []
    index = 0
    #下面的循环将解析出的数据放入矩阵中
    for line in arrayOlines:
        #line.strip()函数删除line的头部和尾部的空白符(包括'\n','\r', '\t', ' ')
        line= line.strip()
        #将line按\t分割成一个一个的字符(如a\tbb\tccc\td将会被分成[a,bb,ccc,d])
        listFromLine = line.split('\t')
        returnMat[index,:] = listFromLine[0:3]
        classLabelVector.append(int(listFromLine[-1]))
        index += 1
    return returnMat,classLabelVector

到这里就得到了训练数据的矩阵了,下面可以用matplotlib做出它的图像:
可以写一个main.py用来做测试用,下面是main.py的代码

# -*- coding: utf-8 -*-
"""
Created on Fri Oct  6 20:37:39 2017
@author: bjk
"""

import kNN
import matplotlib
import matplotlib.pyplot as plt
from numpy import *


#得到数据,做出图像(注意此处数据文件要和工程放在同一个目录下)
datingDateMat,datingLabels = kNN.file2matrix('datingTestSet.txt')
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(datingDateMat[:,0],datingDateMat[:,1],15.0*array(datingLabels),15.0*array(datingLabels))
plt.show()

绘制图像如下:

程序清单2-3 归一化特征值

计算距离时,根据距离公式,数值差距大的属性对距离影响很大,比如飞行里程数,这是不够准确的,所以要将数值都归一化到[0,1]区间。

def autoNorm(dataSet):
    #得到dataSet的每一列的最小值
    minVals = dataSet.min(0)
    #得到dataSet的每一列的最大值
    maxVals = dataSet.max(0)
    #计算范围(这三步目的是得到属性的取值范围)
    ranges = maxVals - minVals
    #初始化一个尺寸和dataSet一样的矩阵,用来存放归一化后的dataSet
    normDataSet = zeros(shape(dataSet))
    #得到dataSet的数据条数
    m = dataSet.shape[0]
    #得到归一化后的矩阵,tile函数把minVals复制成与dataSet尺寸一样的矩阵
    normDataSet = dataSet - tile(minVals,(m,1))
    normDataSet = normDataSet/tile(ranges,(m,1))
    return normDataSet,ranges,minVals

程序清单2-4 分类器针对约会网站的测试代码

def datingClassTest():

    #定义用于测试的数据占总数据的10%
    hoRatio = 0.10
    #调用file2matrix读数据文件,得到矩阵
    datingDateMat,datingLabels = file2matrix('datingTestSet.txt')
    #得到归一化后矩阵
    normMat,ranges,minVals = autoNorm(datingDateMat)
    #用于测试的数据向量
    numTestVecs = int(m*hoRatio)
    #错误次数
    errorCount = 0.0
    #调用classify0()将测试数据(总数据前10%),训练数据(总数据后90%),训练数据标签,k传入
        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]))
        #若判断结果与测试数据标签不同,则错误次数+1
        if(classifierResult != datingLabels[i]):
            errorCount += 1.0
    print("the total error rate is: %f" %(errorCount/float(numTestVecs)))

测试这段代码同样简单,将kNN.datingClassTest() 这段代码放到main.py里然后运行即可

程序清单2-5 约会网站预测函数

def classifyPerson():
    resultList = ['not at all','in small doses','in big doses']
    percentTats = float(input('pecentage of time spent playing viedo games ?'))
    ffMiles = float(input('frequent flier miles earned per year ?'))
    iceCream = float(input('liters of ice cream consumed per year ?'))
    datingDateMat,datingLabels = file2matrix('datingTestSet.txt')
    normMat,ranges,minVals = autoNorm(datingDateMat)
    inArr = array([ffMiles,percentTats,iceCream])
    classifierResult = classify0((inArr - minVals)/ranges,normMat,datingLabels,3)
    print('you will probably like this person:',resultList[classifierResult - 1])

这个函数功能是接受你输入的参数,然后调用分类算法,告知你预测的结果,测试他同样简单,在main.py内加上kNN.classifyPerson()调用它即可。

点这里到下一篇机器学习实战之程序清单1-kNN(手写数字识别系统)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值