《机器学习实战》Code1-KNN

本博客是学习《机器学习实战》例子后,自己对书上的例子代码总结的个人理解。在代码必要的地方,添加了注解。博客书写的目的是,方便后续的复习。


k-邻近算法:选择样本集中特征比较最邻近的k个点,将这K个点中出现次数最多的分类,作为新数据的分类。

k-邻近算法对异常值不敏感(采用k个数据投票的方式),并且预先不需要训练算法(输入特征向量后,全局计算距离,没有之前没有训练好的分类器)。

k-邻近算法是分类数据中最简单有效地算法。但是k-邻近算法具有存储空间和时间复杂度开销大的问题。k-邻近算法必须保存全部的数据集,如果训练的数据很大,必须花费大量的存储空间。此外,必须对数据集中每个数据计算距离数值,非常耗时。

K决策树是k-邻近算法算法的优化版,可以节省大量的资源开销。


机器学习实战中 KNN第1个例子 

#!/usr/bin/env python 
# -*- coding:utf-8 -*-

#KNN book example 2.1
#learn in 2018.11.6
from numpy import *
import operator

def createDataSet():
    group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]) #array将一个列表转换成数组,所以参数必须是列表 b=array([1,3,3])
    labels=['A','A','B','B']
    return group,labels


def classify0(inx,dataSet,labels,k):
    # shape 输出矩阵的维度,如group是[4,2]。shape[0]输出4,为矩阵的行数,同理shape[1]输出列数。shape[2]以上报错,因为没有第三维度
    dataSetSize=dataSet.shape[0]

    #tile 格式函数  b = [1, 3, 5]  tile(b, [2, 3]) --> array([[1, 3, 5, 1, 3, 5, 1, 3, 5],  [1, 3, 5, 1, 3, 5, 1, 3, 5]])
    diffMat=tile(inx,(dataSetSize,1))-dataSet
    # print 'diffMat',diffMat
    sqDiffMat=diffMat**2
    print 'sqDiffMat',sqDiffMat

    # 当axis=0,就是将一个矩阵的每一列向量相加;当axis=1,就是将一个矩阵的每一行向量相加
    sqDistances=sqDiffMat.sum(axis=1)
    print 'sqDistances',sqDistances
    distances=sqDistances**0.5
    print 'distances',distances

    #argsort 从小到大排序,提取其对应的index(索引),然后输出到y
    sortedDistIndicies=distances.argsort()
    print 'sortedDistIndicies',sortedDistIndicies

    classCount={}
    for i in range(k):
        voteIlabel=labels[sortedDistIndicies[i]]
        #字典中,如果该key不存在,返回默认值
        classCount[voteIlabel]=classCount.get(voteIlabel,0)+1

    #降序排序  reverse=True
    #sorted(iterable,key,reverse) iterable表示可以迭代的对象,  key是一个函数,
    # 用来选取参与比较的元素,reverse则是用来指定排序是倒序还是顺序,
    #iteritems()返回一个迭代器
    #operator模块提供的itemgetter函数用于获取对象的哪些维的数据,获取对象的第1个域的值
    sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)

    return sortedClassCount[0][0]

def main():
    # help(sorted)
    group, labels = createDataSet()
    inx=[0,0]
    k=3
    result=classify0(inx, group, labels, k)
    print result



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

def Classfy(curP,points,labels,k):
    shape=points.shape[0]
    print shape
    Point=(tile(curP,[shape,1])-points)**2
    print Point
    Pointsum=Point.sum(axis=1)**0.5
    print Pointsum
    # 列表排序
    Pointsort=Pointsum.argsort()
    print Pointsort
    votecount={}
    for i in range(k):
        #字典累加赋值
        label=labels[Pointsort[i]]
        votecount[label]=votecount.get(label,0)+1
    print votecount
    #字典排序
    sortcount=sorted(votecount.iteritems(),key=operator.itemgetter(1),reverse=True)
    print sortcount
    print sortcount[0][0]

def recode():
    points,labels=MkData()
    curP=[0,0]
    Classfy(curP,points,labels,3)

main()
recode()

 机器学习实战中 KNN第2个例子 ---社交约会网站

#!/usr/bin/env python 
# -*- coding:utf-8 -*-

#KNN book example 2.2
#learn in 2018.11.6

from numpy import *
import operator

import matplotlib
import matplotlib.pyplot as plt

