将数据集从SQL转换为RDD [vector]

时间:2016-03-22 08:04:24

标签: scala apache-spark apache-spark-mllib

我知道有几个问题已经被问过类似的主题,但我无法应用我的问题的任何答案,我也想知道最佳做法。

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

我的主要问题是关于我在Spark文档中读到的内容:Local vector,在我的理解中,DataFrame映射将在worker上执行,之后将在创建Vector时发送给Driver(是本地载体的含义)只是为了以后再发送给工人?是不是有更好的方法来实现这一目标?

另外一点是,将SQL加载到DataFrame只是为了将其转换为字符串并再次解析它似乎有点奇怪。还有其他最佳做法建议吗?

1 个答案:

答案 0 :(得分:0)

来自您建议的link

  

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

     

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

本地向量的行为类似于您将用于RDD(String,Integer,Array)的任何对象,它们是在单个计算机上创建和存储的工作节点,并且仅当您收集它们,它们将被发送到驱动程序节点。

如果您考虑分配存储它的大小为x的向量2n,则会将其分为长度为nx1x2的两半, (x = x1::x2)。要使用另一个向量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      ...