当前位置: 代码网 > 科技>人工智能>数据分析 > 使用聚类提升knn的预测速度

使用聚类提升knn的预测速度

2024年08月03日 数据分析 我要评论
knn算法适用于较小的数据集,在处理大数据集时由于KNN算法需要计算测试样本与所有训练样本之间的距离。所以计算复杂度高,预测速度慢。为了缓解这个问题, 可以先把 10,000 条训练数据聚为 50 个簇, 每簇约 200 个样本 (聚类问题), 并获得这些簇中心点. 进行比对的时候, 先确定与哪个簇中心最近, 然后再在这个簇中心找邻居. 这样就可以把 10,000 次对比降为约 50 + 200 次.

knn算法适用于较小的数据集,在处理大数据集时由于knn算法需要计算测试样本与所有训练样本之间的距离。所以计算复杂度高,预测速度慢。
为了缓解这个问题, 可以先把 10,000 条训练数据聚为 50 个簇, 每簇约 200 个样本 (聚类问题), 并获得这些簇中心点. 进行比对的时候, 先确定与哪个簇中心最近, 然后再在这个簇中心找邻居. 这样就可以把 10,000 次对比降为约 50 + 200 次.

使用鸢尾花数据集做示例,鸢尾花有150多个样本,先使用kmeans进行聚类,把训练集聚为三个簇,然后再为每一簇构建一个knn分类器,把150 次对比降为约 3+50次.

使用kmeans和knn进行鸢尾花分类

首先,导入所需的库:

import numpy as np
import operator

from sklearn.datasets import load_iris
from sklearn.preprocessing import standardscaler
from sklearn.model_selection import train_test_split
from sklearn.cluster import kmeans
from sklearn.metrics import accuracy_score

接下来,定义一个函数knnclassify来执行knn分类。这个函数计算测试数据与训练数据之间的距离,然后根据距离排序,并选择距离最小的k个样本点。然后,它确定k个样本点所在类别的出现频率,并返回最高频率的类别作为预测分类。

def knnclassify(inputx, data, labels, k):
    # 1. 计算测试数据与各训练数据之间的距离。
    datasize = data.shape[0]
    x = np.tile(inputx, (datasize, 1)) - data
    xpositive = x ** 2
    xdistances = xpositive.sum(axis=1)
    distances = np.sqrt(xdistances)

    # 2. 按照距离的大小进行排序。
    sortdisindex = distances.argsort()

    # 3. 选择其中距离最小的k个样本点。4. 确定k个样本点所在类别的出现频率。
    classcount = {}  # 创建字典:label为键,频数为值
    for i in range(k):
        getlabel = labels[sortdisindex[i]]
        classcount[getlabel] = classcount.get(getlabel, 0) + 1

    # 5. 返回k个样本点中出现频率最高的类别作为最终的预测分类。
    sortclass = sorted(classcount.items(), key=operator.itemgetter(1), reverse=true)
    return sortclass[0][0]

加载鸢尾花数据集,并对特征进行归一化:

data = load_iris()
x = data.data[:, :3]  # 选择前三个特征
y = data.target

scaler = standardscaler()
x_scaled = scaler.fit_transform(x)

将数据集划分为训练集和测试集:

x_train, x_test, y_train, y_test = train_test_split(x_scaled, y, test_size=0.2, random_state=42)

使用kmeans聚类算法将训练集进行聚类,并获取聚类中心(选取三个聚类中心):

kmeans = kmeans(n_clusters=3)
kmeans.fit(x_train)

cluster_centers = kmeans.cluster_centers_

为每个聚类中心创建一个自定义的knn分类器,并将其存储在classifiers列表中:

classifiers = []
for cluster_idx in range(kmeans.n_clusters):
    cluster_samples = x_train[kmeans.predict(x_train) == cluster_idx]
    cluster_labels = y_train[kmeans.predict(x_train) == cluster_idx]

    classifiers.append((cluster_samples, cluster_labels))

使用分类器对测试集进行预测:

y_pred = []
for sample in x_test:
    distances = [np.linalg.norm(sample - center) for center in cluster_centers]
    closest_cluster_idx = np.argmin(distances)
    cluster_samples, cluster_labels = classifiers[closest_cluster_idx]
    y_pred.append(knnclassify(sample, cluster_samples, cluster_labels, k=3))

最后,计算分类的准确率并进行输出:

accuracy = accuracy_score(y_test, y_pred)
print(f"accuracy: {accuracy}")

虽然这种方式速度更快,但是会降低一定的精度。

运行结果

请添加图片描述
下面是不进行聚类直接使用knn进行分类的结果请添加图片描述

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com