码迷,mamicode.com
首页 > 编程语言 > 详细

机器学习-kNN算法

时间:2019-04-09 20:56:35      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:文件   with   asi   style   冰淇淋   提取   print   输入   思想   

1、前沿

    K最近邻(k-Nearest Neighbor,KNN)分类算法可以说是最简单的机器学习算法了。它采用测量不同特征值之间的距离方法进行分类。它的思想很简单:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

选择k个最相似数据中出现次数最多的分类。其算法描述如下:

K-近邻算法的一般流程
(1): 收集数据:提供文本文件
(2):准备数据:使用 Python 分析文本文件
(3):分析数据:使用 Matplotlib 画二维扩散图。
(4):测试算法:使用文本文件的部分数据作为测试样本,计算错误率。
(5):使用算法:错误率在可接受范围内,就可以运行k-近邻算法进行分类。

理解可参考大神博客:https://blog.csdn.net/zouxy09/article/details/16955347

2、kNN基础实践

from numpy import *

def createDataSet(): group = array([[0, 0], [0, 0.1], [1.0, 1.1], [1.0, 1.0]]) labels = [‘A‘, ‘A‘, ‘B‘, ‘B‘] return group, labels def kNNClassify(newInput, dataSet, labels, k): numSamples = dataSet.shape[0] diff = tile(newInput, (numSamples, 1)) - dataSet squaredDiff = diff ** 2 squaredDist = sum(squaredDiff, axis=1) distance = squaredDist ** 0.5 sortedDistIndices = argsort(distance) # 给出每个点在列表中大小的排列 例如:列表[7,9,5,10],结果为[1,2,0,3] classCount = {} for i in range(k): voteLabel = labels[sortedDistIndices[i]] classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 # 如果能够取到那么便加 1,如果取不到便为 0。 maxCount = 0 for key, value in classCount.items(): if value > maxCount: maxCount = value maxIndex = key return maxIndex if __name__ == ‘__main__‘: dataSet, labels = createDataSet() testX = array([1.2, 1.0]) k = 3 outputLabel = kNNClassify(testX, dataSet, labels, k) print(outputLabel)

# 自行理解基础,挺简单的。

3、根据网上修改凯伦约会网站

import numpy as np
import matplotlib.pyplot as plt

"""
准备数据  大神博客:https://www.cnblogs.com/asialee/p/9307337.html
"""


def file2matrix(filename):
    with open(filename, r) as f:
        array_lines = f.readlines()
        number_lines = len(array_lines)
        return_mat = np.zeros((number_lines, 3))
        # 返回的分类标签向量
        class_label_vector = []
        index = 0
        for line in array_lines:
            line = line.strip()
            list_from_line = line.split(\t)
            # 将数据前三列提取出来,存放到return_mat的NumPy矩阵中,也就是特征矩阵
            return_mat[index, :] = list_from_line[0:3]
            # 根据文本中标记的喜欢程度进行分类,1代表不喜欢。2代表魅力一般。3代表急剧魅力。
            if list_from_line[-1] == didntLike:
                class_label_vector.append(1)
            elif list_from_line[-1] == smallDoses:
                class_label_vector.append(2)
            elif list_from_line[-1] == largeDoses:
                class_label_vector.append(3)
            index += 1
    return return_mat, class_label_vector


"""
分析数据,数据可视化,使用 Matplotlib 创建散点图
"""


def show_data(return_mat, class_label_vector):
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(return_mat[:, 1], return_mat[:, 2], 15.0 * np.array(class_label_vector),
               15.0 * np.array(class_label_vector))
    plt.show()


"""
准备数据:归一化数值。
    因为四组数据中,获取的飞行常客里程数对于计算结果影响远远大于其他两个特征,但这三个特征是同等重要的,
    因此作为三个等权重的特征之一,飞行常客里程数并不该如此严重的影响到计算结果。因此我们通常采用的方法是数值归一化,将取值范围
    处理为0到1之间。
new_value = (old_value-min)/(max-min)
"""


