KNN小白心得

最近在学习机器实战学习,作为一名小白,怕自己忘了,之后就会把每一个照着书本实践后的代码运行成功连带注释的记录下来,供学完这本书后复习使用。

1.K-临近算法(kNN)

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
def classify0(inX,dataSet,labels,k):
    #:用于分类的输人向量是inX,输人的训练样本集为dataSet,标签向量为labels,最后的参数义表示用于选择最近邻居的数目
    dataSetSize = dataSet.shape[0]#shape函数是numpy中的函数,功能是读取矩阵长度,shanpe[0]表示读取矩阵第一维度的长度

    diffMat = tile(inX,(dataSetSize,1))-dataSet
    sqDiffMat = diffMat**2#矩阵每个元素值平方
    sqDistances = sqDiffMat.sum(axis=1)#sum(axis=1)是将一个矩阵的每一行向量相加
                                       # sum(axis=0)是将一个矩阵的每一列向量相加
                                       # 对一维数组,只有第0轴,没有第1轴
    distances = sqDistances**0.5#0.5次方
    sortedDistIndicies = distances.argsort()#argsort函数返回的是数组值从小到大的索引值 不是值,是索引值
    #上面是计算距离欧氏距离公式,计算两个向量点“和成之间的距离0 :d = 」(xA0 - xB0 )2 + (xA1 - xB1 )2

    classCount={}
    for i in range(k):#选择距离最小的k个点
        voteIlable1 = labels[sortedDistIndicies[i]]
        classCount[voteIlable1]=classCount.get(voteIlable1,0)+1
    sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)#排序
    return  sortedClassCount[0][0]

