找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1563

积分

0

好友

231

主题
发表于 4 天前 | 查看: 15| 回复: 0

最近的文章创作中,AI工具扮演了重要角色,这引来了关于“AI味”的讨论。但工具本身并无高下之分,关键在于使用者。一个核心观点是:能够驾驭AI并将其效能最大化的人,必然也是相关领域的深度实践者。这并非取代,而是效率与专业洞察的融合。

一个典型的场景是:在为数据库实践课程准备教学数据时,需要生成一批符合现实世界规律的向量数据。单纯随机生成的数据缺乏“群体聚集性”和“语义相似度”等现实意义。这时,借助AI工具,通过清晰的指令(Prompt)和后续微调,可以快速构建出符合业务逻辑的测试数据。

Prompt示例

我要在PostgreSQL中创建一个存储16维向量的表,需要生成测试数据,写一个PostgreSQL函数,生成1000个(可变量输入)离散随机的向量,然后再以这1000个向量为中心,生成2000个(可变量输入)离散向量,离中心点距离越近出现概率越高,越远概率越低。

AI生成的解决方案

在 PostgreSQL 中处理向量数据,通常推荐安装 pgvector 插件。为了满足“中心点聚合”和“概率分布”的需求,结合高斯分布(正态分布)来编写函数是科学的做法。

1. 环境准备

首先,确保数据库已安装 pgvector 插件。

CREATE EXTENSION IF NOT EXISTS vector;

-- 创建存储 16 维向量的表
CREATE TABLE IF NOT EXISTS vector_test (
    id SERIAL PRIMARY KEY,
    embedding vector(16),
    is_center BOOLEAN -- 标记是否为中心点
);
2. 核心函数逻辑

利用 PostgreSQL 的内置函数 random(),并采用 Box-Muller 变换 生成符合正态分布的随机数,以实现“离中心点越近概率越高”的效果。

函数:generate_vector_data

CREATE OR REPLACE FUNCTION generate_vector_data(
    center_count INT,     -- 中心点数量 (例如 1000)
    points_per_center INT -- 每个中心点周围生成的点数 (例如 2, 总计 2000)
) RETURNS TEXT AS $$
DECLARE
    center_id INT;
    center_vec FLOAT8[];
    new_vec FLOAT8[];
    std_dev FLOAT8 := 0.1; -- 标准差,值越小点越密集
    i INT; j INT; k INT;
    u1 FLOAT8; u2 FLOAT8; z0 FLOAT8;
BEGIN
    -- 1. 生成原始的离散随机中心点
    FOR i IN 1..center_count LOOP
        center_vec := ARRAY(SELECT random() FROM generate_series(1, 16));
        INSERT INTO vector_test (embedding, is_center)
        VALUES (center_vec::vector, TRUE)
        RETURNING id INTO center_id;

        -- 2. 以该中心点为基准,生成服从正态分布的周边点
        FOR j IN 1..points_per_center LOOP
            new_vec := '{}';
            -- 对 16 个维度分别进行高斯扰动
            FOR k IN 1..16 LOOP
                -- Box-Muller 变换生成标准正态分布随机数
                u1 := random();
                u2 := random();
                z0 := sqrt(-2.0 * ln(u1)) * cos(2.0 * pi() * u2);
                -- 将扰动叠加到中心点的对应维度上
                new_vec := array_append(new_vec, center_vec[k] + (z0 * std_dev));
            END LOOP;

            INSERT INTO vector_test (embedding, is_center)
            VALUES (new_vec::vector, FALSE);
        END LOOP;
    END LOOP;

    RETURN 'Successfully generated ' || (center_count + center_count * points_per_center) || ' vectors.';
END;
$$ LANGUAGE plpgsql;
3. 使用与验证

执行函数生成数据:

-- 生成 1000 个中心点,每个点生成 2 个周边点(共 3000 条数据)
SELECT generate_vector_data(1000, 2);

验证数据分布:

-- 查看中心点与周边点的数量
SELECT is_center, count(*) FROM vector_test GROUP BY is_center;

-- 查询距离某个中心点最近的5个点
SELECT * FROM vector_test
ORDER BY embedding <=> (SELECT embedding FROM vector_test WHERE is_center = true LIMIT 1)
LIMIT 5;
关键点解析
  • 概率分布模型:使用正态分布,数值出现在均值(中心点)附近的概率最大,完美符合“近处多、远处少”的需求。
  • Box-Muller变换:通过均匀分布随机数生成正态分布随机数的标准算法。
  • 控制离散度:通过 std_dev(标准差)参数控制点的“紧凑程度”。值越小,点越贴近中心点;值越大,点越分散。

标准差概念详解

为了更直观地理解,可以用“射击打靶”来比喻:

  • 平均值:靶心。
  • 标准差:一把“尺子”,衡量子弹偏离靶心的平均距离。数据集波动越大,这把“尺子”越长。
  • 68%/95%/99.7%:子弹落在“靶心±1/2/3倍尺子长度”范围内的概率(覆盖率)。

