【机器学习】异常检测算法之(KNN)-K Nearest Neighbors

2023-05-16

2c9ee929c567154ec8e55ac364a17747.png

sklearn库里的KNN并没有直接用于异常检测,但是包含了距离计算的函数,所以我们应用PyOD中KNN库进行异常检测,里面基本上也是调用sklearn的函数进行计算,并进行了一些加工。

一、图解KNN异常检算法

KNN怎么进行无监督检测呢,其实也是很简单的,异常点是指远离大部分正常点的样本点,再直白点说,异常点一定是跟大部分的样本点都隔得很远。基于这个思想,我们只需要依次计算每个样本点与它最近的K个样本的平均距离,再利用计算的距离与阈值进行比较,如果大于阈值,则认为是异常点,同样,为了帮助读者理解如何利用KNN思想,实现异常值的识别,我画了下面这张图。对于第一个,3个邻居的平均距离为(2+2+3)/3=2.33,对于第二点,3个邻居的平均距离为(7+8+5)/3=6.667,明显,第二个点的异常程度要高与第一个点。当然,这里除了平均距离,还可以用中位数,也可以用最大距离,通过method这个参数进行控制。

01f10965642c9b72814f4e71ccd7ea40.png

优点是不需要假设数据的分布,缺点是不适合高维数据、只能找出异常点,无法找出异常簇、你每一次计算近邻距离都需要遍历整个数据集,不适合大数据及在线应用、有人用hyper-grid技术提速将KNN应用到在线情况,但是还不是足够快,仅可以找出全局异常点,无法找到局部异常点。

KNN异常检测过程:对未知类别的数据集中的每个点依次执行以下操作:

1) 计算当前点 与 数据集中每个点的距离

2) 按照距离递增次序排序

3) 选取与当前点距离最小的k个点

4) 计算当前点与K个邻居的距离,并取均值、或者中值、最大值三个中的一个作为异常值

1、异常实例计算

无监督,我们就要标签去掉,为了演示过程,我们引进了9号嘉宾,这个人非常自信,每一项都填的非常高,明显异常,我们的目的就是要把这种类似的异常的数据找出来。

05afec3b7d1484ef7033bea02cf967e1.png

2、距离计算和排序

我们计算9号的异常程度,我们这里把计算和排序两步统一到一起了

先计算9号与其他样本的距离,然后排序,取最近的三个,我们计算平均距离,可以看到,9号与最近的三个邻居的平均距离是9.29

aec66b9f66e13353100743c9e1ebb62d.png

3、计算距离值

我们再计算4号嘉宾的距离,可以看到,最近的三个邻居与4号的平均距离为3.07,只是9号的三分之一,相对来说就比较正常了。当然距离计算可以用最大值,平均值,中位数三个,算法中通过method这个参数进行调节。

4ecb34d66c3decf29cdf132c96ef5719.png

我们依次计算,就可以得到每个样本3个邻居的平均距离了,越高的越异常,我们也可以用Python的包来检测下我们计算的对不对。

import numpy as np  
X_train = np.array([
[7,  7,  9,  3],
[5,  4,  5,  6],
[8,  6,  9,  3],
[9,  9,  7,  7],
[5,  5,  5,  5],
[9,  9,  9,  1],
[5,  2,  5,  5],
[8,  8,  7,  6],
[10,10,  12,  13]])
# import kNN分类器
from pyod.models.knn import KNN


# 训练一个kNN检测器
clf_name = 'kNN'
# 初始化检测器clf
clf = KNN( method='mean', n_neighbors=3, )
clf.fit(X_train) 


# 返回训练数据X_train上的异常标签和异常分值
# 返回训练数据上的分类标签 (0: 正常值, 1: 异常值)
y_train_pred = clf.labels_  
y_train_pred
array([0, 0, 0, 0, 0, 0, 0, 0, 1])


