百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

向量搜索之 k-means 算法(向量搜索框架)

ztj100 2025-06-15 20:40 4 浏览 0 评论

一直好奇向量数据库的索引是如何实现的,我们可以推断向量搜索的简单实现:把数据存入向量数据库时,会计算每个分段文档的向量(文档向量),然后把分段文档和文档向量同时存入向量数据库。从向量数据库中搜索文档时,会把待搜索问题转为向量(问题向量),然后计算问题向量与所有文档向量的距离,数据库会返回距离最短的一个或多个文档。

上面计算方式,返回的文档与问题最相关,但文档多时,耗费的计算资源同样多,有没有更好的方法?最容易想到的方法是把存入数据库中的文档向量先聚类为 K 个簇,从向量数据库中搜索文档时,先找到最相近的簇,再和簇内的每个文档向量比较找到与问题向量距离最短的一个或多个文档。这样需要的计算量就会少很多。

K-means算法简介

怎么把文档向量聚类为 K 个簇?可以使用K-means 算法。

  1. 初始化:随机选择K个数据点作为初始簇中心 。
  2. 分配样本:计算每个数据点到各簇中心的距离(通常用欧氏距离),将其分配到最近的簇 。
  3. 更新簇中心:重新计算每个簇的均值作为新中心 。
  4. 迭代:重复分配和更新步骤,直到中心不再变化或达到最大迭代次数

K-means 算法 python 实现

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs

# 生成模拟数据,300个数据点,4个簇,每个簇的标准差为0.6,随机种子为0
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)

# K-means算法实现
def k_means(X, K, max_iters=100):
    np.random.seed(42)
    # 1. 随机初始化:从数据集中随机选择K个点作为初始簇中心
    # np.random.choice 是随机抽样函数
    # X.shape[0] 表示模拟数据个数;
    # replace=False 表示无放回抽样,即每个数据只能被选中一次,不允许重复
    centroids = X[np.random.choice(X.shape[0], K, replace=False)]
    original_centroids = centroids.copy()

    for iteration in range(max_iters):
        # 2. 分配数据点:计算每个数据点到各个簇中心的距离
        # X[:, np.newaxis] 表示为 X 添加一个新维度,使其形状变为 (n_samples, 1, n_features)。
        # 目的是通过广播机制与 centroids 的维度 (K, n_features) 对齐,便于后续逐元素计算
        # X[:, np.newaxis] - centroids 广播机制会将 X 扩展为 (n_samples, K, n_features),
        # centroids 扩展为 (n_samples, K, n_features)(实际仅逻辑扩展,不占用额外内存)
        distances = np.linalg.norm(X[:, np.newaxis] - centroids, axis=2)
        # 3. 将每个数据点分配到最近的簇
        labels = np.argmin(distances, axis=1)
 
        # 4. 更新簇中心:重新计算每个簇的中心点,即簇内所有点的均值
        # labels == k 生成布尔掩码(Boolean Mask),筛选出 labels 数组中标签等于 k 的所有样本索引
        # X[labels == k] 根据布尔掩码从数据矩阵 X 中提取属于第 k 个簇的所有样本
        # .mean(axis=0) 沿列方向(axis=0)计算均值,得到第 k 个簇的中心坐标
        new_centroids = np.array([X[labels == k].mean(axis=0) for k in range(K)])
      
        # 5. 迭代优化:检查簇中心是否变化
        if np.all(centroids == new_centroids):
            print(f"算法在第{iteration + 1}次迭代后收敛")
            break
        centroids = new_centroids

    return original_centroids, centroids, labels


# 使用K-means算法进行聚类
K = 4  # 指定簇的数量
original_centroids, centroids, labels = k_means(X, K)
# 结果可视化
plt.figure(figsize=(8, 6))
# 每个簇的数据使用不同颜色展示
plt.scatter(X[:, 0], X[:, 1], c=labels, s=50, cmap='viridis', edgecolor='k')
# 最终得到的簇心用红色展示
plt.scatter(centroids[:, 0], centroids[:, 1], c='red', s=200, alpha=0.5, marker='X')
# 最初得到的簇心用蓝色展示
plt.scatter(origcentroids[:, 0], origcentroids[:, 1], c='blue', s=200, alpha=0.5, marker='X')
plt.title("K-means Clustering")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
# 保存到本地图片
plt.savefig("k_means_clustering.png")

