机器学习实战——K-近邻算法

数据集和源代码有需要的童鞋可以私信我~

K-近邻算法

K-近邻算法有称为KNN算法(k-Nearest Neighbour algorithm)。

1.原理

1.1基本原理

K-近邻算法原理:给定已知标签类别的训练数据集,输入没有标签的新数据后,在训练集种找到与新数据最邻近的k个实列,如果这k个实例的多数属于某个类别,那么新数据就属于这个类别。
图一
图1中,蓝色方块和红色三角为两种类别,现在需要判断绿色原点属于那种类别:
当k=3时,绿色圆点属于红色三角这类;
当k=5时,绿色圆点属于蓝色方块这类。

举个例子,k-近邻算法可以用来分类电影的所属类型。
表1

可以计算出未知电影到已知电影的距离,按照距离递增排序,就可以找到k个距离最近电影。这k个距离最近的电影类别出现最多就是未知电影的类别。
表2  已知电影到未知电影的距离

假设,k=3,前三部电影都是“爱情片”,则可以认为未知电影也是“爱情片”。

1.2距离计算

知道了K-近邻算法的基本原理后,下一步要做的就是来求解距离。
K-邻近算法中计算距离采用的时欧氏距离,二维、三维的欧氏距离高中便已经学过:
三维欧式公式:

∣ A B ∣ = ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 + ( z 1 − z 2 ) 2 3 \lvert AB \rvert = \sqrt[3]{(x_1-x_2)^2+(y_1-y_2)^2+(z_1-z_2)^2} AB=3(x1x2)2+(y1y2)2+(z1z2)2
扩展到N维:
∣ A B ∣ = ( x 1 − y 1 ) 2 + ( x 1 − y 2 ) 2 + . . . . . . . + ( x n − y n ) 2 n = ∑ ( x i − y i ) 2 n \lvert AB \rvert = \sqrt[n]{(x_1-y_1)^2+(x_1-y_2)^2+.......+(x_n-y_n)^2}=\sqrt[n]{\sum{(x_i-y_i)^2}} AB=n(x1y1)2+(x1y2)2+.......+(xnyn)2 =n(xiyi)2
我们可以通过以上公式计算出未知电影到已知电影的距离。

2.算法实现

在了解K-邻近算法后,可以利用python来实现这些过程:

from numpy import*
import operator
import matplotlib
import  matplotlib.pyplot as plt
#打开文件,读取数据
def openfile(filename):
    fr = open(filename)
    arrayOlines = fr.readlines()
    numberOfLines = len(arrayOlines)
    returnMat = zeros((numberOfLines,3))
    index = 0
    classLabelVector = []
    for lines in  arrayOlines:
        lines = lines.strip()
        listFromLine = lines.split('\t')
        returnMat[index,:] = listFromLine[0:3]
        classLabelVector.append(listFromLine[-1])
        index += 1
    return returnMat,classLabelVector

#数据归一化处理
def autoNorm(dataSet):
    minVector = dataSet.min(0)
    maxVector = dataSet.max(0)
    ranges = maxVector - minVector
    normdataSet = zeros(shape(dataSet))
    normdataSet = dataSet - tile(minVector,(dataSet.shape[0],1))
    normdataSet = normdataSet/tile(ranges,(dataSet.shape[0],1))
    return  normdataSet,ranges,minVector

def classfy0(inX,dataSet,labels,k):
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inX,(dataSetSize,1)) - dataSet
    sqDiffMat = diffMat**2
    sumDance = sqDiffMat.sum(axis = 1)
    distances = sqrt(sumDance)
    SortDance = distances.argsort()
    classCount = {}
    for i in range(k):
        LabelVector = labels[SortDance[i]]
        classCount[LabelVector] = classCount.get(LabelVector,0) + 1
    sortedClassCount = sorted(classCount.items(),key = operator.itemgetter(1),reverse=True)
    return sortedClassCount[0][0]
def datingClasstest(path):
    hoRadio = 0.1
    datingDataMat,datingLabel = openfile(path)
    normDataMat,ranges,minVector = autoNorm(datingDataMat)
    m = normDataMat.shape[0]
    numTestVector = int(hoRadio*m)
    errorCount = 0.0
    for i in range(numTestVector):
        classifileResult = classfy0(datingDataMat[i,:],datingDataMat[numTestVector:m,:],datingLabel[numTestVector:m],3)
        print('the classifileReult is :{}  ,the real label is :{}'.format(classifileResult,datingLabel[i]))
        if (classifileResult != datingLabel[i]):
            errorCount += 1
    print('the total error is :',(errorCount/(numTestVector)))

path = 'datingTestSet.txt'
m,n =openfile(path)
datingClasstest(path)
fig = plt.figure()
ax = fig.add_subplot(111)
#ax.scatter(m[:,1],m[:,2],15.0*array(n),15.0*array(n))
ax.scatter(m[:,0],m[:,1],15.0*array(n),15.0*array(n))
plt.show()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值