纯python实现机器学习之kNN算法示例

首先我们需要清楚kNN算法的基本思想。kNN算法是一种基于实例的有监督学习算法,可以用于分类和回归问题。对于一个新的未标记数据,该算法会根据其与训练集中数据的距离,找到距离该点最近的k个点,然后根据这k个点的标签或者值来对该点进行分类或回归。

以下是具体实现步骤:

准备数据

kNN算法需要一个已经标记好的训练数据集。这里我们以Iris花卉数据集为例。我们先把数据集中的数据提取出来,然后将其随机分为训练集和测试集两部分。

import random

def load_data(filename, split, training_set=[], test_set=[]):
    with open(filename, 'r') as f:
        lines = f.readlines()
        for i in range(len(lines)):
            line = lines[i].strip()
            if len(line) == 0:
                continue
            parts = line.split(',')
            for j in range(4):
                parts[j] = float(parts[j])
            if random.random() < split:
                training_set.append(parts)
            else:
                test_set.append(parts)

training_set = []
test_set = []
load_data('iris.data', 0.66, training_set, test_set)
print(f'Training set: {len(training_set)}')
print(f'Test set: {len(test_set)}')

我们使用了一个load_data函数,将数据集进行加载,并将其分为训练集和测试集。split参数是指将数据随机分为训练集和测试集的比例。这里我们将数据集分为66%的训练数据和33%的测试数据。

计算距离

接下来我们需要根据测试数据和训练数据计算距离。在这里我们使用欧几里得距离来计算距离,其公式为:

$distance = \sqrt{\sum{(a_i - b_i)^2}}$

import math

def euclidean_distance(instance1, instance2, length):
    distance = 0
    for i in range(length):
        distance += pow((instance1[i] - instance2[i]), 2)
    return math.sqrt(distance)

我们使用了一个euclidean_distance函数,该函数接受两个实例instance1和instance2,以及两个实例的长度length作为输入参数,然后使用欧几里得距离公式计算出它们之间的距离。

找到最近的k个点

接下来,我们需要根据测试数据和训练数据计算距离,并找到测试数据最近的k个训练数据点。

import operator

def get_nearest_neighbors(training_set, test_instance, k):
    distances = []
    length = len(test_instance) - 1
    for i in range(len(training_set)):
        dist = euclidean_distance(test_instance, training_set[i], length)
        distances.append((training_set[i], dist))
    distances.sort(key=operator.itemgetter(1))
    neighbors = []
    for i in range(k):
        neighbors.append(distances[i][0])
    return neighbors

在该函数中,我们首先计算每个训练数据点与测试点之间的距离。然后对这些距离进行排序,并选取前k个距离最近的训练数据点作为测试点的邻居。

注:如果有数据距离相同,我们可以按照随机的顺序选择邻居,或者选择距离相同的所有邻居。

预测测试数据的分类

现在我们已经得到了测试数据的k个邻居。接下来我们可以根据这k个邻居的标签来预测出测试点的分类。

def predict_class(neighbors):
    class_votes = {}
    for i in range(len(neighbors)):
        label = neighbors[i][-1]
        if label in class_votes:
            class_votes[label] += 1
        else:
            class_votes[label] = 1
    sorted_votes = sorted(class_votes.items(), key=operator.itemgetter(1), reverse=True)
    return sorted_votes[0][0]

在该函数中,我们遍历测试点的邻居,并统计每个标签出现的次数。然后我们按照标签出现次数从高到低排序,并选择出现次数最高的标签作为测试点的预测分类。

现在我们已经完成了kNN模型的构建。接下来我们可以对测试集中的每个测试数据点进行预测,并计算模型的准确率。以下是完整示例代码:

# kNN algorithm
import random
import math
import operator

def load_data(filename, split, training_set=[], test_set=[]):
    with open(filename, 'r') as f:
        lines = f.readlines()
        for i in range(len(lines)):
            line = lines[i].strip()
            if len(line) == 0:
                continue
            parts = line.split(',')
            for j in range(4):
                parts[j] = float(parts[j])
            if random.random() < split:
                training_set.append(parts)
            else:
                test_set.append(parts)

def euclidean_distance(instance1, instance2, length):
    distance = 0
    for i in range(length):
        distance += pow((instance1[i] - instance2[i]), 2)
    return math.sqrt(distance)

def get_nearest_neighbors(training_set, test_instance, k):
    distances = []
    length = len(test_instance) - 1
    for i in range(len(training_set)):
        dist = euclidean_distance(test_instance, training_set[i], length)
        distances.append((training_set[i], dist))
    distances.sort(key=operator.itemgetter(1))
    neighbors = []
    for i in range(k):
        neighbors.append(distances[i][0])
    return neighbors

def predict_class(neighbors):
    class_votes = {}
    for i in range(len(neighbors)):
        label = neighbors[i][-1]
        if label in class_votes:
            class_votes[label] += 1
        else:
            class_votes[label] = 1
    sorted_votes = sorted(class_votes.items(), key=operator.itemgetter(1), reverse=True)
    return sorted_votes[0][0]

def get_accuracy(test_set, predictions):
    correct = 0
    for i in range(len(test_set)):
        if test_set[i][-1] == predictions[i]:
            correct += 1
    return (correct/float(len(test_set))) * 100.0

