0x00 概述
K近邻算法是机器学习中非常重要的分类算法。可利用K近邻基于不同的特征提取方式来检测异常操作,比如使用K近邻检测Rootkit,使用K近邻检测webshell等。
0x01 原理
距离接近的事物具有相同属性的可能性要大于距离相对较远的。 这是K邻近的核心思想。
- K邻近 K-Nearest Neighbor,KNN 算法,KNN指K个最近的邻居,可认为每个样本都能用与它最相近的K个邻居来代表。
一个样本在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并且具有这个类别里样本的特性。
类域交叉或重叠较多的待分样本集
- Brute Force
- K-D Tree
- Ball Tree
0x02 代码详解
0x02.1 Ball Tree 演示
设置初始数据集 这里自己定义了一个小的数据集
>>> X = np.array([[-1,-1],[-2,-1],[-3,-2],[1,1],[2,1],[3,2]])
调用Scikit-Learn的KNN算法,设置邻居数为2,进行训练
>>> from sklearn.neighbors import NearestNeighbors # 从调用sklearn库中的neighbors模块调用KNN
>>> import numpy as np # 调用numpy库
>>> X = np.array([[-1,-1],[-2,-1],[-3,-2],[1,1],[2,1],[3,2]]) # 设置训练的数据集
>>> nbrs=NearestNeighbors(n_neighbors=2,algorithm='ball_tree').fit(X) # 设置邻居数,设置训练的算法。
>>> distances,indices=nbrs.kneighbors(X) # 开始训练,返回结果
>>> print(indices)
>>> print(distances)
有些不理解,查找官方文档
URL-》https://scikit-learn.org/dev/modules/generated/sklearn.neighbors.NearestNeighbors.html?highlight=#sklearn.neighbors.NearestNeighbors
注意是先返回了距离,然后返回了下标,一开始有点懵,为什么自己在和自己比??而不是哪数据集和某个点比
后面仔细看看就明白了
- 运行结果
直接看不好看懂,但是实际上根据邻居数和官方文档可以这么理解。
邻居数就是一个点周围离它最近的点。
针对一个点 [-1,-1] 与它对应的下标 [0 1] 表示 第1个样本 和第2个样本 距离 对应 [0,1] 表示第一个点与第一个点之间的距离,第一个点与第二个点之间的距离。
其余点都是这种规律。
- 加入一行代码,直接抽象表示每个点的2个邻居
>>> nbrs.kneighbors_graph(X).toarray()
可以看到用1去模拟实现了不同点的邻居。
0x02.2 KNN下的监督学习
from sklearn.neighbors import KNeighborsClassifier
x=[[0],[1],[2],[3]]
y=[0,0,1,1]
neigh=KNeighborsClassifier(n_neighbors=3)
neigh.fit(x,y)
print(neigh.predict([[1.1]]))
print(neigh.predict_proba([[0.9]]))
代码审计 - 从sklear的分类算法里选择KNeighborsClassifier
然后设置邻居数 通过.fit函数 对数据集进行拟合
neigh.predict 去预测 [1.1] 会被分成什么类
正常运行结果
修改了数据进行标签预测后
可以看出总共只有2个标签 一个是0 一个是1 然后根据你输入的数据进行分类,通过neigh.predict_proba 输出被分在不同标签中的概率。