我知道有几个问题已经被问过类似的主题,但我无法应用我的问题的任何答案,我也想知道最佳做法。
我已将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只是为了将其转换为字符串并再次解析它似乎有点奇怪。还有其他最佳做法建议吗?
答案 0 :(得分:0)
来自您建议的link
本地向量具有整数类型和0基类索引并且具有双类型 值,存储在一台机器上。 MLlib支持两种类型的本地 向量:密集和稀疏。
分布式矩阵具有长类型的行和列索引 双类型值,分布式存储在一个或多个RDD中。
本地向量的行为类似于您将用于RDD(String,Integer,Array)的任何对象,它们是在单个计算机上创建和存储的工作节点,并且仅当您收集它们,它们将被发送到驱动程序节点。
如果您考虑分配存储它的大小为x
的向量2n
,则会将其分为长度为n
,x1
和x2
的两半, (x = x1::x2)
。要使用另一个向量y
执行点积,工作人员将执行r1=x1*y1
(在计算机1上)和r2=x2*y2
(在计算机2上),然后您将需要对部分结果进行分组r=r1+r2
。您的向量x
已分布,向量x1
和x2
也是本地向量。如果您将x
作为本地向量,则只需一步即可在工作节点r=x*y
上执行。
对于第二个问题,我不明白为什么要以SQL格式存储向量。拥有这样的CSV文件就足够了:
label feature1 feature2 ...
1, 0.5, 1.2 ...
0, 0.2, 0.5 ...