在前面的向量例子中,假设某个维度的平均值是0.5,标准差 std_dev 设为0.1:

  • 68%的概率,生成的数值会落在 0.4 到 0.6 之间(0.5 ± 0.1)。
  • 95%的概率,数值会落在 0.3 到 0.7 之间(0.5 ± 0.2)。
  • 99.7%的概率,数值会落在 0.2 到 0.8 之间(0.5 ± 0.3)。

人工迭代与性能压测

完全依赖AI会失去思考过程,因此需要在此基础上进行手动优化和扩展,例如使维度和标准差可调,并利用 pgbench 进行并行压测,这是数据库与中间件性能测试的常见手段。

  1. 增强函数:修改函数,支持自定义维度 (dims) 和标准差 (i_std_dev)。

    CREATE OR REPLACE FUNCTION generate_vector_data(
        center_count INT,
        points_per_center INT,
        dims int,  -- 维度
        i_std_dev float8 default 0.1 -- 标准差
    ) RETURNS TEXT AS $$
    -- ... 函数体逻辑类似,将循环上限改为 dims,使用 i_std_dev ...
    $$ LANGUAGE plpgsql;
  2. 并行插入:使用 pgbench 工具并行生成大量数据。

    • 准备脚本 1.sql
      SELECT generate_vector_data(:center_count, :points_per_center, :dims, :i_std_dev);
    • 执行命令(10个并发,共生成30万条记录):
      pgbench -M prepared -n -r -f 1.sql -D center_count=300 -D points_per_center=100 -D dims=8 -D i_std_dev=0.1 -c 10 -j 10 -t 1
  3. 索引与查询:为向量列创建 HNSW 索引以加速相似性搜索,并测试查询性能。

    -- 并行创建索引优化设置
    set maintenance_work_mem ='1GB';
    set max_parallel_workers=4;
    alter table vector_test set (parallel_workers =4);
    create index on vector_test using hnsw (embedding vector_l2_ops) with (m=16, ef_construction=64);
    
    -- 相似向量查询示例
    SELECT * FROM vector_test
    ORDER BY embedding <-> (SELECT embedding FROM vector_test WHERE id = 1)
    LIMIT 10;

应对更复杂的需求

业务需求往往会变得更复杂。例如,要求生成的数据严格落在 [0,1) 区间内,并且每个中心点自身的“聚集强度”(类内标准差)也服从一个正态分布。这再次体现了人工智能工具在辅助解决复杂逻辑问题时的价值。只需将更精确的需求描述为 Prompt,AI 便能生成符合要求、逻辑严谨的代码。

升级后的 Prompt 与 AI 生成的函数核心逻辑

需求要点:向量值需截断至 [0,1);每个中心点的类内标准差服从 N(std_dev_mean, std_dev_sigma) 分布,且必须为正。

CREATE OR REPLACE FUNCTION generate_vector_data(
    center_count INT,
    points_per_center INT,
    dims INT,
    std_dev_mean FLOAT8 DEFAULT 0.1, -- 类内标准差的均值
    std_dev_sigma FLOAT8 DEFAULT 0.01 -- 类内标准差的分布标准差
) RETURNS TEXT AS $$
DECLARE
    local_std_dev FLOAT8; -- 每个中心点自己的类内标准差
    perturbed_val FLOAT8;
    -- ... 其他变量
BEGIN
    FOR i IN 1..center_count LOOP
        -- 生成中心点向量...
        -- 为当前中心点生成其“类内标准差”:N(std_dev_mean, std_dev_sigma),必须 > 0
        LOOP
            u1 := random(); u2 := random();
            IF u1 = 0 THEN u1 := 1e-10; END IF;
            z_std := sqrt(-2.0 * ln(u1)) * cos(2.0 * pi() * u2);
            local_std_dev := std_dev_mean + z_std * std_dev_sigma;
            EXIT WHEN local_std_dev > 0;
        END LOOP;

        -- 生成聚集点,并对每个维度的扰动值进行截断
        FOR j IN 1..points_per_center LOOP
            FOR k IN 1..dims LOOP
                -- ... 生成正态扰动 z0 ...
                perturbed_val := center_vec[k] + z0 * local_std_dev;
                -- 截断到 [0, 1),使用 1 - 1e-9 避免等于1
                perturbed_val := GREATEST(0.0, LEAST(1.0 - 1e-9, perturbed_val));
                new_vec := array_append(new_vec, perturbed_val);
            END LOOP;
            -- 插入数据...
        END LOOP;
    END LOOP;
    RETURN 'Successfully generated ...';
END;
$$ LANGUAGE plpgsql;

总结

整个过程清晰地展示了从提出需求、利用AI生成基础方案、到人工迭代优化以满足具体业务细节和性能要求的完整工作流。这不仅是简单的工具使用,更是大数据处理场景下,专业知识与高效工具的结合。真正高效的使用者,懂得如何向AI清晰表达问题,并具备判断和优化其输出结果的能力。




上一篇:Linux运维必备:终端文件管理器ranger,告别命令行操作繁琐
下一篇:Python函数与代码复用核心知识自测:高阶函数、递归与Lambda表达式实战练习题
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-24 18:58 , Processed in 0.308434 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表