上面实现中 distances = np.linalg.norm(X[:, np.newaxis] - centroids, axis=2) 等价于下面代码,计算每个数据点到各个簇中心的距离。

distances = np.zeros((X.shape[0], centroids.shape[0]))
for i in range(X.shape[0]):
    for j in range(centroids.shape[0]):
        distances[i, j] = np.sqrt(np.sum((X[i] - centroids[j])**2))

展示最终得到的簇中心与各个簇如下图所示

同时展示 K-means 算法最初随机选择的簇中心,使用蓝色叉展示如下,与最终的簇中心位置相隔较远,可见算法帮我们动态调整了簇中心。



向量数据库进行实际的向量搜索时,并不是简单通过 K-meams 算法创建索引,本文是从一个算法小白角度推导向量搜索如何实现,接下来会逐步介绍实际使用的向量搜索算法。

相关推荐

再说圆的面积-蒙特卡洛(蒙特卡洛方法求圆周率的matlab程序)

在微积分-圆的面积和周长(1)介绍微积分方法求解圆的面积,本文使用蒙特卡洛方法求解圆面积。...

python编程:如何使用python代码绘制出哪些常见的机器学习图像?

专栏推荐...

python创建分类器小结(pytorch分类数据集创建)

简介:分类是指利用数据的特性将其分成若干类型的过程。监督学习分类器就是用带标记的训练数据建立一个模型,然后对未知数据进行分类。...

matplotlib——绘制散点图(matplotlib散点图颜色和图例)

绘制散点图不同条件(维度)之间的内在关联关系观察数据的离散聚合程度...

python实现实时绘制数据(python如何绘制)

方法一importmatplotlib.pyplotaspltimportnumpyasnpimporttimefrommathimport*plt.ion()#...

简单学Python——matplotlib库3——绘制散点图

前面我们学习了用matplotlib绘制折线图,今天我们学习绘制散点图。其实简单的散点图与折线图的语法基本相同,只是作图函数由plot()变成了scatter()。下面就绘制一个散点图:import...

数据分析-相关性分析可视化(相关性分析数据处理)

前面介绍了相关性分析的原理、流程和常用的皮尔逊相关系数和斯皮尔曼相关系数,具体可以参考...

免费Python机器学习课程一:线性回归算法

学习线性回归的概念并从头开始在python中开发完整的线性回归算法最基本的机器学习算法必须是具有单个变量的线性回归算法。如今,可用的高级机器学习算法,库和技术如此之多,以至于线性回归似乎并不重要。但是...

用Python进行机器学习(2)之逻辑回归

前面介绍了线性回归,本次介绍的是逻辑回归。逻辑回归虽然名字里面带有“回归”两个字,但是它是一种分类算法,通常用于解决二分类问题,比如某个邮件是否是广告邮件,比如某个评价是否为正向的评价。逻辑回归也可以...

【Python机器学习系列】拟合和回归傻傻分不清?一文带你彻底搞懂

一、拟合和回归的区别拟合...

推荐2个十分好用的pandas数据探索分析神器

作者:俊欣来源:关于数据分析与可视化...

向量数据库:解锁大模型记忆的关键!选型指南+实战案例全解析

本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在...

用Python进行机器学习(11)-主成分分析PCA

我们在机器学习中有时候需要处理很多个参数,但是这些参数有时候彼此之间是有着各种关系的,这个时候我们就会想:是否可以找到一种方式来降低参数的个数呢?这就是今天我们要介绍的主成分分析,英文是Princip...

神经网络基础深度解析:从感知机到反向传播

本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在...

Python实现基于机器学习的RFM模型

CDA数据分析师出品作者:CDALevelⅠ持证人岗位:数据分析师行业:大数据...

取消回复欢迎 发表评论: