K近临算法(KNN)

什么是K近临算法

K近临算法是基于实例的学习算法,俗称KNN

什么是基于实例

基于实例的学习算法只是简单的把样例存储起来。把这些实例中泛化的工作推迟到必须分类的时候。每当学习器遇到一个新的实例时,它将实时分析这个实例与以前存储的实例的关系,并据此把一个目标函数值赋到新的实例。

K近临原理介绍

k近临的思路是找K个与目标最相似的样本,认为目标就属于K个样本中最多频次的类别。
分类
对未知类别属性数据中每个点的分类过程:
1. 计算未知点到训练数据点的距离
2. 对这些训练数据点递增排序
3. 选K个最近的点
4. 确定K个点所在类别的频率
5. 返回K个点出现频率最高的类别作为未知点类别
其中的距离计算一般为欧式距离,或者城市距离(具体依实际情况定)

K近临
如上图所示,如果K=3就是实线所圈的点,那么未知点就会被分成红色三角形的类别上。如果K=5那就是虚线所圈的点,未知点就会被分成蓝色四方块的类别上。

回归
1. 计算未知点到训练数据点的距离
2. 对这些训练数据点递增排序
3. 选K个最近的点
4. 将K个最近点的属性均值赋值给目标点(得到目标点的属性)
当然取均值只是一种方法,还可以按样本点与目标点的距离进行加权等方法进行属性值赋值。

K近临的优缺点

优点

  1. 抗噪声能力强:K近临只选最近的K个点,因些一些离群点完全不影响算法的处理效果。
  2. 模型简单,分类效果相当不错。kaggle的手势识别,朴素的算法就能达到96.5%的准确率
  3. 由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方 法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。

缺点

  1. 维度灾难:k-近邻算法在计算距离的时候,考虑实例的所有属性。可能分类仅由某几个属性决定,这中情况下属性的相似性度量会误导k-近邻算法的分类。

    解决办法:(1)属性加权;(2)剔除不相关的属性。

  2. 效率超慢:对于每个目标点都需要计算它到所有样本点的距离
    当样本维度为 N 特征维度为 D ,那么复杂度就是呈 O(ND

### 虚假邻点法 Python 实现 虚假邻点法是一种用于检测嵌入维度是否合适的方法,在时间序列分析等领域有广泛应用。该方法通过判断重构相空间中的两点在增加嵌入维度后是否仍然接来决定合适的嵌入维度。 #### 方法原理 对于给定的时间序列 \( \{X_t\} \),假设已经选择了初始的延迟时间和嵌入维度 m 来构建向量: \[ V_i^{(m)} = [X(i), X(i+\tau), ..., X(i+(m-1)\tau)] \] 当嵌入维度增加到 \( m+1 \) 时,对应的向量变为: \[ V_i^{(m+1)} = [X(i), X(i+\tau), ..., X(i+(m-1)\tau), X(i+m\tau)] \] 如果两个相邻点之间的欧氏距离显著增大,则认为这两个点是虚假邻点。 #### Python 实现 下面是一个简单的 Python 函数实现,用来计算指定数据集上的虚假邻比例[^1]: ```python import numpy as np def false_nearest_neighbors(time_series, tau, min_dim, max_dim, threshold=0.1): """ 计算不同嵌入维度下的虚假最邻居的比例 参数: time_series (list/array): 输入的一维时间序列. tau (int): 延迟参数. min_dim (int): 最小嵌入维度. max_dim (int): 最大嵌入维度. threshold (float): 判断是否为虚假邻的标准,默认值为0.1 返回: fns_ratio (dict): 不同嵌入维度下虚假最邻居的比例字典 {dim: ratio}. """ def create_embedding(data, dim, delay): n = len(data)-(dim-1)*delay embedded_data = np.zeros((n,dim)) for i in range(dim): embedded_data[:,i] = data[i*delay:i*delay+n] return embedded_data fns_ratio = {} for m in range(min_dim, max_dim + 1): emb_m = create_embedding(time_series, m, tau) dists = [] nearest_indices = [] # 寻找每个点最邻距离及其索引 for idx, point in enumerate(emb_m[:-1]): distances = np.linalg.norm(point - emb_m[idx+1:], axis=1) closest_idx = np.argmin(distances)+idx+1 nearest_indices.append(closest_idx) dists.append(distances.min()) count_fnn = 0 if m < max_dim: emb_next = create_embedding(time_series, m+1, tau) for j, index in enumerate(nearest_indices): orig_dist = dists[j] new_point_1 = emb_next[j] new_point_2 = emb_next[index] next_dist = np.linalg.norm(new_point_1-new_point_2) R = next_dist/orig_dist if R >= threshold and abs(new_point_1[-1]-new_point_2[-1]) > \ 10 * np.std(time_series[(index+j):(index+j+len(new_point_1)-1)]): count_fnn += 1 fns_ratio[m] = float(count_fnn)/len(dists) return fns_ratio ``` 此代码定义了一个 `false_nearest_neighbors` 函数,它接收时间序列以及一些必要的参数作为输入,并返回一个包含各个嵌入维度对应虚假邻比率的结果字典。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值