Samouczek: indeksowanie dużych danych z platformy Apache Spark przy użyciu języka SynapseML i usługi Azure AI Search

Z tego samouczka usługi Azure AI Search dowiesz się, jak indeksować i wykonywać zapytania dotyczące dużych danych załadowanych z klastra Spark. Skonfiguruj notes Jupyter Notebook, który wykonuje następujące akcje:

  • Ładowanie różnych formularzy (faktur) do ramki danych w sesji platformy Apache Spark
  • Analizowanie ich w celu określenia ich funkcji
  • Złóż wynikowe dane wyjściowe do struktury danych tabelarycznych
  • Zapisywanie danych wyjściowych w indeksie wyszukiwania hostowanym w usłudze Azure AI Search
  • Eksplorowanie i wykonywanie zapytań o utworzoną zawartość

Ten samouczek ma zależność od usługi SynapseML — biblioteki typu open source, która obsługuje masowe równoległe uczenie maszynowe na danych big data. W usłudze SynapseML indeksowanie wyszukiwania i uczenie maszynowe są udostępniane za pośrednictwem transformatorów wykonujących wyspecjalizowane zadania. Transformatory zapewniają szeroką gamę możliwości sztucznej inteligencji. W tym ćwiczeniu użyj interfejsów API azureSearchWriter do analizy i wzbogacania sztucznej inteligencji.

Chociaż usługa Azure AI Search ma natywną wzbogacanie sztucznej inteligencji, w tym samouczku pokazano, jak uzyskać dostęp do funkcji sztucznej inteligencji poza usługą Azure AI Search. Korzystając z usługi SynapseML zamiast indeksatorów lub umiejętności, nie podlegasz limitom danych ani innym ograniczeniom skojarzonym z tymi obiektami.

Napiwek

Obejrzyj krótki film z tego pokazu na stronie https://www.youtube.com/watch?v=iXnBLwp7f88. Film wideo rozszerza ten samouczek o więcej kroków i wizualizacji.

Wymagania wstępne

Potrzebna jest biblioteka i kilka zasobów platformy synapseml Azure. Jeśli to możliwe, użyj tej samej subskrypcji i regionu dla zasobów platformy Azure i umieść wszystko w jednej grupie zasobów w celu późniejszego prostego czyszczenia. Poniższe linki dotyczą instalacji portalu. Przykładowe dane są importowane z witryny publicznej.

1 Ten link jest rozpoznawany jako samouczek dotyczący ładowania pakietu.

2 Możesz użyć warstwy wyszukiwania bezpłatna do indeksowania przykładowych danych, ale wybierz wyższą warstwę , jeśli woluminy danych są duże. W przypadku warstw rozliczanych podaj klucz interfejsu API wyszukiwania w kroku Konfigurowanie zależności.

3 W tym samouczku jest używana usługa Azure AI Document Intelligence i usługa Azure AI Translator. W poniższych instrukcjach podaj klucz z wieloma usługami i region. Ten sam klucz działa dla obu usług.

4 W tym samouczku usługa Azure Databricks udostępnia platformę obliczeniową Spark. Użyliśmy instrukcji portalu do skonfigurowania obszaru roboczego.

Uwaga

Wszystkie powyższe zasoby platformy Azure obsługują funkcje zabezpieczeń na platformie Microsoft Identity. Dla uproszczenia w tym samouczku założono, że uwierzytelnianie oparte na kluczach jest używane przy użyciu punktów końcowych i kluczy skopiowanych ze stron portalu każdej usługi. Jeśli zaimplementujesz ten przepływ pracy w środowisku produkcyjnym lub udostępnisz rozwiązanie innym osobom, pamiętaj, aby zastąpić zakodowane klucze zintegrowanymi zabezpieczeniami lub zaszyfrowanymi kluczami.

Krok 1. Tworzenie klastra i notesu Spark

