1、前沿

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

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

选择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算法实现起来还是可以实现的,数据集大神博客有连接的可自行去下载。

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