使用Spark

时间:2018-10-10 05:10:25

标签: scala apache-spark

我有两个文本文件,每行都是(id,数字序列)形式。 我也有一个阈值。

文件1如下所示,其中第一行的ID为0,其余的为 一系列数字。

0 1 4 5 6
1 2 3 6
2 4 5 6

类似地,我有以下内容的文件2。

0 1 4 6
1 2 5 6
2 3 5

我必须找到相似度值大于或等于阈值的那些行。相似度值可以计算为两条线的交点除以两条线的并集。例如,文件1的ID-0行具有seq 1,4,5,6,文件2的ID-0行具有seq 1,4,6。它们的相交大小= 3,联合大小=4。因此它们的相似度将是3/4 = 0.75,大于阈值。

我已经编写了python代码来执行此任务,并尝试将其转换为Scala。

    with open("file1.txt") as f1:
        content1 = f1.readlines()
    content1 = [x.strip() for x in content1]

    with open("file2.txt") as f2:
        content2 = f2.readlines()
    content2 = [x.strip() for x in content2]

    threshold = 0.5
    final_index_list_with_similarity = []

    for i in range(len(content1)):
        for j in range(len(content2)):
            index_content1 = content1[i][0]
            index_content2 = content2[j][0]
            s = set(content1[i][1:])
            t = set(content2[j][1:])
            intersect = s & t
            intersect_size = len(intersect) - 1
            union_size = len(s) + len(t) - intersect_size - 2 #substracting two because I am getting two extra space.
            similarity = intersect_size/union_size
            if similarity >= threshold:
                final_index_list_with_similarity.append((index_content1, index_content2, similarity))
    print(final_index_list_with_similarity)

输出:[('0', '0', 0.75), ('1', '1', 0.5), ('2', '0', 0.5), ('2', '1', 0.5)]

到目前为止,我在scala中尝试的操作看起来像这样。

val inputFile1 = args(0)
val inputFile2 = args(1)
val threshold = args(2).toDouble
val ouputFolder = args(3)

val conf = new SparkConf().setAppName("SetSimJoin").setMaster("local")
val sc = new SparkContext(conf)

val lines1 = sc.textFile(inputFile1).flatMap(line => line.split("\n"))
val lines2 = sc.textFile(inputFile2).flatMap(line => line.split("\n"))

val elements1 = lines1.map { x => x.drop(x.split(" ")(0).length.toInt + 1) }.flatMap { x => x.split(" ") }.map { x => (x, 1) }.reduceByKey(_+_)
val elements2 = lines2.map { x => x.drop(x.split(" ")(0).length.toInt + 1) }.flatMap { x => x.split(" ") }.map { x => (x, 1) }.reduceByKey(_+_)

这给了我整个文件中每个数字的频率。

任何帮助或指导将不胜感激。

1 个答案:

答案 0 :(得分:4)

两个文件都可以作为RDD加入,然后应用公式:“交集大小/联合大小”:

val lines1 = sparkContext.textFile("inputFile1")
val lines2 = sparkContext.textFile("inputFile2")

val rdd1 = lines1.map(_.split(" ")).map(v => (v(0), v.tail))
val rdd2 = lines2.map(_.split(" ")).map(v => (v(0), v.tail))

val result = rdd1.join(rdd2).map(r => (
  r._1,
  r._2._1.intersect(r._2._2).size * 1.0 /
    r._2._1.union(r._2._2).distinct.size
)
)

result.foreach(println)

输出为:

(1,0.5)
(0,0.75)
(2,0.25)