group,lables=createDataSet()
print classify0([0 , 0 ] , group, lables, 3)
... prompt'''

2.约会网站使用K临近算法

出现的问题是:
特征值之间不能一概而论,进行差值计算时,有些特征值对于结果的影响要远远大于其他特征值,但是有没有明确说明该特征值对于结果影响很大,这个时候,不能直接计算,要先进行数值归一化处理。
通过newValue={oldValue-min)/(max-min)这个公式,可以将任意特征值的数值转化成0-1之间的值。
其中min和max分别是数据集中的最小特征值和最大特征值。虽然改变数值取值范围增加了分类器的复杂度,但为了得到准确结果,我们必须这样做。

# -*- coding: utf-8 -*-
from numpy import *
import matplotlib
import matplotlib.pyplot as plt
import operator#导入运算符模块

#将文本记录转化成矩阵
def file2matrix(filename):
    fr = open(filename)
    arrayOLines = fr.readlines()
    numberOfLines = len(arrayOLines)
    #得到文件行数
    returnMat = zeros((numberOfLines,3)) #zeros创建0矩阵numberOfLines行3列
    #3列因为规定只有3个主要特征属性,要返回创建的numpy特征矩阵
    classLabelVector = []#将最后一列元素即结果存储在这之中
    index = 0
    #解析文件数据到列表
    for line in arrayOLines:
        line = line.strip()#s.strip(rm)删除s字符串中开头、结尾处,位于 rm删除序列的字符当rm为空时,
                           # 默认删除空白符(包括'\n', '\r',  '\t',  ' ')
        listFromLine = line.split('\t')#划分
        returnMat[index,:]=listFromLine[0:3]#[index,:]矩阵或二维数组切片,index表示行
        classLabelVector.append(int(listFromLine[-1]))#下标为-1表示最后一个元素
        index += 1
    return returnMat, classLabelVector

#将特征数值进行归一化处理
def autoNorm(dataSet):
    minVals = dataSet.min(0)
    maxVals = dataSet.max(0)
    ranges = maxVals-minVals
    normDataSet = zeros(shape(dataSet))#shanpe()读取矩阵长度
    m = dataSet.shape[0]#shape[0]查看行数
    normDataSet = dataSet - tile(minVals,(m,1))#tile创建矩阵minVals弄成m行1列
    normDataSet = normDataSet/tile(ranges,(m,1))
    #根据公式newValue={oldValue-min)/(max-min)
    return normDataSet,ranges,minVals

#进行knn算法分类计算
def classify0(inX,dataSet,labels,k):
    #:用于分类的输人向量是inX,输人的训练样本集为dataSet,标签向量为labels,最后的参数义表示用于选择最近邻居的数目
    dataSetSize = dataSet.shape[0]#shape函数是numpy中的函数,功能是读取矩阵长度,shanpe[0]表示读取矩阵第一维度的长度

    diffMat = tile(inX,(dataSetSize,1))-dataSet
    sqDiffMat = diffMat**2#矩阵每个元素值平方
    sqDistances = sqDiffMat.sum(axis=1)#sum(axis=1)是将一个矩阵的每一行向量相加
                                       # sum(axis=0)是将一个矩阵的每一列向量相加
                                       # 对一维数组,只有第0轴,没有第1轴
    distances = sqDistances**0.5#0.5次方
    sortedDistIndicies = distances.argsort()#argsort函数返回的是数组值从小到大的索引值 不是值,是索引值
    #上面是计算距离欧氏距离公式,计算两个向量点“和成之间的距离0 :d = 」(xA0 - xB0 )2 + (xA1 - xB1 )2

    classCount={}
    for i in range(k):#选择距离最小的k个点
        voteIlable1 = labels[sortedDistIndicies[i]]
        classCount[voteIlable1]=classCount.get(voteIlable1,0)+1
    sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)#排序
    return  sortedClassCount[0][0]


#对分类器进行错误率检测

def datingClassTest():
    hoRatio = 0.50#取数据50%进行测试
    datingDataMat,datinglabels=file2matrix('date_knn2.txt')
    nornMat,ranges,minVals=autoNorm(datingDataMat)
    m=nornMat.shape[0]
    numTestVecs = int(m*hoRatio)
    errorCount=0.0
    for i in range(numTestVecs):
        classifierResult = classify0(nornMat[i,:],nornMat[numTestVecs:m,:],datinglabels[numTestVecs:m],3)#nornMat[i,:]表示获取nornMat矩阵第i行
                                                                                                        # #nornMat[numTestVecs:m,:]表示取得行数不能大于m
        print "预测的结果是:%d,正确的结果是:%d"%(classifierResult,datinglabels[i])
        if(classifierResult != datinglabels[i]):errorCount +=1.0
    print "预测错误率是:%f" %(errorCount/float(numTestVecs))


datingDataMat,datinglabels = file2matrix("date_knn2.txt")

fig = plt.figure()
ax=fig.add_subplot(111)
ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datinglabels),15.0*array(datinglabels))#x轴为第二个特征,y轴为第三个特征
#plt.show()

#nornMat,ranges,minVals= autoNorm(datingDataMat)
#print nornMat,ranges,minVals

#正式运用约会网站预测
def clasifyPerson():
    resultList = ['不喜欢','还行','喜欢']
    percentTats = float(raw_input("比例的时间花在游戏上"))
    ffMiles = float(raw_input("每年跑多少里程的路"))
    iceCream = float(raw_input("冰淇淋每年消耗多少升"))
    datingDataMat,datinglabels = file2matrix('date_knn2.txt')
    normMat,ranges,minVals = autoNorm(datingDataMat)
    inArr = array([ffMiles,percentTats,iceCream])
    classifierResult = classify0((inArr-minVals)/ranges,normMat,datinglabels,3)
    print"你可能的感觉是:",resultList[classifierResult-1]

#datingClassTest()
clasifyPerson()


... prompt'''

总结

K-近邻算法是基于实例的学习,使用算法时我们必须有接近实际数据的训练样本数据。K-近邻算法必须保存全部数据集,如果训练数据集的很大,必须使用大量的存储空间。
此外,由于必须对数据集中的每个数据计算距离值,实际使用时可能非常耗时。K-近邻算法的另一个缺陷是它无法给出任何数据的基础结构信息,因此我们也无法知晓平均实例样本和典型实例样本具有什么特征。决策树可以解决这个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值