# 返回训练数据上的异常值 (分值越大越异常)
y_train_scores = clf.decision_scores_  
y_train_scores
array([2.91709951, 3.01181545, 3.09299219, 4.16692633, 3.07001503,
       4.25784112, 3.98142397, 3.24271326, 9.42068891])

我们自己计算的平均距离为9.29,系统算的9.42,有一点点的差异,可能是哪里加了一个微调的系数,大家可以探索下。

二、KNN异常检测算法应用

上面大概知道了KNN怎么进行异常检测的,现在我们找个具体的案例,看看更加明细的参数以及实现的过程,有个更加立体的感觉,并且学完能够应用起来。

源码地址:https://pyod.readthedocs.io/en/latest/_modules/pyod/models/knn.html#KNN

75c48f4aeadf4b93c63ac98ac13154bd.png

797da7da3ee9339d105dd463cc4daa54.png

1、算法基本用法

地址:https://pyod.readthedocs.io/en/latest/pyod.models.html#module-pyod.models.knn

pyod.models.knn.KNN(contamination=0.1, 
                    n_neighbors=5, 
                    method='largest', 
                    radius = 1.0, 
                    algorithm='auto', 
                    leaf_size=30, 
                    metric='minkowski', 
                    p=2, 
                    metric_params=None, 
                    n_jobs=1, 
                    **kwargs)

2、参数详解

contamination:污染度,contamination : float in (0., 0.5), optional (default=0.1)数据集的污染量,即数据集中异常值的比例。在拟合时用于定义决策函数的阈值。如果是“自动”,则确定决策函数阈值,如原始论文中所示。在版本0.20中更改:默认值contamination将从0.20更改为'auto'0.22。

n_neighbors:选取相邻点数量

method:‘largest’、‘mean’、‘median’

  • largest:使用与第k个相邻点的距离作为异常得分

  • mean:使用k个相邻点距离的平均值作为异常得分

  • median:使用k个相邻点距离的中值作为异常得分

radius : radius_neighbors使用的参数空间半径

algorithm:找到最近的k个样本

  • kd_tree:依次对K维坐标轴,以中值切分,每一个节点是超矩形,适用于低维(<20时效率最高)

  • ball_tree:以质心c和半径r分割样本空间,每一个节点是超球体,适用于高维(kd_tree高维效率低)

  • brute:暴力搜索

  • auto:通过 fit() 函数拟合,选择最适合的算法;如果数据稀疏,拟合后会自动选择brute,参数失效

leaf_sizekd_tree和ball_tree中叶子大小,影响构建、查询、存储,根据实际数据而定。树叶中可以有多于一个的数据点,算法在达到叶子时在其中执行暴力搜索即可。如果leaf size 趋向于 N(训练数据的样本数量),算法其实就是 brute force了。如果leaf size 太小了,趋向于1,那查询的时候 遍历树的时间就会大大增加。

metric:距离计算标准,距离标准图例

  • euclidean:欧氏距离(p = 2)

  • manhattan:曼哈顿距离(p = 1)

  • minkowski:闵可夫斯基距离

p : metric参数,默认为2

metric_params : metric参数

n_jobs : 并行作业数,-1时,n_jobs为CPU核心数。

3、属性详解

decision_scores_数据X上的异常打分,分数越高,则该数据点的异常程度越高

threshold_异常样本的个数阈值,基于contamination这个参数的设置,总量最多等于n_samples * contamination

labels_: 数据X上的异常标签,返回值为二分类标签(0为正常点,1为异常点)

4、方法详解

fit(X): 用数据X来“训练/拟合”检测器clf。即在初始化检测器clf后,用X来“训练”它。

fit_predict_score(X, y): 用数据X来训练检测器clf,并预测X的预测值,并在真实标签y上进行评估。此处的y只是用于评估,而非训练

decision_function(X): 在检测器clf被fit后,可以通过该函数来预测未知数据的异常程度,返回值为原始分数,并非0和1。返回分数越高,则该数据点的异常程度越高

