《机器学习实战》笔记-----K近邻算法约会软件

考研人信息库

 考研对信息的获取至关重要,此公众号会发表计算机考研(初复试信息)、夏令营等资料,方便考研人对信息的获取,节约自身查找资料的时间

1.KNN算法

import numpy as np
import operator

def createDataset():
    group=np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]);
    labels = ['A','A','B','B'];
    return group,labels;
#knn
def classify0(inX, dataSet, labels, k):
    """
    inX:用于分类的输入向量
    dataSet:输入的训练样本集
    lables:标签向量
    k:表示用于选择最近邻居的数目

    预测数据所在分类可在输入下列命令
    kNN.classify0([0,0], group, labels, 3)
    """
    # array的shape函数返回指定维度的大小,如dataset为n*m的矩阵,
    # 则dataset.shape[0]返回n,dataset.shape[1]返回m,dataset.shape返回n,m
    dataSetSize = dataSet.shape[0]
    # tile函数简单的理解,它的功能是重复某个数组。比如tile(A,n),功能是将数组A重复n次,构成一个新的数组
    # 所以此处tile(inX,(dataSetSize,1))的作用是将inX重复复制dataSetSize次,以便与训练样本集的样本个数一致
    # 减去dataSet就是求出其差值,所以diffMat为一个差值矩阵
    diffmat = np.tile(inX, (dataSetSize, 1)) - dataSet
    # 距离度量,度量公式为欧氏距离,每行的分量计算平方
    sqdiffmat = diffmat ** 2
    # 将矩阵的每一行相加,axis用于控制是行相加还是列相加,axis=0为列相加
    sqdistances = sqdiffmat.sum(axis=1)
    # 开方
    distances = sqdistances ** 0.5
    # 根据距离排序从小到大的排序,返回对应的索引位置
    '''
    numpy.argsort(a, axis=-1, kind=’quicksort’, order = None)
    返回的是数组值从小到大的索引值
    参数:
    a为要排序的数组
    axis:按哪一维进行排序
    kind:排序算法的选择,有quicksort,mergesort,heapsort对于一维数组
    '''
    sortedDistIndicies = distances.argsort()
    # 选择距离最小的k个点
    classcount = {}

    for i in range(k):
        # 找到该样本标签的类型
        voteIlabel = labels[sortedDistIndicies[i]]
        # 字典的get方法,list.get(k,d) 其中 get相当于一条if...else...语句,参数k在字典中,字典将返回list[k];如果参数k不在字典中则返回参数d
        classcount[voteIlabel] = classcount.get(voteIlabel, 0) + 1
        # 字典的 items() 方法,以列表返回可遍历的(键,值)元组数组。
        # sorted 中的第2个参数 key=operator.itemgetter(1) 这个参数的意思是先比较第几个元素
        sortedClasscount = sorted(classcount.items(), key=operator.itemgetter(1), reverse=True)
        # 返回最符合的标签
        return sortedClasscount[0][0]


if __name__ == '__main__':
    #创建数据集
    group, labels = createDataset()
    #测试集
    test = [0,0]
    #kNN分类
    test_class = classify0(test, group, labels, 3)
    #打印分类结果
    print(test_class)

2.准备数据:从文本文件中解析数据

