简单背景
智能营销,精准触达,相似用户挖掘。假设营销业务方需要基于一定数量(1万)的种子用户,从58备选用户集(1000万)中,扩展出一定数量(10万)的最相似用户人群,进行营销触达,用户可用的特征为256维。这里假设余弦相似度越高,营销响应效果越好,最终筛选出来的目标用户为备选用户集合与种子用户计算相似度后,取去重后相似度最高的10万用户(求相似度,全排序,取Top10万)。
程序输入
程序输入为种子用户ID数据集合,每一行包括用户ID和256维用户特征,用户特征数据类型为浮点型数据(存在部分数据用科学计数法表示的情况,比如1.4283673760891302E-4),所有数据分隔符为逗号,ID处于第1个位置,其它256维特征按照顺序处于2-257个位置。其中1-128维为连续性特征,数据都大于等于0小于等于1,余下129-256维为分类型特征经过one-hot处理过后的稀疏数据,数据都为0或者1。如下格式:
ID0001,0.1,0,0.56,…,0,1
程序输出
程序输出为确定数量ID集合,每个ID占一行,代表扩展的最相似的用户人群(不需要考虑ID的次序),要求输出的ID满足评分标准才会被判为输出正确
实现优化点
文件读取优化
采用RandomAccessFileChannel方式提升大文件读取时间消耗,以及将io读取和任务处理并发执行,加快执行速度。
130M File
commonUtil按行读取花费:782毫秒
BufferedReader按行读取花费:489毫秒
BufferedInputStream按行读取花费:508毫秒
RandomAccessFileMap按块读取花费:573毫秒
RandomAccessFileChannel按块花费:340毫秒
1.2G File
commonUtil按行读取花费:39037毫秒
BufferedReader按行读取花费:38873毫秒
BufferedInputStream按行读取花费:39464毫秒
RandomAccessFileMap按块读取花费:1615毫秒
RandomAccessFileChannel按块花费:1598毫秒
top K算法优化
由传统二分或者小顶堆、以及优先级队列改为基于五分的BFPRT算法
BFPRT算法优化了pivot的选取方法,每次选择五分中位数的中位数作为pivot,最坏的时间复杂度由O(n2 )降低到O(n)
余弦相似度计算优化
引用大牛分享,基于LSH算法优化+候选集分桶计算(自己未实现)
尽量避免进行相似度的计算:
- 种子和候选向量后128维‘异或’后bitCount > 2跳过不计算
提升单次相似度计算的效率:
- 向量前128维使用float数组存储
- 向量后128维使用2个long存储,直接通过charAt(0)判断取值是0/1 l 向量点乘计算时,后128维通过‘&’及bitCount计算
- 提前计算向量的模并缓存,防止重复计算
工程优化
- 存储特征唯独使用单精度float,而不是double,差异会很大;
- 尽量使用数组而不是List/Set/Map,使用基础数据类型而不是包装类型
- 使用 ‘>>’ ‘<<’ 代替整数的2的幂次