predict(X): 在检测器clf被fit后,可以通过该函数来预测未知数据的异常标签,返回值为二分类标签(0为正常点,1为异常点)

predict_proba(X): 在检测器clf被fit后,预测未知数据的异常概率,返回该点是异常点概率

当检测器clf被初始化且fit(X)函数被执行后,clf就会生成两个重要的属性:

decision_scores: 数据X上的异常打分,分数越高,则该数据点的异常程度越高

5、案例分析

KNN算法专注于全局异常检测,所以无法检测到局部异常。首先,对于数据集中的每条记录,必须找到k个最近的邻居。然后使用这K个邻居计算异常分数。最   大:使用到第k个邻居的距离作为离群值得分;平均值:使用所有k个邻居的平均值作为离群值得分;中位数:使用到k个邻居的距离的中值作为离群值得分

在实际方法中后两种的应用度较高。然而,分数的绝对值在很大程度上取决于数据集本身、维度数和规范化。参数k的选择当然对结果很重要。如果选择过低,记录的密度估计可能不可靠。(即过拟合)另一方面,如果它太大,密度估计可能太粗略。K值的选择通常在10-50这个范围内。所以在分类方法中,选择一个合适的K值,可以用交叉验证法。

#导入
from pyod.models.knn import KNN
from pyod.utils.data import generate_data
from pyod.utils.data import evaluate_print
from pyod.utils.example import visualize


#参数设置
contamination = 0.1  # percentage of outliers
n_train = 200  # number of training points
n_test = 100  # number of testing points


# 数据生成
X_train, y_train, X_test, y_test = generate_data(\
    n_train=n_train, n_test=n_test,\ 
    contamination=contamination)


# import kNN分类器
from pyod.models.knn import KNN


# 训练一个kNN检测器 初始化检测器clf
clf_name = 'kNN'
clf = KNN() 
# 使用X_train训练检测器clf
clf.fit(X_train)


# 返回训练数据X_train上的异常标签和异常分值
# 返回训练数据上的分类标签 (0: 正常值, 1: 异常值)
y_train_pred = clf.labels_


# 返回训练数据上的异常值 (分值越大越异常)
y_train_scores = clf.decision_scores_  


# 用训练好的clf来预测未知数据中的异常值
y_test_pred   = clf.predict(X_test)
y_test_scores = clf.decision_function(X_test)

对识别结果可视化

# 模型可视化
visualize(clf_name, 
          X_train, 
          y_train, 
          X_test, 
          y_test, 
          y_train_pred,
          y_test_pred, 
          show_figure=True, 
          save_figure=False
         )

7e4a6e8683435016a1ab5cc7b3bb0abc.png

···  END  ···

  

  

  

  

  
往期精彩回顾




适合初学者入门人工智能的路线及资料下载(图文+视频)机器学习入门系列下载中国大学慕课《机器学习》(黄海广主讲)机器学习及深度学习笔记等资料打印《统计学习方法》的代码复现专辑
AI基础下载机器学习交流qq群955171419,加入微信群请扫码:

