最新消息:请随时分享你的乐趣!

机器学习实战-2.KNN临近之算法

技术博客 磊子 284浏览 0评论
目录
[隐藏]

概述

整个KNN的思想是计算某一个给定的点到哪些样本点的距离最近。
K-nn中的k是使用临近的K个点进行判别分类。

代码实现算法步骤

  1. 读取给定的样本数据
  2. 对样本进行矩阵化
  3. 对矩阵进行归一化(归一化特征值,消除属性之间量级不同导致的影响)
  4. 进行测试抽样(用前0.1*sampleCount 作为测试数据)
  5. 对归一化后的数据进行欧氏距离计算。
  6. 取最近(Sort)的k个点进行Label 统计,取值最多的结果(Sort)进行返回.
  7. 计算错误率 sample_error_count /sample_total

优化

  1. 优化的时候直接选择对K值进行训练次数优化。
  2. 数据质量优化

其他知识

  1. 对numpy 得到了进一步了解: tile()、zero()、argsort()、arange()生成器
  2. 矩阵的基本操作:矩阵的加减乘除。
  3. 机器学习概念了解: 归一化、欧氏距离

代码

from operator import itemgetter

from numpy import zeros, array, tile
import pylab

"""
整个KNN的思想是计算某一个给定的点到哪些样本点的距离最近。
K-nn中的k是使用临近的K个点进行判别分类。
属于分类算法
1. 读取给定的样本数据
2. 对样本进行矩阵化
3. 对矩阵进行归一化(归一化特征值,消除属性之间量级不同导致的影响)
4. 进行测试抽样(用前0.1*sampleCount 作为测试数据)
5. 对归一化后的数据进行欧氏距离计算。
6 取最近(Sort)的k个点进行Label 统计,取值最多的结果(Sort)进行返回.
7 计算错误率  sample_error_count /sample_total

优化:
1. 优化的时候直接选择对K值进行训练次数优化。
2. 数据质量优化
"""


def getMatrix(filename):
    """
    读取矩阵
    :param filename: 文件路径
    :return:  样本矩阵,结果标签
    """
    f = open(filename)

    linenum = len(f.readlines())
    matrixN3 = zeros((linenum, 3))
    labels = []
    index = 0

    f.seek(0)
    for line in f.readlines():
        values = line.split("\t")
        matrixN3[index:] = values[0:3]
        # print(matrixN3[index,:],int(values[-1]))
        labels.append(int(values[-1]))
        index += 1

    f.close()

    return matrixN3, labels


def convertNorm(maxtrix):
    """
    归一化(进行特征值归一化)
    :param maxtrix:  原始样本数据矩阵
    :return: 归一化后矩阵,
    """
    maxs = maxtrix.max(0)
    mins = matrix.min(0)
    min_max_diffs = maxs - mins  # 矩阵可以进行统一计算
    xlines = matrix.shape[0]
    # Xmax-Xmin
    maxtrix_bottom = tile(min_max_diffs, (xlines, 1))  # tile(value,(2,3)) 返回 两行三列值为value 的矩阵,如果value是数据,那就横向拷贝

    # Xmin
    maxtrix_min = tile(mins, (xlines, 1))

    # X-Xmin / Xmax-Xmin
    norm_maxtrix = (matrix - maxtrix_min) / maxtrix_bottom

    return norm_maxtrix, min_max_diffs, mins


# def plot_fingue(matrix, labels):
#     """
#     画图
#     :param matrix:
#     :param labels:
#     :return:
#     """
#     pylab.scatter(matrix[:, 1], matrix[:, 2], 10 * array(labels), 10 * array(labels))
#     pylab.show()


# fig = plt.figure()
# ax= fig.add_subplot(111)
# ax.scatter(matrixN3[:, 1], matrixN3[:, 2], 15.0*array(labels), 15.0*array(labels))
#
# fig.show()

# import pylab
# pylab.scatter(matrixN3[:, 1], matrixN3[:, 2], 15.0*array(labels), 15.0*array(labels))
# print("show....")
# pylab.show()

def class0(inLine, matrix, labels, k):
    """
    判别结果
    :param inLine:
    :param matrix:
    :param labels:
    :param k:
    :return:
    """
    total_line = matrix.shape[0]
    inLines = tile(inLine, (total_line, 1))
    matrix_diff = inLines - matrix
    matrix_reslut = (matrix_diff ** 2).sum(axis=1) ** 0.5  # 欧几里得距离
    #第一次Sort:前K个点
    sortedDistance = matrix_reslut.argsort()  # 按值的索引排序
    classCount = {}

    for i in range(k):
        label = labels[sortedDistance[i]]
        classCount[label] = classCount.get(label, 0) + 1
    #第二次Sort ,获取最高次数
    reseult_sorted = sorted(classCount.items(), key=itemgetter(1), reverse=True)
    return reseult_sorted[0][0]


if __name__ == "__main__":
    matrix, labels = getMatrix("datingTestSet2.txt")
    norm_maxtrix, min_max_diffs, mins = convertNorm(matrix)
    # plot_fingue(norm_maxtrix,labels)

    hoRatio = 0.3  # 样本率
    numTestVecs = int(hoRatio * norm_maxtrix.shape[0])
    print("测试样本数为:", numTestVecs)

    errorCount = 0
    # 用前%10 作为样本进行测试, 用后%90作为模型进行匹配
    for i in range(numTestVecs):
        rr = class0(norm_maxtrix[i, :], norm_maxtrix[numTestVecs:, :], labels[numTestVecs:], 3)

        if (labels[i] != rr):
            print("src %s return RR:%s" % (labels[i], rr))
            errorCount += 1

    print("错误率:", errorCount / float(numTestVecs))


转载请注明:印迹. » 机器学习实战-2.KNN临近之算法

发表我的评论
取消评论

表情