web-dev-qa-db-fra.com

Correspondance de chaîne efficace dans Apache Spark

À l'aide d'un outil OCR, j'ai extrait des textes de captures d'écran (environ 1 à 5 phrases chacune). Cependant, lors de la vérification manuelle du texte extrait, j'ai remarqué plusieurs erreurs qui se produisent de temps en temps.

Étant donné le texte "Bonjour là-bas ????! J'aime vraiment Spark ❤️!", J'ai remarqué que:

1) Les lettres comme "I", "!" Et "l" sont remplacées par "|".

2) Les emojis ne sont pas correctement extraits et remplacés par d'autres personnages ou sont laissés de côté.

3) Les espaces vides sont supprimés de temps en temps.

En conséquence, je pourrais finir avec une chaîne comme celle-ci: "Bonjour, 7l | real | y comme Spark!"

Étant donné que j'essaie de faire correspondre ces chaînes à un ensemble de données contenant le texte correct (dans ce cas, "Bonjour, ????! J'aime vraiment Spark ❤️!")), Je recherche un moyen efficace de faire correspondre la chaîne dans Spark.

Quelqu'un peut-il suggérer un algorithme efficace pour Spark qui me permet de comparer les textes extraits (~ 100 000) avec mon ensemble de données (~ 100 millions))?

26
mrtnsd

Je n'utiliserais pas Spark en premier lieu, mais si vous êtes vraiment engagé dans la pile particulière, vous pouvez combiner un tas de transformateurs ml pour obtenir les meilleures correspondances. Vous aurez besoin de Tokenizer (ou split):

import org.Apache.spark.ml.feature.RegexTokenizer

val tokenizer = new RegexTokenizer().setPattern("").setInputCol("text").setMinTokenLength(1).setOutputCol("tokens")

NGram (par exemple 3 grammes)

import org.Apache.spark.ml.feature.NGram

val ngram = new NGram().setN(3).setInputCol("tokens").setOutputCol("ngrams")

Vectorizer (par exemple CountVectorizer ou HashingTF):

import org.Apache.spark.ml.feature.HashingTF

val vectorizer = new HashingTF().setInputCol("ngrams").setOutputCol("vectors")

et LSH:

import org.Apache.spark.ml.feature.{MinHashLSH, MinHashLSHModel}

// Increase numHashTables in practice.
val lsh = new MinHashLSH().setInputCol("vectors").setOutputCol("lsh")

Combiner avec Pipeline

import org.Apache.spark.ml.Pipeline

val pipeline = new Pipeline().setStages(Array(tokenizer, ngram, vectorizer, lsh))

Monter sur des données d'exemple:

val query = Seq("Hello there 7l | real|y like Spark!").toDF("text")
val db = Seq(
  "Hello there ????! I really like Spark ❤️!", 
  "Can anyone suggest an efficient algorithm"
).toDF("text")

val model = pipeline.fit(db)

Transformez les deux:

val dbHashed = model.transform(db)
val queryHashed = model.transform(query)

et rejoignez

model.stages.last.asInstanceOf[MinHashLSHModel]
  .approxSimilarityJoin(dbHashed, queryHashed, 0.75).show
+--------------------+--------------------+------------------+                  
|            datasetA|            datasetB|           distCol|
+--------------------+--------------------+------------------+
|[Hello there ????! ...|[Hello there 7l |...|0.5106382978723405|
+--------------------+--------------------+------------------+

La même approche peut être utilisée dans Pyspark

from pyspark.ml import Pipeline
from pyspark.ml.feature import RegexTokenizer, NGram, HashingTF, MinHashLSH

query = spark.createDataFrame(
    ["Hello there 7l | real|y like Spark!"], "string"
).toDF("text")

db = spark.createDataFrame([
    "Hello there ????! I really like Spark ❤️!", 
    "Can anyone suggest an efficient algorithm"
], "string").toDF("text")


model = Pipeline(stages=[
    RegexTokenizer(
        pattern="", inputCol="text", outputCol="tokens", minTokenLength=1
    ),
    NGram(n=3, inputCol="tokens", outputCol="ngrams"),
    HashingTF(inputCol="ngrams", outputCol="vectors"),
    MinHashLSH(inputCol="vectors", outputCol="lsh")
]).fit(db)

db_hashed = model.transform(db)
query_hashed = model.transform(query)

model.stages[-1].approxSimilarityJoin(db_hashed, query_hashed, 0.75).show()
# +--------------------+--------------------+------------------+
# |            datasetA|            datasetB|           distCol|
# +--------------------+--------------------+------------------+
# |[Hello there ????! ...|[Hello there 7l |...|0.5106382978723405|
# +--------------------+--------------------+------------------+

Connexes

29
hi-zir