W tej sekcji utwórz klaster, zainstaluj synapseml bibliotekę i utwórz notes, aby uruchomić kod.

  1. W witrynie Azure Portal znajdź obszar roboczy usługi Azure Databricks i wybierz pozycję Uruchom obszar roboczy.

  2. W menu po lewej stronie wybierz pozycję Obliczenia.

  3. Wybierz pozycję Utwórz zasoby obliczeniowe.

  4. Zaakceptuj konfigurację domyślną. Utworzenie klastra trwa kilka minut.

  5. Zainstaluj bibliotekę synapseml po utworzeniu klastra:

    1. Wybierz pozycję Biblioteki na kartach w górnej części strony klastra.

    2. Wybierz pozycję Zainstaluj nową.

      Zrzut ekranu przedstawiający polecenie Zainstaluj nowe.

    3. Wybierz pozycję Maven.

    4. W obszarze Współrzędne wprowadź com.microsoft.azure:synapseml_2.12:1.0.4

    5. Wybierz Zainstaluj.

      Zrzut ekranu przedstawiający specyfikację pakietu Maven.

  6. W menu po lewej stronie wybierz pozycję Utwórz>notes.

    Zrzut ekranu przedstawiający polecenie Utwórz notes.

  7. Nadaj notesowi nazwę, wybierz język Python jako język domyślny, a następnie wybierz klaster, który ma bibliotekę synapseml .

  8. Utwórz siedem kolejnych komórek. Wklej kod do każdego z nich.

    Zrzut ekranu notesu z komórkami zastępczymi.

Krok 2. Konfigurowanie zależności

Wklej następujący kod do pierwszej komórki notesu.

Zastąp symbole zastępcze punktami końcowymi i kluczami dostępu dla każdego zasobu. Podaj nazwę nowego indeksu wyszukiwania. Nie są wymagane żadne inne modyfikacje, więc uruchom kod, gdy wszystko będzie gotowe.

Ten kod importuje wiele pakietów i konfiguruje dostęp do zasobów platformy Azure używanych w tym przepływie pracy.

import os
from pyspark.sql.functions import udf, trim, split, explode, col, monotonically_increasing_id, lit
from pyspark.sql.types import StringType
from synapse.ml.core.spark import FluentAPI

cognitive_services_key = "placeholder-cognitive-services-multi-service-key"
cognitive_services_region = "placeholder-cognitive-services-region"

search_service = "placeholder-search-service-name"
search_key = "placeholder-search-service-api-key"
search_index = "placeholder-search-index-name"

Krok 3. Ładowanie danych do platformy Spark

Wklej następujący kod do drugiej komórki. Nie są wymagane żadne modyfikacje, dlatego uruchom kod, gdy wszystko będzie gotowe.

Ten kod ładuje kilka plików zewnętrznych z konta usługi Azure Storage. Pliki są różnymi fakturami i są odczytywane w ramce danych.

def blob_to_url(blob):
    [prefix, postfix] = blob.split("@")
    container = prefix.split("/")[-1]
    split_postfix = postfix.split("/")
    account = split_postfix[0]
    filepath = "/".join(split_postfix[1:])
    return "https://{}/{}/{}".format(account, container, filepath)


df2 = (spark.read.format("binaryFile")
    .load("wasbs://ignite2021@mmlsparkdemo.blob.core.windows.net/form_subset/*")
    .select("path")
    .limit(10)
    .select(udf(blob_to_url, StringType())("path").alias("url"))
    .cache())
    
display(df2)

Krok 4. Dodawanie analizy dokumentów

Wklej następujący kod do trzeciej komórki. Nie są wymagane żadne modyfikacje, dlatego uruchom kod, gdy wszystko będzie gotowe.

Ten kod ładuje transformator AnalyzeInvoices i przekazuje odwołanie do ramki danych zawierającej faktury. Wywołuje ona wstępnie utworzony model faktur analizy dokumentów usługi Azure AI w celu wyodrębnienia informacji z faktur.

from synapse.ml.cognitive import AnalyzeInvoices

analyzed_df = (AnalyzeInvoices()
    .setSubscriptionKey(cognitive_services_key)
    .setLocation(cognitive_services_region)
    .setImageUrlCol("url")
    .setOutputCol("invoices")
    .setErrorCol("errors")
    .setConcurrency(5)
    .transform(df2)
    .cache())