def file2matrix(filename):
    #打开文件
    fr = open(filename)
    #print(fr)
    #读取文件所有内容:['40920\t8.326976\t0.953952\tlargeDoses\n', '14488\t7.153469\t1.673904\tsmallDoses\n',......
    arrayOLines = fr.readlines()
    #print(arrayOLines)
    #得到文件行数
    numberOfLines = len(arrayOLines)
    #返回的NumPy矩阵,解析完成的数据:numberOfLines行,3列
    '''
    np.zeros函数的作用
    返回来一个给定形状和类型的用0填充的数组;
    zeros(shape, dtype=float, order=‘C’)
    shape:形状
    dtype:数据类型,可选参数,默认numpy.float64
    order:可选参数,c代表与c语言类似,行优先;F代表列优先
    '''
    returnMat = np.zeros((numberOfLines,3))
    #返回的分类标签向量
    classLabelVector = []
    #行的索引值
    index = 0
    for line in arrayOLines:
        #s.strip(rm),当rm空时,默认删除空白符(包括'\n','\r','\t',' ')
        '''
        Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
        注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
        '''
        line = line.strip()
        #使用s.split(str="",num=string,cout(str))将字符串根据'\t'分隔符进行切片。
        #str -- 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
        #num -- 分割次数。默认为 -1, 即分隔所有。
        listFromLine = line.split('\t')
        #将数据前三列提取出来,存放到returnMat的NumPy矩阵中,也就是特征矩阵
        returnMat[index,:] = listFromLine[0:3]
        #根据文本中标记的喜欢的程度进行分类,1代表不喜欢,2代表魅力一般,3代表极具魅力
        if listFromLine[-1] == 'didntLike':
            classLabelVector.append(1)
        elif listFromLine[-1] == 'smallDoses':
            classLabelVector.append(2)
        elif listFromLine[-1] == 'largeDoses':
            classLabelVector.append(3)
        index += 1
    return returnMat, classLabelVector

3.分析数据:使用Matplotlib创建散点图

import matplotlib.pyplot as plt
from KNN.约会网站实例 import kNN2
import numpy as np
datingDataMat,datingLabels= kNN2.file2matrix('datingTestSet.txt')
fig=plt.figure()#figure() 函数会产生一个指定编号为 num 的图:plt.figure(num)这里,figure(1) 其实是可以省略的,因为默认情况下 plt 会自动产生一幅图像。
ax=fig.add_subplot(1,1,1)
#分别取第2列和第三列的全部元素,需记住这种写法.scatter()绘制散点图
ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*np.array(datingLabels),15.0*np.array(datingLabels))
plt.show()

4.准备数据:归一化数值

#归一化特征。由于特征值的取值范围差别很大,我们认为每个特征应该同等重要,所以要做归一化操作
def autoNorm(dataSet):
    if __name__ == '__main__':
        minVal=dataSet.min(0)#数组,将每列的最小值放到minVal中
        #print(minVal)
        maxVal=dataSet.max(0)
        ranges=maxVal-minVal
        normDataSet=np.zeros(np.shape(dataSet))
        m=dataSet.shape[0]
        #print(np.tile(minVal,(m,1)))
        normDataSet=dataSet-np.tile(minVal,(m,1))#tile(minVals, (m,1)) 的功能是将数组  minVals 按(m,1)数组的维度叠加(即叠加m行,1列)。
        normDataSet=normDataSet/np.tile(ranges,(m,1))
        return normDataSet,ranges,minVal

5.测试算法:算法评估,验证分类器效果

'''测试算法分类器'''
def datingclassTest():
    hoRatio = 0.10   #拿样本10%的数据测试
    datingDataMat,datingLabels = file2matrix('datingTestSet.txt')
    normMat,ranges,minVals = autoNorm(datingDataMat)
    m = normMat.shape[0]
    numTestVecs = int(m*hoRatio)#测试数据量
    errorCount = 0.0
    for i in range(numTestVecs):
        '''normMat[i,:],normMat[numTestVecs:m,:]    前10%作为测试集,后m-numtestvecs个作为训练集'''
        classifierResult = kNN.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)))
    print(errorCount)

6.使用算法:构建完整程序,用户输入数据进行分类判断

'''约会预测函数'''
def classifyPerson():
    resultList = ['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('datingTestSet.txt')
    normMat,ranges,minVals = autoNorm(datingDataMat)
    inArr = np.array([ffMiles,percentTats,iceCream])#测试数组
    #对输入的数据做归一化
    classifierResult = kNN.classify0((inArr-minVals)/ranges,normMat,datingLabels,4)
    print('You will probably like this person:',resultList[classifierResult - 1])

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值