def main():
    # prepare data
    training_set = []
    test_set = []
    split = 0.66
    load_data('iris.data', split, training_set, test_set)
    print(f'Training set: {len(training_set)}')
    print(f'Test set: {len(test_set)}')
    # generate predictions
    predictions = []
    k = 3
    for i in range(len(test_set)):
        neighbors = get_nearest_neighbors(training_set, test_set[i], k)
        result = predict_class(neighbors)
        predictions.append(result)
        print(f'prediction: {result}, actual: {test_set[i][-1]}')
    accuracy = get_accuracy(test_set, predictions)
    print(f'Accuracy: {accuracy}%')

main()

当运行以上代码时,它会首先输出训练数据集和测试数据集的信息,然后打印出每个测试数据点的预测分类和实际分类,并计算出kNN模型的准确率。

以上就是使用纯Python实现kNN算法的完整攻略。如果你想了解更多有关kNN算法的实现细节,以及如何将其应用于其他数据集,请参考一些开源的机器学习库或教程。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:纯python实现机器学习之kNN算法示例 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • C#递归算法之分而治之策略

    C#递归算法之分而治之策略 简介 递归算法是一种非常重要的算法,使用递归算法可以解决很多复杂的问题。分而治之是一种常用的递归思路,即将一个问题分成若干个子问题,分别解决,然后将它们的解合并起来得到原问题的解。 分而治之策略 分而治之策略就是将一个复杂的问题分成若干个相同或相似的子问题,并且逐个解决这些子问题,最后统合起来得到原问题的解。这种算法适用于一些可分…

    算法与数据结构 2023年5月19日
    00
  • C++实现广度优先搜索实例

    C++实现广度优先搜索实例攻略 什么是广度优先搜索? 广度优先搜索(Breadth-First Search,也称之为BFS)是一种基于图的搜索算法,用于访问位于某个特定顶点距离为K的所有顶点。它广泛应用于树和图的数据结构中。 BFS的过程如下: 从源节点开始遍历; 访问相邻的节点; 将相邻节点加入队列; 标记已访问的节点; 重复步骤2-4,直到队列为空。 …

    算法与数据结构 2023年5月19日
    00
  • C语言快速排序函数用法(qsort)

    C语言快速排序函数用法(qsort) 简介 快速排序是一种常见的排序算法,而C语言中的qsort函数则是一种快速排序的实现。使用qsort函数,我们无需自己编写快速排序算法的代码,只需要提供一个排序所需的比较函数即可。使用qsort函数,既可以方便的排序数组,还可以排序链表等数据结构。 函数原型 void qsort(void *base, size_t n…

    算法与数据结构 2023年5月19日
    00
  • C#七大经典排序算法系列(下)

    《C#七大经典排序算法系列(下)》是一篇文章,通过介绍七种经典的排序算法,帮助读者更好地理解排序算法的原理和操作,并且让读者掌握这些算法的基本实现方法。本文将会细致地讲解每种算法的思路、时间复杂度以及使用场景,希望读者能在阅读后掌握七种排序算法的差异和选用方法。 文章包含七种排序算法,分别为:冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序和希尔排序…

    算法与数据结构 2023年5月19日
    00
  • JS排序之快速排序详解

    JS排序之快速排序详解 快速排序是一种高效的排序算法,它的核心思想是分治。快排的具体步骤如下: 选择一个基准元素,将序列中所有元素和这个基准元素进行比较,将比基准元素小的元素放入左侧序列,将比基准元素大的元素放入右侧序列。 递归地对左右两个子序列进行快速排序,直到每个子序列只有一个元素或者为空。 示例1:将序列[3,1,6,4,8,2,5,7]进行快速排序。…

    算法与数据结构 2023年5月19日
    00
  • 堆排序算法(选择排序改进)

    堆排序算法是一种基于二叉堆的选择排序改进算法。它利用了二叉堆的特点,可以将排序时间降至O(nlogn)级别。下面我们来详细讲解它的完整攻略。 基本思路 将待排序的序列构建成一个最大堆。 将堆顶的元素(即当前最大元素)跟数组最后一个元素交换位置,然后将剩余的元素进行堆调整,使其满足最大堆的要求。 重复步骤2,直至排序完成。 步骤详解 1. 构建最大堆 对于一个…

    算法与数据结构 2023年5月19日
    00
  • Java 直接插入排序的三种实现

    Java 直接插入排序的三种实现 本文将介绍 Java 中直接插入排序的三种实现方式,分别为插入排序、希尔排序和折半插入排序。 插入排序 插入排序是一种简单直观的排序算法,其基本思想是将一个待排序的元素插入到已排好序列中的适当位置。 以下是 Java 中插入排序的实现代码: public static void insertSort(int[] arr) {…

    算法与数据结构 2023年5月19日
    00
  • C语言实现数组元素排序方法详解

    C语言实现数组元素排序方法详解 概述 数组元素排序是C语言中常见的操作,它将数组中的元素按照一定的规则进行排序,使其符合特定的要求。常见的排序方法包括冒泡排序、插入排序、选择排序、快速排序等。 本文将详细讲解C语言实现数组元素排序的方法,包括上述四种排序方法的原理、代码实现,帮助初学者快速入门。 冒泡排序 冒泡排序是一种简单的排序方法,它依次比较相邻的两个元…

    算法与数据结构 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部