a04e6e8d0bb9812fe9e178a256aaae64.png

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【机器学习】异常检测算法之(KNN)-K Nearest Neighbors 的相关文章

  • 5脚继电器的接法

    5脚继电器原理图和接法 一般情况 xff0c 三只脚的那一边中间脚是输出触点的公共端子 xff0c 另外两个引脚是线圈 xff0c 即接驱动端 另外2个脚那边分别是常开和常闭触点 如下图 xff1a A B 脚接驱动电路端 要控制的电路接1
  • Python -- argparse :命令行参数解析模块

    Python argparse xff1a 命令行参数解析模块 官网参考文档 文章目录 Python argparse xff1a 命令行参数解析模块1 总述2 96 add argument 96 2 1 name or flags2 2
  • PWM波控制舵机总结

    文章转载自 https www cnblogs com zhoubatuo p 6138033 html 一 关于舵机 xff1a 舵机 xff08 英文叫Servo xff09 xff1a 它由直流电机 减速齿轮组 传感器和控制电路组成的
  • PNP三极管和NPN三极管的开关电路

    一 三极管开关电路设计的可行性及必要性 可行性 xff1a 用过三极管的人都清楚 xff0c 三极管有一个特性 xff0c 就是有饱和状态与截止状态 xff0c 正是因为有了这两种状态 xff0c 使其应用于开关电路成为可能 必要性 xff
  • Clark变换与Park(派克)变换

    转载https blog csdn net chenjianbo88 article details 53027298 clark变换 xff1a 将abc 变换到 静止 的 坐标系下 Park变换 xff1a 将abc 变换到 旋转 的
  • 无感方波和FOC堵转检测策略参考

    http mcu eetrend com content 2017 100007230 html 基于S12ZVM的车用无传感器BLDC堵转检测方法探讨 judy 发布于 xff1a 周一 07 31 2017 11 05 xff0c 关键
  • kubernetes 快速入门

    文章目录 2 kubernetes 快速入门前言一 nameSpace1 简介2 常用命令查看 nameSpace创建 nameSpace删除 nameSpace 二 pod 与 deployment1 简介2 常用命令查看 pod创建 d
  • 事件处理的本质

    当在点击一个按钮执行某个操作时 xff0c 你有没有想过 xff0c 为什么点击了这个按钮就会执行某个操作 xff0c 这是为什么 xff1f 那么接下来就让我来解开这里面的秘密 用微软中定义的事件函数来说明这个问题是再简单不过的的事情了
  • 在Ubuntu系统中使用dd工具备份Jetson Xavier NX TF/SD卡

    Jetson Xavier NX TF SD卡系统镜像的备份与恢复 备份环境系统备份系统恢复 本次操作是通过 dd 命令完整克隆系统 这种方法是块设备的 bit 复制 xff0c 所以完全不需要了解上层文件系统的结构和内容 xff0c 只需
  • 深度相机使用对比:Gemini Pro与RealSense D435i

    文章目录 前言一 参数对比二 环境配置三 实际使用效果图像读取视觉slam效果对比 总结 前言 为了开展视觉slam相关项目 xff0c 最近找了几款不同的深度相机进行测试 xff0c 本次主要讲一下奥比中光的Gemini Pro相机与In
  • C++ STL——迭代器

    迭代器 无论是序列容器还是关联容器 xff0c 最常做的操作无疑是遍历容器中存储的元素 xff0c 而实现此操作 xff0c 多数情况会选用 迭代器 xff08 iterator xff09 来实现 我们知道 xff0c 尽管不同容器的内部
  • 理解大端(网络)字节序和小端(部分主机)字节序的区分和转换

    一 基本概念 xff1a 举例 xff1a Mac地址为 xff08 0x xff09 xff1a 00 0c 29 74 33 55 大端字节序就是 xff1a 00 0c 29 74 33 55 xff0c 和我们正常的读写习惯一致 x
  • [图像处理]-Opencv中数据类型CV_8U, CV_16U, CV_16S, CV_32F 以及 CV_64F是什么?

    1 宏定义 首先来说CV 8U CV 16U CV 16S CV 32F 以及 CV 64F xff0c 都是opencv定义的数据类型 具体定义如下 define CV 8S 1 define CV 16U 2 define CV 16S
  • 基于卡尔曼滤波和PID调节的自平衡小车

    资源下载 xff1a 源代码 xff1a http download csdn net download feng3121 10262828 功能图与程序框图 xff1a http download csdn net download fe
  • SBUS调试助手 sbus解析,sbus协议

    最近在做一个无人机用的四路的开关 即航模遥控器PWM信号控制四路继电器 设计硬件的时候专门用了一路可以配置成串口输入的管脚 外部加了一路施密特反相器 其实主要是滤波防止信号抖动 当然私心就是后续可以接SBUS信号 接触航模遥控器时间挺长了
  • Android WebView 网页使用本地字体

    要求在网页里面调用android app中assets目录下的某个字体文件 网页加载通常有两种方式 xff1a 1 loadDataWithBaseURL 2 loadUrl 一 loadDataWithBaseURL 网页中直接使用fil
  • 若依前后端分离版,图片上传后无法显示问题

    若依前后端分离版 xff0c 部署时通常会采用Nginx做反向代理 访问图片出现404 Not Found问题 若依在文件上传成功后 xff0c 请求访问后台地址会根据profile进行匹配 xff0c 需要自己配置代理 配置方式一 xff
  • Vue项目使用history模式,打包部署到二级目录

    需求 xff1a Vue项目使用history模式 xff0c 打包部署到服务器上的二级目录 示例 xff1a your host name h5 index html 原理 xff1a 把页面地址所有含有 h5 的url重定向到 xff1
  • Springboot 服务jar的外部指定端口和文件方式

    在命令行中指定启动端口 java jar xxx jar server port 61 9000 在命令行中指定启动端口与配置文件 java jar xxx jar server port 61 8980 spring profiles a
  • 【Android】本地图片选择(打开媒体库,选择图片)

    在此调查中我要实现的是 xff1a 点击Pictures 按钮后 xff0c 获取手机内所有图片 xff0c 选择某一个图片 xff0c 并显示到ImageView中 应用范围 xff1a 图片上传时的图片选择 xff0c 类似 34 浏览

