2016-12-20 4 views
1

列に100K個の名前があります。私は彼らが同じかどうか(D'souza、D'souza)、またはほぼ同じ(D'souza、Dsouza)かどうかを確認するために、それぞれを比較する必要があります。スカラを使用して1つの行を他のすべての行と比較する方法

私はカサンドラテーブルをRDDに読み込み、列のデカルト積を作成してタプルを作成しました。しかし、列サイズが100Kであるため、これは巨大なRDDをもたらし、最終的にスパークジョブがぶら下がります。ここでの問題は、デカルト結果は理想的ではない100K *の100Kの順になるということです

val valueRdd = sc.cassandraTable("keyspace", "some_table") 
    val dataRDD = valueRdd 
    .map(row => { 
     (
     row 
      .getStringOption("name") 
      .get, 

    }).cache() 

    val cartesianResult = dataRDD cartesian dataRDD 
    //Followed by some compare logic. May be soundex or some other library or some fuzzy logic. 

:以下

は、私が持っているコードです。これを行うための良い方法はありますか?

問題文は、指定されたデータセット内の兄弟を識別することです。データセットには10​​0K +のデータが含まれます。

+0

重複した名前と同じような名前は何ですか?重複排除?データを推測する?あるいは、文字通り、可能なすべてのペアと、それらが同じか類似しているかどうかを文字通りだけ必要としますか? –

+0

アイデアは兄弟を識別することです。この場合、名前には小さなバリエーションがありますが、最終的には同じ人物を参照します。例:D'souza、Dsouzaは同じ人ですが、名前は「 '」で異なります。だから私はそのようなすべてのバリエーションを特定し、すべての兄弟を共通の名前に置き換えています。例:D'souza、DsouzaまたはD souzaまたは類似の名前のすべてのインスタンスは、Dsouzaという共通の名前を持ちます。 – Ankur

答えて

4

リストは、あなたが放送変数にリストを変換し、各ノードを持っている可能性が十分に小さいが、それは放送リストにRDDの一部です比較:

val valueRddBC =sc.broadcast(valueRdd.collect()) 
val similarPairsRdd = valueRdd.flatMap(x => 
    valueRddBc.value.filter(y => dist(x,y) > threshold) 
        .map(y => (x,y))) 

100kのは、あなたができることのに十分に小さいですあなたが望むならドライバの中のすべてのもの(dist関数が高価でないなら、これはもっと速くなるでしょう)。

RDDが本当に大きい場合、LSH(ローカルに機密性の高いハッシング)などの戦略を使用して、無関係なアイテムのほとんどを無視するためにアイテムをある種のフィンガープリントにマップできます。これは、最も近い項目を見つけるためにO(1)を与える近似最近傍アルゴリズムです。

0

あなたの比較機能は名前を比較するために何か複雑ですか?スペースやアポストロフィを削除するだけであれば、単純化されたバージョンのRDDにRDDを変換し、groupByを使用して同様の名前をグループ化することができます。例:

scala> val rdd = sc.parallelize(List("d'souza", "d souza", "Dsouza")) 
scala> rdd.map{ 
    |  case x => x.replaceAll(" ", "").replaceAll("'","").toLowerCase -> x 
    | }.groupByKey.collect 
res3: Array[(String, Iterable[String])] = Array((dsouza,CompactBuffer(d'souza, d souza, Dsouza))) 
関連する問題