2016-03-22 38 views
0

我知道有几个问题已经提出了类似的主题,但我无法对我的问题应用任何答案,也想知道最佳实践。将数据集从SQL转换为RDD [矢量]

我已经将ML的日期集加载到SQL数据库。我想根据它应用mllib的聚类功能。我已经使用sqlContext将SQL数据库加载到DataFrame,删除了不相关的列。然后发生问题的部分,我通过解析DataFrame的每一行来创建一个向量。 然后使用toJavaRDD函数将矢量转换为RDD。

下面是代码(作品):

val usersDF = sqlContext.read.format("jdbc").option("url","jdbc:mysql://localhost/database"). 
    option("driver","com.mysql.jdbc.Driver").option("dbtable","table"). 
    option("user","woot").option("password","woot-password").load() 

val cleanDF = usersDF.drop("id").drop("username") 
cleanDF.show() 

val parsedData = cleanDF.map(s => Vectors.dense(s.toString().replaceAll("[\\[\\]]", "").trim.split(',').map(_.toDouble))).cache() 

val splits = parsedData.randomSplit(Array(0.6,0.4), seed = 11L) 
val train_set = splits(0).cache() 

val gmm = new GaussianMixture().setK(2).run(train_set) 

我的主要问题问候我的火花文档阅读:Local vector,在我的理解数据帧映射将在工人执行,以后会在创建Vector时发送给驱动程序(是否是本地向量的含义)才能稍后再次发送给工人?有没有更好的方法来实现这一目标?

另一件事是,将SQL加载到DataFrame中仅将其转换为字符串并再次解析它似乎有点奇怪。有没有其他的最佳实践建议?

回答

0

link你建议

本地矢量具有整数类型的和基于索引0和双输入 值,存储在单台机器上。 MLlib支持两种类型的本地向量:密集和稀疏。

分布式矩阵具有长型的行和列索引以及分布式存储在一个或多个RDD中的双重类型的值。

当地的载体表现得像个你会用你的RDD(字符串,整数数组)的任何对象,他们创建和一台机器,工作节点上存储,只有当你收集他们他们将被发送到驱动程序节点。

如果考虑大小2n将其存储分布式你会在长度nx1x2(x = x1::x2)两个半区分开它的向量x。要使用另一个矢量y执行点积,工作人员将执行r1=x1*y1(在机器1上)和r2=x2*y2(在机器2上),然后您需要将给出r=r1+r2的部分结果进行分组。你的向量x是分布式的,向量x1x2也是局部向量。如果您有x作为本地向量,那么您可以在一个步骤中在工作节点r=x*y上执行。

对于第二个问题,我不明白为什么要以SQL格式存储矢量。拥有这样的CSV文件就足够了:

label feature1 feature2 ... 
1, 0.5,  1.2  ... 
0, 0.2,  0.5  ...