随机推荐

  • 【Android】获取手机中已安装apk文件信息(PackageInfo、ResolveInfo)(应用图片、应用名、包名等)

    众所周知 xff0c 通过PackageManager 可以获取手机端已安装的apk 文件的信息 xff0c 具体代码如下 PackageManager packageManager 61 this getPackageManager Li
  • 【Android】状态栏通知Notification、NotificationManager详解

    在Android系统中 xff0c 发一个状态栏通知还是很方便的 下面我们就来看一下 xff0c 怎么发送状态栏通知 xff0c 状态栏通知又有哪些参数可以设置 xff1f 首先 xff0c 发送一个状态栏通知必须用到两个类 xff1a N
  • 【Android动画】之Tween动画 (渐变、缩放、位移、旋转)

    Android 平台提供了两类动画 一类是Tween动画 xff0c 就是对场景里的对象不断的进行图像变化来产生动画效果 xff08 旋转 平移 放缩和渐变 xff09 第二类就是 Frame动画 xff0c 即顺序的播放事先做好的图像 x
  • 面试题之Linux58个面试常问【附带答案】

    面试题之Linux58问 目录 1 Linux常用的发行版 2 在Linux里面查看指定时间段的日志文件 3 将文件中所有的old字符以new代替 4 修改文件中第n行到第m行以new代替old 5 统计字符串在文件中出现的次数 6 查看文
  • 【Android布局】在程序中设置android:gravity 和 android:layout_Gravity属性

    在进行UI布局的时候 xff0c 可能经常会用到 android gravity 和 android layout Gravity 这两个属性 关于这两个属性的区别 xff0c 网上已经有很多人进行了说明 xff0c 这边再简单说一下 资料
  • 我的2011年终总结(流水账篇)

    2011即将过去 xff0c 2012即将到来 2013应该还会如期而来吧 xff1f 2011回顾 xff1a 去日本出差很幸运的遇上了大地震 xff08 还好不在福岛 xff09 和老婆谈了7年了 xff08 认识十年了 xff09 儿
  • poll函数详解及原理

    poll函数实现和select极为相似 xff0c 但是它们的接口并不相同 xff1a int poll struct pollfd fdarray nfds t nfds int timeout int select int maxfdp
  • 深度学习中的优化算法之SGD

    之前在https blog csdn net fengbingchun article details 75351323 介绍过梯度下降 xff0c 常见的梯度下降有三种形式 xff1a BGD SGD MBGD xff0c 它们的不同之处
  • CMake中include_directories的使用

    CMake中include directories命令用于在构建 build 中添加包含目录 其格式如下 include directories AFTER BEFORE SYSTEM dir1 dir2 将给定的目录添加到编译器 comp
  • CMake中target_link_libraries的使用

    CMake中的target link libraries命令用于指定链接给定目标和 或其依赖项时要使用的库或标志 来自链接库目标的使用要求将被传播 propagated 目标依赖项的使用要求会影响其自身源代码的编译 其格式如下 xff1a
  • CMake中install的使用

    CMake中的install命令用于指定安装时要运行的规则 xff0c 其格式如下 xff1a install TARGETS targets EXPORT lt export name gt RUNTIME DEPENDENCIES ar
  • 相机的内参和外参介绍

    注 xff1a 以下相机内参与外参介绍除来自网络整理外全部来自于 视觉SLAM十四讲从理论到实践 第2版 中的第5讲 xff1a 相机与图像 xff0c 为了方便查看 xff0c 我将每节合并到了一幅图像中 相机与摄像机区别 xff1a 相
  • Linux下常用的C/C++开源Socket库

    1 Linux Socket Programming In C 43 43 http tldp org LDP LG issue74 tougher html 2 ACE http www cs wustl edu schmidt ACE
  • C++11中unique_ptr的使用

    在C 43 43 中 xff0c 动态内存的管理是通过一对运算符来完成的 xff1a new xff0c 在动态内存中为对象分配空间并返回一个指向该对象的指针 xff0c 可以选择对对象进行初始化 xff1b delete xff0c 接受
  • 2021年校招软件测试工程师经典面试题,月薪15K你需要掌握哪些知识点?

    软件测试工程师 xff0c 和开发工程师相比起来 xff0c 前期可能不会涉及太深奥的内容 xff0c 但是涉及的面还是比较广的 面试实习生或者一年左右的岗位 xff0c 问的也主要是一些基础性的问题比较多 涉及的知识主要有MySQL数据库
  • 矩阵特征分解介绍及雅克比(Jacobi)方法实现特征值和特征向量的求解(C++/OpenCV/Eigen)

    对角矩阵 diagonal matrix xff1a 只在主对角线上含有非零元素 xff0c 其它位置都是零 xff0c 对角线上的元素可以为0或其它值 形式上 xff0c 矩阵D是对角矩阵 xff0c 当且仅当对于所有的i j Di j
  • HTTP解析库http-parser简介及使用

    http parser是一个用C编写的HTTP消息解析器 xff0c 可以解析请求和响应 xff0c 被设计用于高性能HTTP应用程序 它不会进行任何系统调用及内存分配 xff0c 它不会缓冲数据 xff0c 它可以被随时中断 根据你的体系
  • k8s之multus cni

    通常情况下在k8s中 xff0c 一个pod只有一个接口 xff0c 用于集群网络中pod和pod通信 xff0c 而multus定义了一种crd Kubernetes Network Custom Resource Definition
  • 【机器学习】浅析机器学习各大算法的适用场景

    最近在参加一个分类算法竞赛 xff0c 也正好整理各个分类机器学习算法的简单介绍 xff0c 应用场景和优缺点 资源来自网上和自己个人理解 一 逻辑回归模型 1 理解逻辑回归模型 xff08 LR xff09 逻辑回归是一种分类算法 xff
  • 【机器学习】异常检测算法之(KNN)-K Nearest Neighbors

    sklearn库里的KNN并没有直接用于异常检测 xff0c 但是包含了距离计算的函数 xff0c 所以我们应用PyOD中KNN库进行异常检测 xff0c 里面基本上也是调用sklearn的函数进行计算 xff0c 并进行了一些加工 一 图