临近取样算法(KNN)笔记

5 篇文章 0 订阅
4 篇文章 0 订阅

综述

  1. Cover和Hart在1968年提出了最初的临近算法
  2. 输入基于实例的学习(instance-based learning)
  3. 懒惰学习(lazy learning)

算法步骤

  1. 为了判断未知类别实例的类别,以所有已知类别的实例作为参照
  2. 选择参数K
  3. 计算未知实例与所有已知实例的距离
  4. 根据少数服从多数的投票法则(majority-voting)
  5. 让未知实例归类为k个最邻近样本中最多数的类别

细节(关于K)

关于距离的衡量方法:
1.Euclidean Distance定义:
在这里插入图片描述
E ( x , y ) = ∑ i = 0 n ( x i − y i ) 2 E(x,y)=\sqrt{\sum\limits_{i=0}^n(x_i-y_i)^2} E(x,y)=i=0n(xiyi)2
其他距离衡量:余弦值(cos),相关度(correlation),曼哈顿距离(Manhattan distance)

例子1

在这里插入图片描述
预测G点的电影类型:
我们计算G点到各个点之间的距离

import math

def ComputeEuclideanDistance(x1, y1, x2, y2):
    d = math.sqrt(math.pow((x1 - x2), 2) + math.pow((y1 - y2), 2))
    return d

if __name__ == '__main__':
    d_ag = ComputeEuclideanDistance(3, 104, 18, 90)
    d_bg = ComputeEuclideanDistance(2, 100, 18, 90)
    d_cg = ComputeEuclideanDistance(1, 81, 18, 90)
    d_dg = ComputeEuclideanDistance(101, 10, 18, 90)
    d_eg = ComputeEuclideanDistance(99, 5, 18, 90)
    d_fg = ComputeEuclideanDistance(98, 2, 18, 90)
    
    print("d_ag:",d_ag)
    print("d_bg:",d_bg)
    print("d_cg:",d_cg)
    print("d_dg:",d_dg)
    print("d_eg:",d_eg)
    print("d_fg:",d_fg)

输出

d_ag: 20.518284528683193
d_bg: 18.867962264113206
d_cg: 19.235384061671343
d_dg: 115.27792503337315
d_eg: 117.41379816699569
d_fg: 118.92854997854805

由此看到最近的距离是a、b、c三个点,所以G点归类为romance

算法优缺点:

优点:
1. 简单
2. 易于理解
3. 容易实现
4. 通过对K的选择可具备丢噪音数据的键壮性
缺点:
在这里插入图片描述

  1. 需要大量空间存储所有已知实例
  2. 算法复杂度高(需要比较所有已知实例与要分类的实例)
  3. 当其样本分布不平衡时,比如其中一类样本过大(实例数量过多)占主导的时候,新的未知实例容易被归类为这个主导样本,因为这类样本实例的数量过大,但这个新的未知实例实际并没接近目标样本
改进版本

考虑距离,根据距离加上权重
比如:1/d (d:距离)

实例2

根据150个实例,实例包含萼片长度(sepal length),萼片宽度(sepal width),花瓣长度(petal length),花瓣宽度(petal width)
类别:
iris setosa, iris versicolor, iris virginica
1.利用python的机器学习库sklearn: SKLearnExample.py实现

from sklearn import neighbors
from sklearn import datasets

knn = neighbors.KNeighborsClassifier() # 调用分类器

iris = datasets.load_iris() # 返回iris数据库

# print(iris)

# iris.data为4*150矩阵的特征值,iris.target为矩阵对应的一维的对象
knn.fit(iris.data, iris.target)  # 建立模型对象,同时传入数据参数

predictedLabel = knn.predict([[0.1, 0.8, 0.3, 0.9]]) # 预测

print(predictedLabel)

2.完全手写算法

import csv
import random
import math
import operator

def loadDataset(filename, split, trainingSet=[], testSet=[]):
    """
    对数据进行整理
    :filename: 导入数据集文件名称
    :split: 区分训练集与测试集指标
    :trainingSet: 训练集
    :testSet: 测试集
    """
    with open(filename, 'r') as csvfile:
        lines = csv.reader(csvfile)
        dataset = list(lines)
        for x in range(len(dataset)-1):
            for y in range(4):
                dataset[x][y] = float(dataset[x][y])
            if random.random() < split:
                trainingSet.append(dataset[x])
            else:
                testSet.append(dataset[x])

def euclideanDistance(instance1, instance2, length):
    """
    算出其k
    :instance1: 表示训练集的点
    :instance2: 表示预测集的点
    :length: 表示维度
    """
    distance = 0
    for x in range(length):
        distance += pow((instance1[x] - instance2[x]), 2)
    return math.sqrt(distance)

def getNeighbors(trainingSet, testInstance, k):
    """
    返回距离测试实例的最近的邻居
    :trainingSet: 数据项
    :testInstance: 一个测试实例
    :k: k个数量训练集距离testInstance的label
    """
    distances = []
    length = len(testInstance) - 1
    for x in range(len(trainingSet)):
        dist = euclideanDistance(testInstance, trainingSet[x], length)
        distances.append((trainingSet[x], dist))
    distances.sort(key=operator.itemgetter(1)) # 获取对象第一个域里的值
    print(distances)
    neighbors = []
    for x in range(k):
        neighbors.append(distances[x][0])
    return neighbors

