k-алгоритм ближайшего соседа (kNN)

машинное обучение Python алгоритм сбор данных

1. Введение

  алгоритм k-соседей (kNN)Это очень лаконичный и простой в освоении алгоритм машинного обучения, непараметрический статистический алгоритм классификации и регрессии.    Эта статья сначала знакомит с идеей и процессом алгоритма k-близости, а затем знакомит с реализацией kNN на Python. Полный текст на основемашинное обучение в действии, подчеркивая собственное понимание автора. Кроме того, см.Scipy Lecture Notes, Википедия и множество блогов.

2. Описание

2.1 Принцип работы

  Есть набор обучающей выборки (x,y), и каждая выборка x^(i) имеет соответствующую метку y^(i), то есть для каждой обучающей выборки мы знаем классификацию выборки. После этого введите немаркированные данные тестовой выборки x_new и выберите ближайшее евклидово расстояние (*) к x_new в наборе обучающей выборки.kОчки, получите метки k образцов, метка с наибольшим количеством вхождений - это метка y_new для x_new, то есть: классифицируйте x_new как y_new Class. Среди них k

  • Евклидово расстояние: геометрическое расстояние. как:(0, 0, 0)и(1, 2, 3)Евклидово расстояние равноd = \sqrt{(1-0)^2 + (2-0)^2 + (3-0)^2}

2.2 Описание алгоритма

  1. Вычислите евклидово расстояние между неизвестными данными классификации x_new и данными набора обучающей выборки x
  2. Упорядочить расстояние в порядке возрастания
  3. выбрать первые k точек расстояния
  4. Выберите категорию y с наибольшей частотой среди первых k точек в качестве классификации x_new.

  

3. Реализация Python

import numpy as np
import os
from collections import Counter

3.1 Импорт данных

3.1.1 Импорт данных с помощью NumPy

использоватьnp.loadtxt()Данные, разделенные пробелами, могут быть прочитаны.

def read_file(file_path):
    file = np.loadtxt(file_path) # 读取txt文件
    feature = file[:, :-1]  # 前n-1列构成特征矩阵
    label = file[:, -1]     # 最后一列构成标签向量
    return feature, label

3.1.2 Преобразование фотографий текстового формата 32*32 в векторы

def img_to_vector(file_path):
    lines = 32 # 像素大小
    with open(file_path) as f: # 用这种形式,将自动执行f.close()
        data = list() # 生成一个空的list
        # 使用f.readline()逐行遍历文本,添加到data后
        for i in range(lines):
            data.append(list(f.readline())[:lines])
        # 循环结束后,生成一个32*32矩阵
        return_vector = np.array(data).ravel() # 将矩阵扁平化为一个向量
    return return_vector

3.1.3 Прочитайте папку и сгенерируйте матрицу обучающей выборки

def read_digits(file_path):
    file_lists = os.listdir(file_path) # 读取文件夹下所有文件名,生成list
    file_num = file_lists.__len__() # 文件数m
    matrix = np.zeros((file_num, 1024), dtype=np.int) # 生成矩阵(m*2014)
    for i in range(file_lists.__len__()):
        abs_file_path = file_path + file_lists[i] # 文件绝对路径
        vector = img_to_vector(abs_file_path) # 获取文件生成的向量
        matrix[i] = vector # 为矩阵(m*2014)赋值
    return matrix

3.2 Нормализованные данные

Функция    выборочной нормализации заключается в преобразовании собственных значений любого диапазона значений в значения в интервале от 0 до 1.   new_value = (old_value - min) / (max - min)

def auto_norm(data_mat):
    min_column = np.min(data_mat, axis=0) # 获取每一列的最小值
    max_column = np.max(data_mat, axis=0) # 获取每一列的最大值
    range_column = max_column - min_column # 获取每一列的取值范围(max - min)
    data_mat = data_mat - min_column # (old_value - min)
    norm_feature_mat = np.true_divide(data_mat, range_column)
    return norm_feature_mat

3.3 Расчет расстояния

# x为待测试点,point为训练样本集中的点
# NumPy数组可以进行许多便捷的操作
def cal_distance(x, point):
    temp = (point - x)**2
    return temp.sum(axis=1)

3.4 Классификация

# in_x 测试数据,可以不止一组
# data_set, labels 分别为训练集和训练集标签
# k 不必赘述
def classify(in_x, data_set, labels , k):
    result_labels = np.zeros((in_x.shape[0], ), dtype=np.int) # 分类结果向量
    for i in range(in_x.shape[0]):
        distance = cal_distance(in_x[i], data_set) # 计算距离
        mask = distance.argsort()[:k] # 选取前k个点
        k_array = labels[mask] # 利用掩码获取k个点的标签
        result_labels[i] = Counter(k_array).most_common(1)[0][0] # 获取出现频率最高的标签
    return result_labels

Электронная почта автора: mr.yxj@foxmail.com Пожалуйста, сообщите автору перепечатки, спасибо!