display(analyzed_df)

Dane wyjściowe z tego kroku powinny wyglądać podobnie do następnego zrzutu ekranu. Zwróć uwagę, że analiza formularzy jest pakowana w gęsto ustrukturyzowaną kolumnę, z którą trudno jest pracować. Kolejna transformacja rozwiązuje ten problem, analizuje kolumnę w wierszach i kolumnach.

Zrzut ekranu przedstawiający dane wyjściowe funkcji AnalyzeInvoices.

Krok 5. Zmiana struktury danych wyjściowych analizy dokumentów

Wklej następujący kod do czwartej komórki i uruchom go. Nie są wymagane żadne modyfikacje.

Ten kod ładuje formOntologyLearner, transformator, który analizuje dane wyjściowe funkcji przekształcania analizy dokumentów i wywnioskuje strukturę danych tabelarycznych. Dane wyjściowe funkcji AnalyzeInvoices są dynamiczne i różnią się w zależności od funkcji wykrytych w zawartości. Ponadto transformator konsoliduje dane wyjściowe w jedną kolumnę. Ponieważ dane wyjściowe są dynamiczne i skonsolidowane, trudno jest ich używać w przekształceniach podrzędnych, które wymagają większej struktury.

FormOntologyLearner rozszerza narzędzie przekształcania AnalyzeInvoices, wyszukując wzorce, których można użyć do utworzenia struktury danych tabelarycznych. Organizowanie danych wyjściowych w wielu kolumnach i wierszach sprawia, że zawartość jest eksploatująca w innych transformatorach, takich jak AzureSearchWriter.

from synapse.ml.cognitive import FormOntologyLearner

itemized_df = (FormOntologyLearner()
    .setInputCol("invoices")
    .setOutputCol("extracted")
    .fit(analyzed_df)
    .transform(analyzed_df)
    .select("url", "extracted.*").select("*", explode(col("Items")).alias("Item"))
    .drop("Items").select("Item.*", "*").drop("Item"))

display(itemized_df)

Zwróć uwagę, że ta transformacja przekształca zagnieżdżone pola w tabelę, co umożliwia wykonanie dwóch następnych przekształceń. Ten zrzut ekranu został przycięty do zwięzłości. Jeśli obserwujesz je we własnym notesie, masz 19 kolumn i 26 wierszy.

Zrzut ekranu przedstawiający dane wyjściowe FormOntologyLearner.

Krok 6. Dodawanie tłumaczeń

Wklej następujący kod do piątej komórki. Nie są wymagane żadne modyfikacje, dlatego uruchom kod, gdy wszystko będzie gotowe.

Ten kod ładuje funkcję Translate— transformator, który wywołuje usługę Azure AI Translator w usługach Azure AI. Oryginalny tekst, który jest w języku angielskim w kolumnie "Opis", jest tłumaczony maszynowo na różne języki. Wszystkie dane wyjściowe są konsolidowane w tablicy "output.translations".

from synapse.ml.cognitive import Translate

translated_df = (Translate()
    .setSubscriptionKey(cognitive_services_key)
    .setLocation(cognitive_services_region)
    .setTextCol("Description")
    .setErrorCol("TranslationError")
    .setOutputCol("output")
    .setToLanguage(["zh-Hans", "fr", "ru", "cy"])
    .setConcurrency(5)
    .transform(itemized_df)
    .withColumn("Translations", col("output.translations")[0])
    .drop("output", "TranslationError")
    .cache())

display(translated_df)

Napiwek

Aby sprawdzić przetłumaczone ciągi, przewiń do końca wierszy.

Zrzut ekranu przedstawiający dane wyjściowe tabeli z kolumną Tłumaczenia.

Krok 7. Dodawanie indeksu wyszukiwania za pomocą narzędzia AzureSearchWriter

Wklej następujący kod w szóstej komórce, a następnie uruchom go. Nie są wymagane żadne modyfikacje.

