Подтвердить что ты не робот

Эффективное сопоставление строк в Apache Spark

Используя инструмент OCR, я извлек тексты из скриншотов (около 1-5 предложений каждый). Однако при ручной проверке извлеченного текста я заметил несколько ошибок, которые возникают время от времени.

Учитывая текст "Привет, 😊! Мне очень нравится Spark ❤️!", я заметил, что:

1) Буквы типа "I", "!" и "l" заменяются на "|".

2) Emojis неправильно извлекаются и заменяются другими символами или не учитываются.

3) Пустое пространство время от времени удаляется.

В результате я мог бы получить строку вроде этого: "Привет, 7l | real | y, как Spark!"

Так как я пытаюсь сопоставить эту строку с набором данных, включая правильный текст (в этом случае "Hello there 😊! Мне очень нравится Spark ❤️!" ), я ищу эффективный способ сопоставления строки в Спарк.

Может ли кто-нибудь предложить эффективный алгоритм для Spark, который позволяет мне сравнивать тексты извлечения (~ 100 000) против моего набора данных (~ 100 миллионов)?

4b9b3361

Ответ 1

В первую очередь я бы не использовал Spark, но если вы действительно привержены конкретному стеку, вы можете комбинировать кучу трансформаторов мл, чтобы получить наилучшие совпадения. Вам понадобится Tokenizer (или split):

import org.apache.spark.ml.feature.RegexTokenizer

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

NGram (например, 3 грамма)

import org.apache.spark.ml.feature.NGram

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

Vectorizer (например, CountVectorizer или HashingTF):

import org.apache.spark.ml.feature.HashingTF

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

и LSH:

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

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

Объединить с Pipeline

import org.apache.spark.ml.Pipeline

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

Установите данные примера:

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)

Преобразовать оба:

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

и присоедините

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