为了加快搜索速度,我们打算通过将源数据进行聚类以减少后续搜索的计算次数。
方案简介
-
设定初始值 d 作为高位空间角度阈值
聚类流程
-
对于所有词和对应词向量,执行以下
-
与现有所有簇的中心向量对比,若存在余弦值>cos(d)内,则将其放入该簇
-
否则,以该词和词向量建立新簇,簇的中心向量为该词向量值
关键词查询流程
-
将查询的词向量与所有簇的中心向量对比,筛选出余弦值>cos(2d)的簇
-
将筛选出的簇中的所有元素再与查询词向量做对比,返回所有余弦值>c(c为所需精度,c>cos(d))的词或最接近的前k个词
代码实现
考虑到聚类流程是单纯的预处理,不参与后续组间工作对接,故选用nodejs以加快代码执行速度。
本次代码实现考虑了sql执行错误日志,程序多次衔接运行,本地关键数据缓存,流式读取文件以减少内存压力等。
主文件index.js
const fs = require('fs');
const {
con, do: query } = require('./db');
const {
load, save } = require('./tool/cache');
const vectorLength = 200;
//基本误差角度
const loss = 1 / 180 * Math.PI;
//聚类流程余弦阈值
const threshold = Math.cos(loss);
//搜索流程余弦阈值
const thresholdQuery = Math.cos(loss * 2);
// 保存执行错误的sql语句,用于重试
const resqlPath = './resql.txt';
/**
* 本地缓存已有聚类和文件读取的位置
* @type {
{
* clusters:{
* center:string,
* id:number,
* abs:number
* }[],
* nextLine:number,
* nextId:number
* }}
*/
let cache = load(undefined, {
clusters: [],
nextLine: 1,
nextId: 1
});
//程序本次执行处理的关键词个数
const taskBatch = 100000;
let batchIndex = taskBatch;
//在人工中断程序时保存缓存到本地
process.on('SIGINT', e => {
save(cache);
process.exit(0);
})