Ten kod ładuje element AzureSearchWriter. Korzysta z tabelarycznego zestawu danych i wywnioskuje schemat indeksu wyszukiwania, który definiuje jedno pole dla każdej kolumny. Ponieważ struktura tłumaczeń jest tablicą, jest ona wyrażana w indeksie jako złożona kolekcja z polami podrzędnymi dla każdego tłumaczenia języka. Wygenerowany indeks ma klucz dokumentu i użyj wartości domyślnych dla pól utworzonych przy użyciu interfejsu API REST tworzenia indeksu.

from synapse.ml.cognitive import *

(translated_df.withColumn("DocID", monotonically_increasing_id().cast("string"))
    .withColumn("SearchAction", lit("upload"))
    .writeToAzureSearch(
        subscriptionKey=search_key,
        actionCol="SearchAction",
        serviceName=search_service,
        indexName=search_index,
        keyCol="DocID",
    ))

Możesz sprawdzić strony usługi wyszukiwania w witrynie Azure Portal, aby zapoznać się z definicją indeksu utworzoną przez narzędzie AzureSearchWriter.

Uwaga

Jeśli nie możesz użyć domyślnego indeksu wyszukiwania, możesz podać zewnętrzną definicję niestandardową w formacie JSON, przekazując jej identyfikator URI jako ciąg we właściwości "indexJson". Najpierw wygeneruj indeks domyślny, aby wiedzieć, które pola mają być określone, a następnie postępuj zgodnie z dostosowanymi właściwościami, jeśli na przykład potrzebujesz określonych analizatorów.

Krok 8. Wykonywanie zapytań względem indeksu

Wklej następujący kod do siódmej komórki, a następnie uruchom go. Nie są wymagane żadne modyfikacje, z wyjątkiem tego, że warto zmienić składnię lub wypróbować więcej przykładów, aby dokładniej zapoznać się z zawartością:

Nie ma transformatora ani modułu, który wystawia zapytania. Ta komórka jest prostym wywołaniem interfejsu API REST wyszukiwania dokumentów.

W tym konkretnym przykładzie wyszukiwany jest wyraz "door" ("search": "door"). Zwraca również wartość "count" liczby pasujących dokumentów i wybiera tylko zawartość pól "Description" i "Translations" dla wyników. Jeśli chcesz wyświetlić pełną listę pól, usuń parametr "select".

import requests

url = "https://{}.search.windows.net/indexes/{}/docs/search?api-version=2020-06-30".format(search_service, search_index)
requests.post(url, json={"search": "door", "count": "true", "select": "Description, Translations"}, headers={"api-key": search_key}).json()

Poniższy zrzut ekranu przedstawia dane wyjściowe komórki dla przykładowego skryptu.

Zrzut ekranu przedstawiający wyniki zapytania z polami licznika, ciągu wyszukiwania i zwracania.

Czyszczenie zasobów

Gdy pracujesz we własnej subskrypcji, na końcu projektu warto usunąć zasoby, których już nie potrzebujesz. Uruchomione zasoby mogą generować koszty. Zasoby możesz usuwać pojedynczo lub jako grupę zasobów, usuwając cały zestaw zasobów.

Zasoby można znaleźć w portalu i zarządzać nimi, korzystając z linku Wszystkie zasoby lub Grupy zasobów w okienku nawigacji po lewej stronie.

Następne kroki

W tym samouczku przedstawiono przekształcanie azureSearchWriter w usłudze SynapseML, czyli nowy sposób tworzenia i ładowania indeksów wyszukiwania w usłudze Azure AI Search. Funkcja przekształcania przyjmuje ustrukturyzowany kod JSON jako dane wejściowe. FormOntologyLearner może zapewnić niezbędną strukturę danych wyjściowych generowanych przez transformatory analizy dokumentów w usłudze SynapseML.

W następnym kroku zapoznaj się z innymi samouczkami usługi SynapseML, które generują przekształconą zawartość, którą warto eksplorować za pomocą usługi Azure AI Search: