(更新于2014/01/26)关注和学习数据挖掘不少年,现在数据挖掘算法已经非常多了,比较出名的基本都能找到实现好的。掌握一个算法原理十分重要,但我觉得实现一遍算法对于算法的如何适用数据才是最有帮助的。一些挖掘工具遇到大量点的数据集就吃不消,可能是对内存不珍惜,可能是对计算不节俭等等。感觉到写出一个能在海量规模下实用的算法应该还是有意义,能锻炼技术。最近业余时间多一些,也就开始想把之前工作之余写过的算法重新汇总一下。很久不写博客有点不太好。
于是给自己建了个项目:dami 是data mining的前两个字符组合,
在githubs https://github.com/lgnlgn/dami 能下到源码
(这个项目最终会合并到feluca里作为单机部分)
dami的目标是能够高效地在单机上处理海量数据,达到亿的级别。当然现在海量数据都分布式了,有MPI\MR\BSP等各种并行处理框架, 算法也基本都被并行化了。但是可能很多人还没这种条件,因此在单机做实验或者工程还是有需要的。
dami用java的原因主要有几个,1:我觉得数据挖掘很大一部分时间是让数据在模型里跑,这部分开销不可避免因此语言影响不会太大;2:java使用广泛,效率也不差太多,代码测试的时候觉得只用java基本类型也挺够快了;3:另外这个项目学习为主,希望更多的人能加入一起,当然最重要的原因还是当前我对java和python最熟悉。
为了能让算法在达到单机有限内存处理大量数据,我主要用了两个思路:一是数据集留在磁盘,只留模型在内存;二是数据ID化,尽可能连续地存放,并用id做检索。而很多算法要迭代多次扫数据集,因此IO必须足够快,而如果用java每次都解析文本,那速度实在不能忍,加上java的String的处理效率不行,内存控制不能. 所以我采用高效的字节流。也因此,每个数据集都得转换成字节码存放在文件里。对一个算法的格式而言,转换的工作无聊而繁琐,但是又必须进行,虽然理论上是每条数据可以独立地流式处理,不存在内存问题,但java字符流速度使处理速度不如人意。
增加了两个基础库:1. 数据向量池,通过一个小缓存进行一边读一边写的异步IO,提高CPU使用率;2. 简单的纯ID的数据的解析工具类,就是简单把文本字符的ascii码取出,对照ascii码表与数值有关的字符,包括'0123456789+-.',其他字符一律当成分隔符。
dami有几个算法,基本都在我博客上能找到,列表如下,将会不断更新:
目前有:
- 分类:SGD逻辑回归 L1以及L2
- 推荐:SlopeOne\SVD\RSVD\ItemNeighborSVD
- 显著检验:随机交换
- 图挖掘:pagerank
下一步推出:
- 近似查找:simhash(结构不太一样,暂不放进去了)
- 争取实现SGD逻辑回归的hadoop版
未来需要:
- 其他算法
基础库部分,接口基本上阶段性完成了,可能还需要些深入测试,那么实现算法只需要关心核心计算。如果有哪位朋友也希望加入项目一起学习、增加算法、提出意见,欢迎随时留言联系,邮箱:gnliang10 [at] 126.com 或QQ:一久叁35三⑤三