def auto_norm(data_set):
    # 获得每列数据的最小值和最大值
    min_value = data_set.min(0)
    max_value = data_set.max(0)
    # 最大值和最小值的范围
    ranges = max_value - min_value
    m = data_set.shape[0]
    # 原始值减去最小值
    norm_data_set = data_set - np.tile(min_value, (m, 1))
    # 除以最大和最小值的差,得到归一化数据
    norm_data_set = norm_data_set / np.tile(ranges, (m, 1))
    # 返回归一化数据结果,数据范围,最小值
    return norm_data_set, ranges, min_value


"""
KNN算法分类器
in_x:用于分类的数据(测试集)。
data_set:用于训练的数据(训练集)。
labels:训练数据的分类标签。
k :kNN算法参数,选择距离最小的 k 个点。
sorted_class_count[0][0] 分类结果。
"""


def knn_classify(in_x, data_set, labels, k):
    data_set_size = data_set.shape[0]
    diff_mat = np.tile(in_x, (data_set_size, 1)) - data_set
    sq_diff_mat = diff_mat ** 2
    sq_distances = sq_diff_mat.sum(axis=1)
    distances = sq_distances ** 0.5
    sorted_dist_indices = distances.argsort()
    class_count = {}
    for i in range(k):
        vote_label = labels[sorted_dist_indices[i]]
        class_count[vote_label] = class_count.get(vote_label, 0) + 1  # 如果能够取到那么便加 1,如果取不到便为 0。
    max_count = 0
    for key, value in class_count.items():
        if value > max_count:
            max_count = value
            max_index = key
    return max_index


"""
测试算法,计算分类器的准确率,验证分类器
"""


def dating_class_test():
    file_name = F:\KNN-master\datingTestSet.txt
    dating_data_mat, dating_labels = file2matrix(file_name)
    ho_ratio = 0.1
    norm_data_set, ranges, min_value = auto_norm(dating_data_mat)
    m = norm_data_set.shape[0]
    num_test_vec = int(m * ho_ratio)
    error_count = 0.0
    for i in range(num_test_vec):
        class_fire_result = knn_classify(norm_data_set[i, :], norm_data_set[num_test_vec:m, :],
                                         dating_labels[num_test_vec:m], 4)
        print(分类结果:%d\t真实类别:%d % (class_fire_result, dating_labels[i]))
        if class_fire_result != dating_labels[i]:
            error_count += 1.0
    print(错误率:%f%% % (error_count / float(num_test_vec * 100)))


"""
使用算法,构建完整可用系统
"""


def classify_person():
    # 输出结果
    result_list = [不喜欢, 有些喜欢, 非常喜欢]
    # 三维特征用户输入
    f_miles = float(input(每年飞行常客里程数:))
    percent_game = float(input(玩游戏所消耗时间百分比:))
    ice_cream = float(input(每周消费的冰淇淋公升数:))
    file_name = F:\KNN-master\datingTestSet.txt
    dating_data_mat, dating_labels = file2matrix(file_name)
    norm_data_set, ranges, min_value = auto_norm(dating_data_mat)
    in_arr = np.array([f_miles, percent_game, ice_cream])
    # 测试集归一化
    nor_min_arr = (in_arr - min_value) / ranges
    classifier_result = knn_classify(nor_min_arr, norm_data_set, dating_labels, 3)
    print("你可能%s这个人" % (result_list[classifier_result - 1]))


if __name__ == __main__:
    return_mat, class_label_vector = file2matrix(F:\KNN-master\datingTestSet.txt)
    show_data(return_mat, class_label_vector)
    dating_class_test()
    classify_person()

kNN算法实现起来还是可以实现的,数据集大神博客有连接的可自行去下载。

机器学习-kNN算法

标签:文件   with   asi   style   冰淇淋   提取   print   输入   思想   

原文地址:https://www.cnblogs.com/fierydragon/p/10679262.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!