def getResponse(neighbors):
    """
    统计邻居分类的多少
    :neighbors: 邻居数据
    :return: 邻居分类最多的 
    """
    classVotes = {}
    for x in range(len(neighbors)):
        response = neighbors[x][-1]
        if response in classVotes:
            classVotes[response] += 1
        else:
            classVotes[response] = 1
    sortedVotes = sorted(classVotes.items(), key=operator.itemgetter(1), reverse=True) # reverse按降序排列
    return sortedVotes[0][0]

def getAccuracy(testSet, predictions):
    """
    预测算法的精确度
    :testSet: 测试集
    :predictions: 算法算出的结果
    """
    correct = 0
    for x in range(len(testSet)):
        if testSet[x][-1] == predictions[x]:
            correct += 1
    return (correct/float(len(testSet))) * 100.0

def main():
    tariningSet = []
    testSet = []
    split = 0.67
    print(split)
    loadDataset(r'irisdata.txt', split, tariningSet, testSet)
    print('Train set:' + repr(len(tariningSet)))
    print('Train set:' + repr(len(testSet)))
    predictions = []
    k = 3
    for x in range(len(testSet)):
        neighbors = getNeighbors(tariningSet, testSet[x], k)
        result = getResponse(neighbors)
        predictions.append(result)
        # print('> predicted=' + repr(result) + ', actual=')
    accuracy = getAccuracy(testSet, predictions)
    print('Accuracy: ' + repr(accuracy) + '%')

if __name__ == '__main__':
    main()   

代码以及所有用到的材料请到码云上下载:
https://gitee.com/wolf_hui/MachineLearning

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 定位指纹算法是一种用于室内定位的技术,通过收集和分析Wi-Fi指纹来确定移动设备的位置。Wi-Fi信号的强度在不同位置有所变化,通过创建指纹数据库并使用机器学习算法,可以根据Wi-Fi信号强度来预测移动设备的位置。 定位指纹算法的基本步骤包括以下几个方面: 1. 数据收集:首先在要进行定位的区域内选择一些采样地点,使用移动设备收集Wi-Fi信号的强度数据,并记录每个采样点的准确位置信息。 2. 数据预处理:对收集到的数据进行预处理,包括去除异常值、数据平滑、数据规范化等操作,提高数据的质量。 3. 特征提取:从预处理后的数据中提取出有用的特征,通常使用Wi-Fi信号的强度作为特征。 4. 指纹数据库构建:将特征与其对应的位置信息构建成指纹数据库,以便后续的定位计算。 5. 定位计算:根据待定位设备的Wi-Fi信号强度,与指纹数据库中的数据进行匹配,使用机器学习算法KNN算法,通过选择最近邻的指纹数据来推测设备的位置。 KNN(k-nearest neighbors)算法是一种常用的分类算法,也可以用于定位指纹算法中的位置推测。KNN算法的基本原理是通过测量待分类数据与训练数据之间的距离,将待分类数据归类为与其距离最近的k个训练数据所属的类别。在定位指纹算法中,可以将指纹数据库中的数据看作是训练数据,根据待定位设备的Wi-Fi信号强度与数据库中的数据进行距离计算,选择距离最近的k个数据点的位置信息,通过统计这些数据点的位置信息来推测待定位设备的位置。 定位指纹算法KNN算法的结合,可以实现室内定位的功能。通过建立指纹数据库和使用KNN算法,可以提高定位的准确性和精度,为室内导航、智能家居等应用提供便利。 ### 回答2: 定位指纹算法是一种用于室内定位的技术,它利用WiFi、蓝牙等无线信号和传感器数据来确定用户在建筑物内的位置。定位指纹算法的基本原理是通过收集并分析大量的指纹数据,建立一个与位置相关的指纹数据库。当用户需要定位时,算法会将用户当前收集到的指纹特征与数据库中的指纹进行比对,找到最匹配的位置,并给出对应的坐标。 定位指纹算法主要包括指纹采集、指纹处理和位置估计三个步骤。指纹采集通过无线信号接收器或传感器设备获取用户所处位置的信号强度、延迟等参数,进而形成指纹样本。指纹处理是将采集到的原始指纹数据进行预处理和特征提取,以便于后续的匹配和定位。位置估计是根据当前的指纹特征与数据库中的指纹特征进行比对,利用各种分类或回归算法来估计用户的位置。 KNN算法,即k最近邻算法,是一种常见的分类和回归算法。它的核心思想是通过测量不同特征之间的距离,找到与待分类样本最接近的k个样本,根据它们的标签来对待分类样本进行分类或回归。在定位指纹算法中,可以将指纹样本的特征作为样本的特征向量,然后利用KNN算法对用户当前的指纹特征进行分类,得到最近邻的位置估计结果。 定位指纹算法KNN算法的结合,可以实现对用户在室内位置的准确定位。通过收集和处理大量的指纹数据,并结合KNN算法的分类或回归能力,可以减小定位误差,提高定位的准确性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值