机器学习笔记1-KNN

KNN-K近邻分类算法

作为机器学习入门的算法之一,其数学原理很简单

原理:

即对于测试样本点,寻找与其距离最近的K个样本点,以这K个点的类别作为参考依据,用来判定测试样本点的类别

其中K的取值一般为奇数(3,5,7....等),它是一种基于实例的学习,使用算法时必须有接近实际数据的训练样本。


优点:

1.新数据可以加入数据集而无需再次训练

2.理论简单,易于实现

缺点:

1.必须保存全部数据,对于样本容量大的数据集计算量较大

2.KNN每一次分类都会进行一次全局计算

3.样本不平衡时,计算偏差大

4.K值的大小需要人为选择

5.忽略了样本数据之间的内在联系

如何选择k的值:

  • K值较小就相当于用较小的领域中的训练实例进行预测,“学习”近似误差会减小,只有与输入实例较近或相似的训练实例才会对预测结果起作用,与此同时带来的问题是“学习”的估计误差会增大,换句话说,K值的减小就意味着整体模型变得复杂,容易发生过拟合;
  • K值较大可以减少学习的估计误差,但是学习的近似误差会增大,与输入实例较远的训练实例也会对预测起作用,使预测发生错误,k值增大模型的复杂度会下降。
  • 在应用中,k值一般取一个比较小的值,通常采用交叉验证法来来选取最优的K值。
     

Python代码如下:

import numpy as np
import operator
import matplotlib.pyplot as plt

# KNN
def KNN(x_test, dataSet, labels, k):
    m = len(dataSet)
    diff = dataSet - np.tile(x_test, (m,1))
    distance = np.sqrt((diff**2).sum(axis=1))
    sortedDist = distance.argsort() # 对数字从小到大排序,返回索引值
    classCount= {}
    for i in range(k):
        voteIlabel = labels[sortedDist[i]]
        if voteIlabel not in classCount.keys():
            classCount[voteIlabel] = 0
        classCount[voteIlabel] += 1
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) # 对字典的keys按照value值从大到小排序
    return sortedClassCount[0][0]

# Load dataset
def createdataset(filename):
    fr = open(filename).readlines()
    x_Mat = [];y_Mat =[]
    for line in fr:
        data = [float(example) for example in line.strip().split('\t')]
        x_Mat.append(data[:-1])
        y_Mat.append(data[-1])
    return np.array(x_Mat), np.array(y_Mat)

# Normalization
def autoNorm(dataSet):
    minvalue = np.min(dataSet, axis=0)
    maxvalue = np.max(dataSet, axis=0)
    ranges = maxvalue - minvalue
    normDataSet = (dataSet - minvalue)/ranges
    return normDataSet, minvalue, ranges

# Test
def datingClassTest():
    x_Mat, y_Mat = createdataset('datingTestSet2.txt')
    m = len(x_Mat)
    # 使用Matplotlib绘制原始数据的散点图
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(x_Mat[:, 0], x_Mat[:, 1], 15.0*np.array(y_Mat), 15.0*np.array(y_Mat))
    plt.show()
    # 前90%的数据作为训练集,后10&用于测试
    train_x, train_y = x_Mat[:int(m*0.9), :], y_Mat[:int(m*0.9)]
    test_x, test_y = x_Mat[int(m*0.9):m, :], y_Mat[int(m*0.9):m]
    normDataSet, minvalue, ranges = autoNorm(train_x)
    test_x = (test_x - minvalue)/ranges
    errorCount = 0
    for i in range(len(test_x)):
        result = KNN(test_x[i], normDataSet, train_y, k=3)
        print("the classifier came back with: %d, the real answer is: %d" % (result, test_y[i]))
        if result != test_y[i]: errorCount += 1
    print("The number of errr is: %d" % int(errorCount))
    print("The total error rate is: %f" % (errorCount / float(len(test_x))))

if __name__ == '__main__':
    datingClassTest()







 

你可能感兴趣的:(机器学习篇,机器学习)