Delen via


Door de gebruiker gedefinieerde Python-tabelfuncties (UDDF's) in Unity Catalog

Belangrijk

Het registreren van Python UDFS in Unity Catalog bevindt zich in openbare preview.

Een door de gebruiker gedefinieerde tabelfunctie (UDTF) van Unity Catalog registreert functies die volledige tabellen retourneren in plaats van scalaire waarden. In tegenstelling tot scalaire functies die één resultaatwaarde retourneren uit elke aanroep, worden UDDF's aangeroepen in de component van FROM een SQL-instructie en kunnen meerdere rijen en kolommen worden geretourneerd.

UDDF's zijn met name handig voor:

  • Matrices of complexe gegevensstructuren transformeren in meerdere rijen
  • Externe API's of services integreren in SQL-werkstromen
  • Aangepaste gegevensgeneratie- of verrijkingslogica implementeren
  • Verwerking van gegevens waarvoor stateful bewerkingen in rijen zijn vereist

Elke UDTF-aanroep accepteert nul of meer argumenten. Deze argumenten kunnen scalaire expressies of tabelargumenten zijn die volledige invoertabellen vertegenwoordigen.

UDDF's kunnen op twee manieren worden geregistreerd:

Requirements

UDFS voor Unity Catalog Python worden ondersteund op de volgende rekentypen:

  • Serverloze notebooks en taken
  • Klassieke berekening met standaardtoegangsmodus (Databricks Runtime 17.1 en hoger)
  • SQL Warehouse (servervrij of pro)

Een UDTF maken in Unity Catalog

Gebruik SQL DDL om een beheerde UDTF te maken in Unity Catalog. UDTF's worden aangeroepen door de FROM clausule van een SQL-instructie.

CREATE OR REPLACE FUNCTION square_numbers(start INT, end INT)
RETURNS TABLE (num INT, squared INT)
LANGUAGE PYTHON
HANDLER 'SquareNumbers'
DETERMINISTIC
AS $$
class SquareNumbers:
    """
    Basic UDTF that computes a sequence of integers
    and includes the square of each number in the range.
    """
    def eval(self, start: int, end: int):
        for num in range(start, end + 1):
            yield (num, num * num)
$$;

SELECT * FROM square_numbers(1, 5);

+-----+---------+
| num | squared |
+-----+---------+
| 1   | 1       |
| 2   | 4       |
| 3   | 9       |
| 4   | 16      |
| 5   | 25      |
+-----+---------+

Azure Databricks implementeert Python UDFS als Python-klassen met een verplichte eval methode die uitvoerrijen oplevert.

Tabelargumenten

Opmerking

TABLE argumenten worden ondersteund in Databricks Runtime 17.2 en hoger.

UDTF's kunnen volledige tabellen accepteren als invoerargumenten, waardoor complexe transformaties en aggregaties met behoud van status mogelijk zijn.

eval() en terminate() levenscyclusmethoden

Tabelargumenten in UDDF's maken gebruik van de volgende functies om elke rij te verwerken:

  • eval(): Eenmaal aangeroepen voor elke rij in de invoertabel. Dit is de belangrijkste verwerkingsmethode en is vereist.
  • terminate(): Eenmaal aangeroepen aan het einde van elke partitie, nadat alle rijen zijn verwerkt door eval(). Gebruik deze methode om uiteindelijke samengevoegde resultaten te genereren of opschoonbewerkingen uit te voeren. Deze methode is optioneel, maar essentieel voor bewerkingen met toestandsinformatie, zoals het uitvoeren van aggregaties, tellingen of batchverwerking.

Zie eval() voor meer informatie over terminate() en methoden.

Rijtoegangspatronen

eval() ontvangt rijen van TABLE argumenten als pyspark.sql.Row-objecten . U kunt waarden toegankelijk maken via kolomnaam (row['id'], row['name']) of via index (row[0], row[1]).

  • Flexibiliteit van schema: argumenten zonder schemadefinities declareren TABLE (bijvoorbeeld data TABLE, t TABLE). De functie accepteert elke tabelstructuur, dus uw code moet valideren dat de vereiste kolommen bestaan.

Zie Voorbeeld: IP-adressen vergelijken met CIDR-netwerkblokken en Voorbeeld: Batch afbeeldingsonderschriften maken met behulp van Azure Databricks visie-eindpunten.

Omgevingsisolatie

Opmerking

Voor gedeelde isolatieomgevingen is Databricks Runtime 17.2 en hoger vereist. In eerdere versies worden alle Unity Catalog Python UDFS uitgevoerd in de modus Strikt isolatie.

UDFS voor Unity Catalog Python met dezelfde eigenaar en sessie kunnen standaard een isolatieomgeving delen. Dit verbetert de prestaties en vermindert het geheugengebruik door het aantal afzonderlijke omgevingen te verminderen dat moet worden gestart.

Strikte isolatie

Voeg de STRICT ISOLATION kenmerkcomponent toe om ervoor te zorgen dat een UDTF altijd in een eigen, volledig geïsoleerde omgeving wordt uitgevoerd.

De meeste UDDF's hebben geen strikte isolatie nodig. Standaard-UDDF's voor gegevensverwerking profiteren van de standaardomgeving voor gedeelde isolatie en worden sneller uitgevoerd met een lager geheugenverbruik.

Voeg de STRICT ISOLATION kenmerkcomponent toe aan UDDF's die:

  • Voer invoer uit als code met behulp vaneval()exec(), of vergelijkbare functies.
  • Schrijf bestanden naar het lokale bestandssysteem.
  • Wijzig globale variabelen of systeemstatus.
  • Omgevingsvariabelen openen of wijzigen.

In het volgende UDTF-voorbeeld wordt een aangepaste omgevingsvariabele ingesteld, wordt de variabele teruggelezen en wordt een set getallen vermenigvuldigd met behulp van de variabele. Omdat de UDTF de procesomgeving muteert, voert u deze uit in STRICT ISOLATION. Anders kan het omgevingsvariabelen lekken of overschrijven voor andere UDF's/UDDF's in dezelfde omgeving, waardoor onjuist gedrag wordt veroorzaakt.

CREATE OR REPLACE TEMPORARY FUNCTION multiply_numbers(factor STRING)
RETURNS TABLE (original INT, scaled INT)
LANGUAGE PYTHON
STRICT ISOLATION
HANDLER 'Multiplier'
AS $$
import os

class Multiplier:
    def eval(self, factor: str):
        # Save the factor as an environment variable
        os.environ["FACTOR"] = factor

        # Read it back and convert it to a number
        scale = int(os.getenv("FACTOR", "1"))

        # Multiply 0 through 4 by the factor
        for i in range(5):
            yield (i, i * scale)
$$;

SELECT * FROM multiply_numbers("3");

Stel DETERMINISTIC in als uw functie consistente resultaten produceert

Voeg deze DETERMINISTIC toe aan uw functiedefinitie als deze dezelfde uitvoer produceert voor dezelfde invoer. Hierdoor kunnen queryoptimalisaties de prestaties verbeteren.

Standaard wordt ervan uitgegaan dat Python UDFS in Batch Unity Catalog niet-deterministisch zijn, tenzij expliciet gedeclareerd. Voorbeelden van niet-deterministische functies zijn: willekeurige waarden genereren, de huidige tijden of datums openen of externe API-aanroepen uitvoeren.

Zie CREATE FUNCTION (SQL en Python).

Praktische voorbeelden

In de volgende voorbeelden ziet u praktijkvoorbeelden voor Unity Catalog Python UDFS, waarbij u van eenvoudige gegevenstransformaties naar complexe externe integraties gaat.

Voorbeeld: Opnieuw implementeren explode

Hoewel Spark een ingebouwde functie biedt, toont het maken van uw eigen versie het fundamentele UDTF-patroon explode van het nemen van één invoer en het produceren van meerdere uitvoerrijen.

CREATE OR REPLACE FUNCTION my_explode(arr ARRAY<STRING>)
RETURNS TABLE (element STRING)
LANGUAGE PYTHON
HANDLER 'MyExplode'
DETERMINISTIC
AS $$
class MyExplode:
    def eval(self, arr):
        if arr is None:
            return
        for element in arr:
            yield (element,)
$$;

Gebruik de functie rechtstreeks in een SQL-query:

SELECT element FROM my_explode(array('apple', 'banana', 'cherry'));
+---------+
| element |
+---------+
| apple   |
| banana  |
| cherry  |
+---------+

U kunt deze functie ook toepassen op bestaande tabelgegevens met een LATERAL samenvoeging:

SELECT s.*, e.element
FROM my_items AS s,
LATERAL my_explode(s.items) AS e;

Voorbeeld: geolocatie van IP-adres via REST API

In dit voorbeeld ziet u hoe UDDF's externe API's rechtstreeks in uw SQL-werkstroom kunnen integreren. Analisten kunnen gegevens verrijken met realtime API-aanroepen met behulp van vertrouwde SQL-syntaxis, zonder afzonderlijke ETL-processen te vereisen.

CREATE OR REPLACE FUNCTION ip_to_location(ip_address STRING)
RETURNS TABLE (city STRING, country STRING)
LANGUAGE PYTHON
HANDLER 'IPToLocationAPI'
AS $$
class IPToLocationAPI:
    def eval(self, ip_address):
        import requests
        api_url = f"https://api.ip-lookup.example.com/{ip_address}"
        try:
            response = requests.get(api_url)
            response.raise_for_status()
            data = response.json()
            yield (data.get('city'), data.get('country'))
        except requests.exceptions.RequestException as e:
            # Return nothing if the API request fails
            return
$$;

Opmerking

Python UDFS staan TCP/UDP-netwerkverkeer toe via poorten 80, 443 en 53 bij gebruik van serverloze berekeningen of berekeningen die zijn geconfigureerd met de standaardtoegangsmodus.

Gebruik de functie om weblogboekgegevens te verrijken met geografische informatie:

SELECT
  l.timestamp,
  l.request_path,
  geo.city,
  geo.country
FROM web_logs AS l,
LATERAL ip_to_location(l.ip_address) AS geo;

Deze benadering maakt realtime geografische analyse mogelijk zonder dat vooraf verwerkte opzoektabellen of afzonderlijke gegevenspijplijnen nodig zijn. De UDTF verwerkt HTTP-aanvragen, JSON-parsering en foutafhandeling, waardoor externe gegevensbronnen toegankelijk zijn via standaard SQL-query's.

Voorbeeld: IP-adressen vergelijken met CIDR-netwerkblokken

In dit voorbeeld ziet u overeenkomende IP-adressen voor CIDR-netwerkblokken, een algemene data engineering-taak waarvoor complexe SQL-logica is vereist.

Maak eerst voorbeeldgegevens met zowel IPv4- als IPv6-adressen:

-- An example IP logs with both IPv4 and IPv6 addresses
CREATE OR REPLACE TEMPORARY VIEW ip_logs AS
VALUES
  ('log1', '192.168.1.100'),
  ('log2', '10.0.0.5'),
  ('log3', '172.16.0.10'),
  ('log4', '8.8.8.8'),
  ('log5', '2001:db8::1'),
  ('log6', '2001:db8:85a3::8a2e:370:7334'),
  ('log7', 'fe80::1'),
  ('log8', '::1'),
  ('log9', '2001:db8:1234:5678::1')
t(log_id, ip_address);

Definieer en registreer vervolgens de UDTF. Let op de Python-klassestructuur:

  • De t TABLE parameter accepteert een invoertabel met elk schema. De UDTF past zich automatisch aan om alle kolommen te verwerken. Deze flexibiliteit betekent dat u dezelfde functie in verschillende tabellen kunt gebruiken zonder de functiehandtekening te wijzigen. U moet echter zorgvuldig het schema van de rijen controleren om compatibiliteit te garanderen.
  • De __init__ methode wordt gebruikt voor zware eenmalige installatie, zoals het laden van de grote netwerklijst. Dit werk vindt eenmaal per partitie van de invoertabel plaats.
  • De eval methode verwerkt elke rij en bevat de kernkoppelingslogica. Deze methode wordt precies één keer uitgevoerd voor elke rij in de invoerpartitie en elke uitvoering wordt uitgevoerd door het bijbehorende exemplaar van de IpMatcher UDTF-klasse voor die partitie.
  • De HANDLER component geeft de naam op van de Python-klasse die de UDTF-logica implementeert.
CREATE OR REPLACE TEMPORARY FUNCTION ip_cidr_matcher(t TABLE)
RETURNS TABLE(log_id STRING, ip_address STRING, network STRING, ip_version INT)
LANGUAGE PYTHON
HANDLER 'IpMatcher'
COMMENT 'Match IP addresses against a list of network CIDR blocks'
AS $$
class IpMatcher:
    def __init__(self):
        import ipaddress
        # Heavy initialization - load networks once per partition
        self.nets = []
        cidrs = ['192.168.0.0/16', '10.0.0.0/8', '172.16.0.0/12',
                 '2001:db8::/32', 'fe80::/10', '::1/128']
        for cidr in cidrs:
            self.nets.append(ipaddress.ip_network(cidr))

    def eval(self, row):
        import ipaddress
	    # Validate that required fields exist
        required_fields = ['log_id', 'ip_address']
        for field in required_fields:
            if field not in row:
                raise ValueError(f"Missing required field: {field}")
        try:
            ip = ipaddress.ip_address(row['ip_address'])
            for net in self.nets:
                if ip in net:
                    yield (row['log_id'], row['ip_address'], str(net), ip.version)
                    return
            yield (row['log_id'], row['ip_address'], None, ip.version)
        except ValueError:
            yield (row['log_id'], row['ip_address'], 'Invalid', None)
$$;

Nu deze ip_cidr_matcher is geregistreerd in Unity Catalog, roept u deze rechtstreeks vanuit SQL aan met behulp van de TABLE() syntaxis:

-- Process all IP addresses
SELECT
  *
FROM
  ip_cidr_matcher(t => TABLE(ip_logs))
ORDER BY
  log_id;
+--------+-------------------------------+-----------------+-------------+
| log_id | ip_address                    | network         | ip_version  |
+--------+-------------------------------+-----------------+-------------+
| log1   | 192.168.1.100                 | 192.168.0.0/16  | 4           |
| log2   | 10.0.0.5                      | 10.0.0.0/8      | 4           |
| log3   | 172.16.0.10                   | 172.16.0.0/12   | 4           |
| log4   | 8.8.8.8                       | null            | 4           |
| log5   | 2001:db8::1                   | 2001:db8::/32   | 6           |
| log6   | 2001:db8:85a3::8a2e:370:7334  | 2001:db8::/32   | 6           |
| log7   | fe80::1                       | fe80::/10       | 6           |
| log8   | ::1                           | ::1/128         | 6           |
| log9   | 2001:db8:1234:5678::1         | 2001:db8::/32   | 6           |
+--------+-------------------------------+-----------------+-------------+

Voorbeeld: Bijschriften voor batchafbeeldingen met behulp van Azure Databricks Vision-eindpunten

In dit voorbeeld wordt gedemonstreerd hoe batchgewijze beeldannotaties worden uitgevoerd met behulp van een Azure Databricks visionmodel via een serveer-eindpunt. Het toont het gebruik van terminate() voor batchverwerking en partitiegebaseerde uitvoering.

  1. Maak een tabel met openbare afbeeldings-URL's:

    CREATE OR REPLACE TEMPORARY VIEW sample_images AS
    VALUES
        ('https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg', 'scenery'),
        ('https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/Camponotus_flavomarginatus_ant.jpg/1024px-Camponotus_flavomarginatus_ant.jpg', 'animals'),
        ('https://upload.wikimedia.org/wikipedia/commons/thumb/1/15/Cat_August_2010-4.jpg/1200px-Cat_August_2010-4.jpg', 'animals'),
        ('https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/M101_hires_STScI-PRC2006-10a.jpg/1024px-M101_hires_STScI-PRC2006-10a.jpg', 'scenery')
    images(image_url, category);
    
  2. Maak een Unity Catalog Python UDTF om bijschriften voor afbeeldingen te genereren:

    1. Initialiseer de UDTF met de configuratie, inclusief batchgrootte, Azure Databricks API-token, vision-modeleindpunt en werkruimte-URL.
    2. Verzamel in de eval methode de afbeeldings-URL's in een buffer. Wanneer de buffer de batchgrootte bereikt, activeert u batchverwerking. Dit zorgt ervoor dat meerdere installatiekopieën samen worden verwerkt in één API-aanroep in plaats van afzonderlijke aanroepen per installatiekopieën.
    3. Download in de batchverwerkingsmethode alle gebufferde afbeeldingen, codeer ze als base64 en verzend ze naar één API-aanvraag naar Databricks VisionModel. Het model verwerkt alle afbeeldingen tegelijk en retourneert bijschriften voor de hele batch.
    4. De terminate methode wordt precies één keer uitgevoerd aan het einde van elke partitie. In de beëindigingsmethode verwerkt u alle resterende afbeeldingen in de buffer en levert u alle verzamelde bijschriften op als resultaten.

Opmerking

Vervang door <workspace-url> de werkelijke URL van uw Azure Databricks-werkruimte (https://your-workspace.cloud.databricks.com).

CREATE OR REPLACE TEMPORARY FUNCTION batch_inference_image_caption(data TABLE, api_token STRING)
RETURNS TABLE (caption STRING)
LANGUAGE PYTHON
HANDLER 'BatchInferenceImageCaption'
COMMENT 'batch image captioning by sending groups of image URLs to a Databricks vision endpoint and returning concise captions for each image.'
AS $$
class BatchInferenceImageCaption:
    def __init__(self):
        self.batch_size = 3
        self.vision_endpoint = "databricks-claude-sonnet-4-5"
        self.workspace_url = "<workspace-url>"
        self.image_buffer = []
        self.results = []

    def eval(self, row, api_token):
        self.image_buffer.append((str(row[0]), api_token))
        if len(self.image_buffer) >= self.batch_size:
            self._process_batch()

    def terminate(self):
        if self.image_buffer:
            self._process_batch()
        for caption in self.results:
            yield (caption,)

    def _process_batch(self):
        batch_data = self.image_buffer.copy()
        self.image_buffer.clear()

        import base64
        import httpx
        import requests

        # API request timeout in seconds
        api_timeout = 60
        # Maximum tokens for vision model response
        max_response_tokens = 300
        # Temperature controls randomness (lower = more deterministic)
        model_temperature = 0.3

        # create a batch for the images
        batch_images = []
        api_token = batch_data[0][1] if batch_data else None

        for image_url, _ in batch_data:
            image_response = httpx.get(image_url, timeout=15)
            image_data = base64.standard_b64encode(image_response.content).decode("utf-8")
            batch_images.append(image_data)

        content_items = [{
            "type": "text",
            "text": "Provide brief captions for these images, one per line."
        }]
        for img_data in batch_images:
            content_items.append({
                "type": "image_url",
                "image_url": {
                    "url": "data:image/jpeg;base64," + img_data
                }
            })

        payload = {
            "messages": [{
                "role": "user",
                "content": content_items
            }],
            "max_tokens": max_response_tokens,
            "temperature": model_temperature
        }

        response = requests.post(
            self.workspace_url + "/serving-endpoints/" +
            self.vision_endpoint + "/invocations",
            headers={
                'Authorization': 'Bearer ' + api_token,
                'Content-Type': 'application/json'
            },
            json=payload,
            timeout=api_timeout
        )

        result = response.json()
        batch_response = result['choices'][0]['message']['content'].strip()

        lines = batch_response.split('\n')
        captions = [line.strip() for line in lines if line.strip()]

        while len(captions) < len(batch_data):
            captions.append(batch_response)

        self.results.extend(captions[:len(batch_data)])
$$;

Om de batch image caption UDTF te gebruiken, roept u deze aan met behulp van de voorbeeldafbeeldingen-tabel:

Opmerking

Vervang your_secret_scope en api_token door het werkelijke geheime bereik en de sleutelnaam voor het Databricks API-token.

SELECT
  caption
FROM
  batch_inference_image_caption(
    data => TABLE(sample_images),
    api_token => secret('your_secret_scope', 'api_token')
  )
+---------------------------------------------------------------------------------------------------------------+
| caption                                                                                                       |
+---------------------------------------------------------------------------------------------------------------+
| Wooden boardwalk cutting through vibrant wetland grasses under blue skies                                     |
| Black ant in detailed macro photography standing on a textured surface                                        |
| Tabby cat lounging comfortably on a white ledge against a white wall                                          |
| Stunning spiral galaxy with bright central core and sweeping blue-white arms against the black void of space. |
+---------------------------------------------------------------------------------------------------------------+

U kunt ook categorie voor afbeeldingsbijschriften per categorie genereren:

SELECT
  *
FROM
  batch_inference_image_caption(
    TABLE(sample_images)
    PARTITION BY category ORDER BY (category),
    secret('your_secret_scope', 'api_token')
  )
+------------------------------------------------------------------------------------------------------+
| caption                                                                                              |
+------------------------------------------------------------------------------------------------------+
| Black ant in detailed macro photography standing on a textured surface                               |
| Stunning spiral galaxy with bright center and sweeping blue-tinged arms against the black of space.  |
| Tabby cat lounging comfortably on white ledge against white wall                                     |
| Wooden boardwalk cutting through lush wetland grasses under blue skies                               |
+------------------------------------------------------------------------------------------------------+

Voorbeeld: ROC-curve en AUC-berekening voor ML-modelevaluatie

In dit voorbeeld wordt aangetoond hoe ROC-curves (Receiver Operating Characteristic-curves) en scores voor de oppervlakte onder de curve (AUC) worden berekend voor de evaluatie van binaire classificatiemodellen met behulp van scikit-learn.

In dit voorbeeld ziet u verschillende belangrijke patronen:

  • Extern bibliotheekgebruik: Integreert scikit-learn voor ROC-curveberekening
  • Stateful aggregatie: Verzamelt voorspellingen van alle rijen voordat metrieken worden berekend
  • terminate() methodegebruik: verwerkt de volledige gegevensset en levert alleen resultaten op nadat alle rijen zijn geëvalueerd
  • Foutafhandeling: Controleert of de vereiste kolommen aanwezig zijn in de invoertabel

De UDTF verzamelt alle voorspellingen in het geheugen met behulp van de eval() methode, waarna de volledige ROC-curve in de terminate() methode wordt berekend en geretourneerd. Dit patroon is handig voor metrische gegevens waarvoor de volledige gegevensset voor berekening is vereist.

CREATE OR REPLACE TEMPORARY FUNCTION compute_roc_curve(t TABLE)
RETURNS TABLE (threshold DOUBLE, true_positive_rate DOUBLE, false_positive_rate DOUBLE, auc DOUBLE)
LANGUAGE PYTHON
HANDLER 'ROCCalculator'
COMMENT 'Compute ROC curve and AUC using scikit-learn'
AS $$
class ROCCalculator:
    def __init__(self):
        from sklearn import metrics
        self._roc_curve = metrics.roc_curve
        self._roc_auc_score = metrics.roc_auc_score

        self._true_labels = []
        self._predicted_scores = []

    def eval(self, row):
        if 'y_true' not in row or 'y_score' not in row:
            raise KeyError("Required columns 'y_true' and 'y_score' not found")

        true_label = row['y_true']
        predicted_score = row['y_score']

        label = float(true_label)
        self._true_labels.append(label)
        self._predicted_scores.append(float(predicted_score))

    def terminate(self):
        false_pos_rate, true_pos_rate, thresholds = self._roc_curve(
            self._true_labels,
            self._predicted_scores,
            drop_intermediate=False
        )

        auc_score = float(self._roc_auc_score(self._true_labels, self._predicted_scores))

        for threshold, tpr, fpr in zip(thresholds, true_pos_rate, false_pos_rate):
            yield float(threshold), float(tpr), float(fpr), auc_score
$$;

Voorbeeldgegevens voor binaire classificatie maken met voorspellingen:

CREATE OR REPLACE TEMPORARY VIEW binary_classification_data AS
SELECT *
FROM VALUES
  ( 1, 1.0, 0.95, 'high_confidence_positive'),
  ( 2, 1.0, 0.87, 'high_confidence_positive'),
  ( 3, 1.0, 0.82, 'medium_confidence_positive'),
  ( 4, 0.0, 0.78, 'false_positive'),
  ( 5, 1.0, 0.71, 'medium_confidence_positive'),
  ( 6, 0.0, 0.65, 'false_positive'),
  ( 7, 0.0, 0.58, 'true_negative'),
  ( 8, 1.0, 0.52, 'low_confidence_positive'),
  ( 9, 0.0, 0.45, 'true_negative'),
  (10, 0.0, 0.38, 'true_negative'),
  (11, 1.0, 0.31, 'low_confidence_positive'),
  (12, 0.0, 0.15, 'true_negative'),
  (13, 0.0, 0.08, 'high_confidence_negative'),
  (14, 0.0, 0.03, 'high_confidence_negative')
AS data(sample_id, y_true, y_score, prediction_type);

De ROC-curve en AUC berekenen:

SELECT
    threshold,
    true_positive_rate,
    false_positive_rate,
    auc
FROM compute_roc_curve(
  TABLE(
    SELECT y_true, y_score
    FROM binary_classification_data
    WHERE y_true IS NOT NULL AND y_score IS NOT NULL
    ORDER BY sample_id
  )
)
ORDER BY threshold DESC;
+-----------+---------------------+----------------------+-------+
| threshold | true_positive_rate  | false_positive_rate  | auc   |
+-----------+---------------------+----------------------+-------+
| 1.95      | 0.0                 | 0.0                  | 0.786 |
| 0.95      | 0.167               | 0.0                  | 0.786 |
| 0.87      | 0.333               | 0.0                  | 0.786 |
| 0.82      | 0.5                 | 0.0                  | 0.786 |
| 0.78      | 0.5                 | 0.125                | 0.786 |
| 0.71      | 0.667               | 0.125                | 0.786 |
| 0.65      | 0.667               | 0.25                 | 0.786 |
| 0.58      | 0.667               | 0.375                | 0.786 |
| 0.52      | 0.833               | 0.375                | 0.786 |
| 0.45      | 0.833               | 0.5                  | 0.786 |
| 0.38      | 0.833               | 0.625                | 0.786 |
| 0.31      | 1.0                 | 0.625                | 0.786 |
| 0.15      | 1.0                 | 0.75                 | 0.786 |
| 0.08      | 1.0                 | 0.875                | 0.786 |
| 0.03      | 1.0                 | 1.0                  | 0.786 |
+-----------+---------------------+----------------------+-------+

Beperkingen

De volgende beperkingen gelden voor Unity Catalog Python UDTFs:

Volgende stappen