纯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日

相关文章

  • JS栈stack类的实现与使用方法示例

    JS栈Stack类的实现与使用方法示例 一、栈的概念 栈(stack)是一种线性数据结构,它有两个主要操作:入栈(push)和出栈(pop)。栈的特点是先进后出(FILO,First In, Last Out)。从数据结构的角度来说,栈是在同一端进行插入和删除操作的一种数据结构。该端被称为栈顶,相对地,把另一端称为栈底。 在计算机科学中,栈具有非常重要的作用…

    算法与数据结构 2023年5月19日
    00
  • JavaScript中几种排序算法的简单实现

    JavaScript中几种排序算法的简单实现 排序算法在计算机科学中是一个基本问题。不同的排序算法具有不同的时间和空间复杂度,选择合适的排序算法可以提高程序的效率。本文介绍了JavaScript中几种排序算法的简单实现,包括冒泡排序、选择排序、插入排序、归并排序和快速排序。 冒泡排序 冒泡排序是最简单的排序算法之一。它重复遍历列表,比较相邻的元素,并交换它们…

    算法与数据结构 2023年5月19日
    00
  • 手把手教你搞懂冒泡排序和选择排序

    手把手教你搞懂冒泡排序和选择排序 冒泡排序 冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复地进行直到没有再需要交换的数据为止。 算法流程 比较相邻的元素。如果当前的元素大于下一个元素,则交换它们的位置。 对每一对相邻元素都执行步骤 1,从开始第一对到…

    算法与数据结构 2023年5月19日
    00
  • JavaScript数据结构与算法之二叉树添加/删除节点操作示例

    首先让我们来介绍一下“JavaScript数据结构与算法之二叉树添加/删除节点操作示例”这个主题。 主题介绍 本主题主要介绍了在 JavaScript 中对于二叉树数据结构进行添加/删除节点操作的示例代码。二叉树是一种常见的树形结构,在计算机科学领域中被广泛应用。节点的添加与删除是该数据结构中常见的操作之一,本主题将通过示例代码,为您详细介绍操作的过程。 代…

    算法与数据结构 2023年5月19日
    00
  • MySQL order by与group by查询优化实现详解

    MySQL的order by与group by是常用的查询优化手段,本篇攻略将详细讲解order by与group by的使用方法及其优化实现。 1. MySQL Order By MySQL Order By 用于对查询结果进行排序,将查询结果按照指定字段的顺序进行排列 ,默认升序排序,也可以指定为降序排序。 SELECT column1, column2…

    算法与数据结构 2023年5月19日
    00
  • PHP字符串逆序排列实现方法小结【strrev函数,二分法,循环法,递归法】

    下面我将为您详细讲解“PHP字符串逆序排列实现方法小结【strrev函数,二分法,循环法,递归法】”的完整攻略。 什么是字符串逆序排列? 字符串逆序排列指的是将一个字符串中的字符按照相反的顺序重新排列,比如将字符串 “hello world” 更改为 “dlrow olleh”。 使用strrev函数实现字符串逆序排列 PHP内置函数 strrev() 可以…

    算法与数据结构 2023年5月19日
    00
  • C#归并排序的实现方法(递归,非递归,自然归并)

    下面是关于C#归并排序的实现方法的完整攻略: 什么是归并排序? 归并排序是一种基于分治法的算法,具体实现方法是将原序列分成若干个子序列,分别进行排序,然后将排好序的子序列合并成一个大的有序序列。 递归实现归并排序 递归实现归并排序分为三步: 分解数组:将要排序的数组从中间分成两个部分,即分为左右两个子数组。这里使用数组下标来实现。 递归排序子数组:对分解出来…

    算法与数据结构 2023年5月19日
    00
  • C++实现合并排序的方法

    C++ 是一门功能强大的编程语言,提供了多种排序算法来满足不同场景的需要。其中,合并排序是一种常用的高效排序算法,下面我们就来介绍一下 C++ 实现合并排序的方法。 合并排序算法简介 合并排序算法是一种基于归并操作的排序算法,它的基本思想是将一个数组划分为两个子数组,递归地对这两个子数组分别进行排序,然后将排好序的两个子数组合并成一个有序的数组。该算法的时间…

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