最近在写spark下的机器学习程序,用RDD编程模型。spark自带的机器学习算法API局限太多。想请问各路大侠,能不能再spark的编程模型下引用scikit-learn?

回复内容:

和以上几个观点不同,我认为在PySpark下引用scikit-learn可能的,但不能直接简单粗暴地移植,而是要相应地对各自环境下的数据结构做一些转换。

我们知道scikit-learn运算中最核心的数据结构存储主要是numpy ndarray,而Spark运算中最核心的存储是RDD,说白了就是一个基于有向无环图的MapReduce,图的目的就是减少Map和Reduce之间传递的数据,所以非常适合反复迭代的机器学习场景。PySpark可以提供很好用的API来计算map、reduce、join、filter等函数式运算,但没法处理numpy ndarray这种local存储。

所以就是要想办法将(distributed的RDD)披上羊(local的ndarray)的皮(变成ndarrayRDD),混入羊群(scikit-learn)就能吃上肉了。简单地说,就是用RDD的键值对(key-value pairs)来表示多维数组的不同部分,并从中记录着变换后的子数组的形状及其计算时发生的各种变化。比如说吧,我们设定一个数组可以用其axes的子集作为键,因此一个标出横轴和纵轴(axis=(0,1))的五维数组就可以表示成key-value pairs,其中keys是二元组,values是三维数组,这就算做成了一个ndarrayRDD。然后ndarrayRDD不断地转置、变形,从而实现不断并行化的过程。这当中我们可以用Python中的map、filter、reduce等函数式运算,再加上Spark中的cache、unpersist等方法控制RDD的缓存,也就没浪费Spark的快速特点,同时也发挥了Python和scikit-learn的优势。

我就这样大致这么一说,更具体的理解还要有赖于直接阅读源码。是的,其实这方面的尝试早就有人做了,而且有的开发得已经相当不错了呢。

GitHub - bolt-project/bolt: Unified interface for local and distributed ndarrays
推荐!这是我最早看到的关于多维数组的单机和分布式之间的转换方法,其设计思路的关键在于一个叫swap的方法,也就是我上面提到的ndarrayRDD的key-value pairs不断变换,把value axes挪到key axes,value axes可以分开挪到key axes等等,split就越来越多,自然就越来越并行化。

GitHub - thunder-project/thunder: scalable analysis of images and time series
thunder是一个可以处理以图像为主的海量数据的包,其中用到分布式的部分就是引用了上面所说的bolt.spark。

GitHub - lensacom/sparkit-learn: PySpark + Scikit-learn = Sparkit-learn
这个splearn是我觉得目前很有前途的一个包,因为它提供了三种分布式的数据结构:arrayRDD、sparseRDD、dictRDD,同时也相应地改写了scikit-learn,以适用于变换过的RDD。

GitHub - databricks/spark-sklearn: Scikit-learn integration package for Spark
最后说一下databricks亲自开发的这个Spark-sklearn。开发得还不够充分,功能还非常有限,只能是在数据集in memory的前提下,用网格搜寻对参数做交叉验证(也就是用到scikit-learn里面的GridSearchCV)的时候实现并行,而不能像MLlib那样对每个学习算法实现并行;当内存架不住很大的数据集的时候,还得上Spark MLlib。o(︶︿︶)o泻药!简单的回答是:不能。
spark的核心是RDD,是一个DAG版的map reduce,机器学习算法的单机和并行化版本的实现是完全不同的,sklearn作为单机的算法库是不能简单的移植到spark上的

2016.2.10 updated:
在github上发现了一个项目GitHub - databricks/spark-sklearn: Scikit-learn integration package for Spark,目的是为了无缝的把sklearn和spark集成,不过现在看上去功能还比较简单家里的不规则自留地就别指望用生产队的康麦因收割了顶多是提供和scikit一样的API,但是内部实现是完全不一样的,底层的数据结构就不同,上层的算法逻辑也不同,还怎么移植?有那么爽就好了没有用过scikit这个包,不过很同意你所说的spark api限制多这个结论。很多我们习惯使用的参数或者用法在spark里都不好使了。但是我对于spark mllib的理解是他的算法是basic的,但是其中的散列化和网络吞吐量的考虑是亮点,很棒的亮点。如果有时间和精力,完全可以去把基础算法改进至你想要的模式。上次scikit照理说应该在pyspark下引进去,但是能否实现分布式效率得看scikit实现方法了。浅见,希望有用
09-15 09:40