WK-NNC


WK_NNC[1]

WK_NNC简介

WK_NNR模型(Distance-Weighted k-Nearest-Neighbor Rule)是Sahibsingh A. Dudani于1976年提出的对KNN(详见KNN | BaoWJ’s Blog)的一种改进方法。

该方法的主要思路是对KNN中的距离进行加权

基础KNN是:直接取距离待预测数据点 α \alpha α 最近的K个点,并预测该数据类别为这K个数据中占比最大的数据的类别。KNN可以看成WK__NNC的一个特例,这相当于对K个数据点中,设置权重都为1

WK_NNR的思路是根据这K个点距离 α \alpha α 的距离不同赋予不同的权重,最后依据权重之和最大的类别来预测。

对于待预测数据点 α \alpha αK个“最近邻” α i , 1 ≤ i ≤ K \alpha_i,1\le i \le K αi,1iK,其中 α i \alpha_i αi 距离 α \alpha α 点的距离为 d i d_i di,且 d 1 ≤ d 2 ≤ ⋯ ≤ d K d_1\le d_2 \le \cdots \le d_K d1d2dK。则,其每个点的权重定义如下:

w i = { d k − d i d k − d 1 d k ≠ d 1 1 d k = d 1 w_i=\left\{\begin{aligned} \frac{d_k-d_i}{d_k-d_1}\quad & d_k \ne d_1\\ 1\quad &d_k=d_1\end{aligned}\right. wi=dkd1dkdi1dk=d1dk=d1

最终 α \alpha α预测类别权重加和值最大的数据的类别。

WK_NNC代码

因为sklearn没有提供WK_NNR模型的库函数,所以这里我基于sklearnKNeighborsClassifier类构造WK_NNR模型。

KNeighborsClassifier提供了一个weights参数接口,用户可以通过自定义函数来自定义距离权重,所以我写了一个基于WK_NNR权重的自定义函数kw_nnc,代码如下:

def kw_nnc(distances):
    return ((distances[:, -1][:, np.newaxis] - distances) + 1e-6) / ((distances[:, -1] - distances[:, 0])[:, np.newaxis] + 1e-6) # 1e-6为了防止除0发生

wk_nnc_model = KNeighborsClassifier(weights=kw_nnc)

WK_NNC实验

实验数据

  • 数据来源:http://www.cad.zju.edu.cn/home/dengcai/Data/TDT2/TDT2.mat

  • 数据简介:该数据是新闻文本数据,数据的作者从新闻文本中提取出的词频数据。。

  • 数据维度:36771;

  • 类别数:30;

  • 数据条数:9394;

实验代码

导入依赖包
import scipy.io as scio
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection  import cross_val_score
from sklearn.metrics import confusion_matrix, accuracy_score
from sklearn.model_selection import train_test_split

加载数据
dataFile = './TDT2.mat'
data = scio.loadmat(dataFile)
Y = data['gnd'].ravel()
X = data['fea'].A

print('X shape:', X.shape)
print('Y shape:', Y.shape)
TF-IDF
from sklearn.feature_extraction.text import TfidfTransformer

tfidf = TfidfTransformer()
X = tfidf.fit_transform(X).A
寻找最优K值
import matplotlib.pyplot as plt

def get_best_k_acc(X_train, Y_train, X_test, Y_test):
    acc_list = []
    k_list = []
    model = KNeighborsClassifier(weights=kw_nnc)
    for k in range(5, 16, 1):
        model.n_neighbors = k
        model.fit(X_train, Y_train)
        Y_pred = model.predict(X_test)
        acc = accuracy_score(Y_test, Y_pred)
        k_list.append(k)
        acc_list.append(acc)

    plt.plot(k_list, acc_list)
    plt.ylabel('Accuracy')
    plt.title('Accuracy with K')
    plt.xlabel('K')
    plt.show()
    # 计算最优K
    best_acc = np.max(acc_list)
    best_k = k_list[np.argmax(acc_list)]
    print('最优k值为: {}, value为: {}'.format(best_k, best_acc))
    return (best_k, best_acc)
寻找最优降维维度
from sklearn.decomposition import PCA
acc_list = []
k_list = []
n_list = []
pca_model = PCA()
for n in range(1, 11, 1):
    # 降维
    n = n * 10
    print('-' * 15 + '维度为' + str(n) + '-' * 15)
    pca_model.n_components = n
    print('-' * 15 + '开始降维' + '-' * 15)
    pca_X = pca_model.fit_transform(X)
    print('降维后形状:', pca_X.shape)
    # 划分数据集
    print('-' * 15 + '开始切分数据' + '-' * 15)
    X_train, X_test, Y_train, Y_test = train_test_split(pca_X, Y, test_size=0.25, random_state=21, shuffle=True)
    print('训练数据:', X_train.shape)
    print('训练label:', Y_train.shape)
    print('测试数据:', X_test.shape)
    print('测试label', Y_test.shape)
    k, acc = get_best_k_acc(X_train, Y_train, X_test, Y_test)
    k_list.append(k)
    acc_list.append(acc)
    n_list.append(n)
绘图
import matplotlib.pyplot as plt

plt.title('K-NNMC')
plt.subplot(2, 1, 1)
plt.xlim(0, 105)
plt.ylim(0.96, 0.98)
plt.scatter(n_list, acc_list)
plt.plot(n_list, acc_list)
for x, y in zip(n_list, acc_list):
    plt.text(x, y + 0.001, "%.3f"%y)
plt.ylabel('Accuracy')
plt.grid()
plt.title('Best_Accuracy with Dim')
plt.xlabel('Dim')

plt.subplot(2, 1, 2)
plt.scatter(n_list, k_list)
plt.plot(n_list, k_list)
for x, y in zip(n_list, k_list):
    plt.text(x, y + 0.1, "%d"%y)
plt.ylabel('K')
plt.grid()
plt.title('Best_K with Dim')
plt.xlabel('Dim')
plt.show()
实验结果

请添加图片描述

结果发现,WK_NNC模型取的最优值的地方K值都比较大(在10附近),说明WK_NNC模型泛化性比较好。

链接

引用

[1] S. A. Dudani, "The Distance-Weighted k-Nearest-Neighbor Rule," in IEEE Transactions on Systems, Man, and Cybernetics, vol. SMC-6, no. 4, pp. 325-327, April 1976, doi: 10.1109/TSMC.1976.5408784.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值