def file2matrix(filename):
   file=open(filename)
   arrayOLines=file.readlines()
   # print 'arrayOLines',arrayOLines

   #len 函数,求出列表中一共有多少元素
   numberLines=len(arrayOLines)
   # print 'numberLines',numberLines
   # 该函数功能是创建给定类型的矩阵,并初始化为1000行3列0矩阵
   #一维数组  zeros(3)
   #二维数组 zeros((2,3)) [[  ],[  ],...,[  ]]
   returnMat=zeros((numberLines,3))
   # print returnMat.shape[0],returnMat.shape[1]

   classLabel=[]
   index=0
   #遍历列表的方法
   for line in arrayOLines:
       #去除首尾空格,去掉制表符后,返回剩下的列表
       line=line.strip()
       # print line
       listFormLine=line.split('\t')
       # print listFormLine
       returnMat[index,:]=listFormLine[0:3]
       #列表中添加数字,用append方法
       if "largeDoses"==listFormLine[-1]:
           classLabel.append(3)
       elif "smallDoses"==listFormLine[-1]:
           classLabel.append(2)
       else:
            classLabel.append(1)
       index=index+1
   return returnMat,classLabel

# min(0)返回该矩阵中每一列的最小值
# min(1)返回该矩阵中每一行的最小值
# max(0)返回该矩阵中每一列的最大值
# max(1)返回该矩阵中每一行的最大值
def autoNorm(dataSet):
    minVals=dataSet.min(0) #返回每一列最小值,一共3列
    # print 'minVals',minVals
    maxVals=dataSet.max(0)
    # print 'maxVals', maxVals
    #列表之间可以对应直接运算的
    ranges=maxVals-minVals
    # print 'ranges',ranges

    normData=zeros(shape(dataSet))
    m=dataSet.shape[0]
    #有是tile的举证格式运算
    normData=dataSet-tile(minVals,(m,1))
    normData=normData/tile(ranges,(m,1))
    # print 'normData',normData
    return normData

def classify0(inx,dataSet,labels,k):
    #  shape[0]输出4,为矩阵的行数,同理shape[1]输出列数,shape[2]以上报错
    dataSetSize=dataSet.shape[0]
    diffMat=tile(inx,(dataSetSize,1))-dataSet
    # print diffMat
    # 矩阵和列表,都可以直接运算的
    sqDiffMat=diffMat**2
    # print sqDiffMat
    sqDistances=sqDiffMat.sum(axis=1)
    # print sqDistances
    distances=sqDistances**0.5
    # print distances
    sortedDistIndicies=distances.argsort()
    # print sortedDistIndicies
    classCount={}
    for i in range(k):
        voteIlabel=labels[sortedDistIndicies[i]]
        classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
    sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
    return sortedClassCount[0][0]

def main():
    filename="datingTestSet.txt"
    returnMat, classLabel=file2matrix(filename)

    # 可视化数据分布
    fig=plt.figure()#自定义画布
    ax=fig.add_subplot(111) #参数349的意思是:将画布分割成3行4列,图像画在从左到右从上到下的第9块  ax是具体一个局域
    ax.scatter(returnMat[:,0],returnMat[:,1],8.0*array(classLabel),8.0*array(classLabel)) #scatter散点图
    plt.show()
    ax.scatter(returnMat[:, 1], returnMat[:, 2])
    plt.show()

    normData = autoNorm(returnMat)
    testCele=0.1
    m=normData.shape[0]
    testPart=int(m*testCele)
    errorTime=0.0
    k=3
    for i in range(testPart):  #现在操作对象都是矩阵
        result=classify0(normData[i,:],normData[testPart:m,:],classLabel[testPart:m],3)
        if result!=classLabel[i]:
            errorTime=errorTime+1
            print "the classifyresult is", result, "   the real result is ", classLabel[i]
    print errorTime/float(testPart)


main()

 机器学习实战中 KNN第3个例子 ---识别手写数字

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
from numpy import *
import operator
from os import listdir
from knn import *


# 可以读取文件的名字
#KNN book example three(learn digits)  2.3
#learn in 2018.11.6

def img2vec(filename):
    result=zeros((1,1024)) #变成一个矩阵向量
    file=open(filename)
    for i in range(32):
        line=file.readline()
        for j in range(32):
            result[0,i*32+j]=int(line[j])
    return result

def handwritingClassTest():
    lables=[]
    fileList=listdir('trainingDigits')
    print 'fileList',fileList
    m=len(fileList)
    print m
    trainMat=zeros((m,1024))
    for i in range(m):
        file=fileList[i]
        num=int(file.split('.')[0].split('_')[0])
        lables.append(num)
        trainMat[i,:]=img2vec('trainingDigits/%s' %file)  #遍历赋值文件名

    TestfileList = listdir('Digits')
    errotime=0
    Testm = len(TestfileList)
    for i in range(Testm):
        filename=TestfileList[i]
        testnum = int(filename.split('.')[0].split('_')[0])
        testVec=img2vec('trainingDigits/%s' %filename)
        result=classifyResult=classify0(testVec,trainMat,lables,3)
        if result!=testnum:
            errotime+=1
            print "the right num is ",testnum,", but the classify is ",result

    print "error is ",errotime
    print errotime / float(Testm)

def main():
    handwritingClassTest()

main()
# print img2vec("digits/Digits/0_0.txt")

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值