# Language Services - Custom Text Classification and NER

**Last updated:** 2026-02
**Status:** GA
**Category:** Azure AI Services (Foundry Tools)

---

## Introduksjon

Custom Text Classification og Custom Named Entity Recognition (NER) er to spesialiserte funksjoner i Azure Language in Foundry Tools som gjør det mulig å bygge skreddersydde maskinlæringsmodeller for tekstanalyse. Tjenestene bruker machine learning-intelligens for å klassifisere dokumenter i egendefinerte kategorier eller for å trekke ut domene-spesifikke entities fra ustrukturert tekst.

Custom Text Classification støtter to typer prosjekter: **Single label classification** (ett dokument, én kategori) og **Multi label classification** (ett dokument, flere kategorier). Custom NER gjør det mulig å trene modeller for å gjenkjenne spesialiserte entities som ikke dekkes av standard NER-modellene, for eksempel juridiske termer, produktnavn eller finansielle data.

Begge tjenestene følger samme utviklingslivssyklus: definer schema → merk data → tren modell → evaluer ytelse → deploy → bruk i produksjon. De er tilgjengelige via Microsoft Foundry portal (ai.azure.com) og via REST API/SDK-er for Python, C#, Java og JavaScript. Kvaliteten på merkede data er den viktigste faktoren for modellytelse.

---

## Kjernekomponenter / Nøkkelegenskaper

### Custom Text Classification

| Komponent | Beskrivelse |
|-----------|-------------|
| **Single Label Classification** | Ett dokument får én kategori (f.eks. "Romance" eller "Comedy") |
| **Multi Label Classification** | Ett dokument kan få flere kategorier (f.eks. både "Romance" og "Comedy") |
| **Project** | Arbeidsområde for å bygge modeller basert på dine data |
| **Model** | Trent objekt som klassifiserer tekst basert på merkede data |
| **Class** | Brukerdefinert kategori som indikerer klassifisering av tekst |

### Custom Named Entity Recognition

| Komponent | Beskrivelse |
|-----------|-------------|
| **Entity** | Domene-spesifikk informasjon som skal trekkes ut (f.eks. kundenavn, lånebeløp) |
| **Project** | Arbeidsområde for å bygge entity extraction-modeller |
| **Model** | Trent objekt som ekstraherer entities fra tekst |
| **Labeling** | Prosess for å merke entities i treningsdata (presisjon, konsistens, komplett dekning) |

### Felles komponenter

| Komponent | Beskrivelse |
|-----------|-------------|
| **Training Set** | Data brukt til å trene modellen (anbefalt: 80%) |
| **Testing Set** | Blindsett for evaluering etter trening (anbefalt: 20%) |
| **Language Resource** | Azure-ressurs med managed identity og storage account-tilkobling |
| **Microsoft Foundry** | Webportal for visuell utvikling (ai.azure.com) |
| **REST API** | Programmatisk tilgang (Authoring API + Runtime API) |

### Evalueringsmetrikker

Både Custom Text Classification og Custom NER bruker samme metrikker:

| Metrikk | Formel | Hva den måler |
|---------|--------|---------------|
| **Precision** | `TP / (TP + FP)` | Hvor mange av de predikerte labels/entities er korrekte |
| **Recall** | `TP / (TP + FN)` | Hvor mange av de faktiske labels/entities ble fanget opp |
| **F1 Score** | `2 * P * R / (P + R)` | Balanse mellom precision og recall |

**Nivåer:** Metrikker beregnes både per class/entity (entity-level) og for hele modellen (model-level).

### Eksempel på API-bruk (Python)

**Custom Text Classification:**

```python
from azure.ai.textanalytics import TextAnalyticsClient
from azure.core.credentials import AzureKeyCredential

endpoint = os.environ["AZURE_LANGUAGE_ENDPOINT"]
key = os.environ["AZURE_LANGUAGE_KEY"]
project_name = "movie-classification"
deployment_name = "production"

client = TextAnalyticsClient(endpoint, AzureKeyCredential(key))

document = ["An epic space adventure with stunning visuals and emotional depth."]

poller = client.begin_single_label_classify(
    document,
    project_name=project_name,
    deployment_name=deployment_name
)

result = poller.result()
for doc, classification in zip(document, result):
    print(f"Category: {classification.classifications[0].category}")
    print(f"Confidence: {classification.classifications[0].confidence_score}")
```

**Custom NER:**

```python
from azure.ai.textanalytics import TextAnalyticsClient
from azure.core.credentials import AzureKeyCredential

endpoint = os.environ["AZURE_LANGUAGE_ENDPOINT"]
key = os.environ["AZURE_LANGUAGE_KEY"]
project_name = "loan-agreement-extraction"
deployment_name = "production"

client = TextAnalyticsClient(endpoint, AzureKeyCredential(key))

document = ["Borrower John Smith at 5678 Main Rd., City of Frederick."]

poller = client.begin_recognize_custom_entities(
    document,
    project_name=project_name,
    deployment_name=deployment_name
)

result = poller.result()
for doc_result in result:
    for entity in doc_result.entities:
        print(f"Entity: {entity.text}")
        print(f"Category: {entity.category}")
        print(f"Confidence: {entity.confidence_score}")
```

---

## Arkitekturmønstre

### Mønster 1: Automatisk E-post/Ticket Triage

**Bruksområde:** Support-sentre som mottar høyt volum av ustrukturerte henvendelser.

**Arkitektur:**
- Azure Logic Apps eller Power Automate mottar e-post/tickets
- Custom Text Classification API klassifiserer innholdet
- Automatisk routing til riktig avdeling basert på predikert kategori

**Fordeler:**
- ✅ Reduserer manuell sortering med 70-90%
- ✅ Raskere responstid for kritiske saker
- ✅ Konsistent prioritering

**Ulemper:**
- ❌ Krever godt merket treningsdata fra eksisterende tickets
- ❌ Må re-trenes når nye kategorier introduseres
- ❌ Kan feile på tvetydige saker (human-in-the-loop anbefales)

---

### Mønster 2: Dokumentinnsikt for Knowledge Mining

**Bruksområde:** Forbedre søkekvalitet i dokumentrepositorier (kontrakter, forskningsrapporter, etc.).

**Arkitektur:**
- Azure AI Search indexer crawl-dokumenter
- Custom NER API ekstraherer domene-spesifikke entities (produktnavn, lokasjoner, tall)
- Entities berike Azure AI Search-indeksen
- Brukere søker med facets basert på entities

**Fordeler:**
- ✅ Semantisk rik søkeopplevelse
- ✅ Facettering på business-spesifikke termer
- ✅ Kobler Custom NER med Azure AI Search seamless

**Ulemper:**
- ❌ Indexing-latency øker med NER-ekstraksjon
- ❌ Cost per dokument kan bli høy ved store volumer
- ❌ Krever re-indexing ved modell-oppdatering

---

### Mønster 3: Compliance og Audit Automation

**Bruksområde:** Finansielle institusjoner som skal automatisere gjennomgang av låneavtaler eller juridiske dokumenter.

**Arkitektur:**
- Custom NER ekstraherer kritiske felt (låntaker, beløp, dato, rentesats)
- Custom Text Classification identifiserer dokumenttype (kontrakt, addendum, søknad)
- Downstream-systemer validerer mot forretningsregler
- Alert sendes ved non-compliance

**Fordeler:**
- ✅ Reduserer manuell gjennomgang fra dager til minutter
- ✅ Konsistent compliance-sjekk
- ✅ Auditlog for alle ekstrakte entities

**Ulemper:**
- ❌ Krever høy precision (false positives kan gi feil beslutninger)
- ❌ Juridisk ansvar ved feil-ekstraksjon (human review påkrevd)
- ❌ Domene-spesifikk terminologi krever kontinuerlig merking

---

## Beslutningsveiledning

### Når bruke Custom Text Classification

| Scenario | Anbefaling |
|----------|------------|
| Klassifisere e-post/tickets i forhåndsdefinerte kategorier | ✅ **Single Label** (én avdeling per ticket) |
| Tagge artikler med flere emner | ✅ **Multi Label** (samme artikkel kan være både "AI" og "Healthcare") |
| Sentiment-analyse på norske tekster | ⚠️ Vurder standard Sentiment Analysis først (støtter norsk), bruk custom hvis domene-spesifikk sentiment trengs |
| Klassifisering med <50 merkede eksempler per kategori | ❌ For lite data, modellen vil ha lav ytelse |

### Når bruke Custom NER

| Scenario | Anbefaling |
|----------|------------|
| Trekke ut standard entities (person, lokasjon, org) | ⚠️ Bruk standard NER først (dekker 18+ entity-typer out-of-the-box) |
| Trekke ut domene-spesifikke entities (produktkoder, juridiske termer) | ✅ Custom NER er riktig verktøy |
| Ekstraksjon fra strukturerte former (tabeller, skjemaer) | ⚠️ Vurder Document Intelligence (Form Recognizer) først |
| Ekstraksjon med <15 merkede eksempler per entity | ❌ For lite data, modellen vil ha lav recall |

### Røde flagg

| Problem | Symptom | Løsning |
|---------|---------|---------|
| **Ambiguity** | Flere kategorier/entities overlapper sterkt | Merger kategorier eller legg til flere treningseksempler for skille |
| **Imbalanced Data** | En kategori/entity har 90% av dataene | Oversampling av minoritetsklasser eller undersampling av majoritetsklasse |
| **Test Set Leakage** | Test set performance >> training set performance | Sjekk at test set ikke ble brukt i trening (data leakage) |
| **Overfitting** | Modellen performerer bra på treningsdata men dårlig på nye data | Legg til mer variasjon i treningsdata |
| **Inconsistent Labeling** | Samme tekst har forskjellige labels i dataset | Gjennomgå og standardiser labeling-prosessen |

### Vanlige feil

- ❌ **Trene uten data split:** Alltid bruk 80/20 split (training/testing) for realistisk evaluering
- ❌ **Ignorere confusion matrix:** Confusion matrix viser hvilke kategorier/entities som forveksles (kritisk for forbedring)
- ❌ **Deploy uten evaluering:** Sjekk alltid precision/recall/F1 før deployment
- ❌ **Glemme re-training:** Modeller degraderer over tid når domenet endrer seg

---

## Integrasjon med Microsoft-stakken

### Azure AI Foundry

Custom Text Classification og Custom NER er **Foundry Tools** — de er tilgjengelige både i stand-alone Language Studio og i Azure AI Foundry portal. I Foundry kan du:

- Opprette prosjekt fra unified interface (ai.azure.com)
- Kombinere med andre Azure AI-tjenester i samme workflow
- Bruke Language resource fra Foundry Hub (samme credentials)

**Viktig:** Language resource må ha **Custom text classification & custom named entity recognition** feature enabled (krever storage account-tilkobling).

### Power Platform

| Tjente | Integrasjonsmønster |
|---------|---------------------|
| **Power Automate** | Custom connector til Language REST API → klassifiser e-post/Teams-meldinger → route flow |
| **Power Apps** | Kall Language API fra Power Apps via HTTP connector → vis predikerte kategorier/entities i app |
| **AI Builder** | Bruk Document Intelligence for strukturerte skjemaer, Custom NER for ustrukturerte tekster |

### Microsoft 365 Copilot

Custom Text Classification kan **ikke** integreres direkte i M365 Copilot (Copilot bruker forhåndstrente modeller). Men du kan:

- Bygge egen **Copilot Studio** bot som kaller Custom Text Classification API
- Bruke Power Automate-flow trigget av Copilot

### Azure AI Search

| Integrasjonspunkt | Beskrivelse |
|-------------------|-------------|
| **Indexing Enrichment** | Bruk Custom NER som custom skill i Azure AI Search enrichment pipeline |
| **Facets** | Entities ekstrahert av Custom NER blir facets i søket |
| **Query Expansion** | Bruk Custom Text Classification til å forbedre query understanding |

**Eksempel:** Azure AI Search → Custom Skill (Custom NER) → Extraherer "ProductCode" entities → Legger til i index → Brukere filtrerer på produktkoder.

### Copilot Studio

Bruk Custom Text Classification/NER i Copilot Studio via Power Automate-flow:

1. Bruker sender melding til bot
2. Bot trigger Power Automate-flow
3. Flow kaller Language API (Custom Classification/NER)
4. Returner entities/kategorier til bot
5. Bot bruker informasjonen til å gi relevant svar

---

## Offentlig sektor (Norge)

### GDPR og datasuverenitet

| Krav | Custom Text Classification/NER Compliance |
|------|-------------------------------------------|
| **Personopplysninger i treningsdata** | ⚠️ Treningsdata lagres i Azure Storage Account (må være EU-region for GDPR-compliance) |
| **Personopplysninger i runtime-kall** | ⚠️ Tekst sendt til API logger ikke, men respons caches i 15 min (kan deaktiveres med `loggingOptOut: true`) |
| **Data Residency** | ✅ Bruk Language resource i **West Europe** eller **North Europe** for EU-data residency |
| **Right to be Forgotten** | ⚠️ Treningsdata må slettes manuelt fra Storage Account (Language tjenesten har ikke innebygd RTBF) |

**Anbefaling for offentlig sektor:**
- Bruk **West Europe** region for Language resource og Storage Account
- Anonymiser treningsdata før merking (erstatt personnavn med placeholders)
- Implementer data retention policy på Storage Account (auto-delete etter X måneder)

### Schrems II og dataoverføring

Custom Text Classification/NER **har ikke** data transfer til USA hvis du:
- ✅ Bruker EU-region (West Europe/North Europe)
- ✅ Kobler Language resource til Storage Account i samme EU-region
- ✅ Ikke bruker globale endpoints (bruk regional endpoint: `https://<your-subdomain>.cognitiveservices.azure.com`)

⚠️ **Viktig:** Microsoft kan fortsatt ha support-tilgang fra USA. For sensitive data, vurder **Customer Lockbox** (krever Enterprise Agreement).

### AI Act (EU)

Custom Text Classification/NER faller typisk under **"Limited Risk"** i AI Act (transparent information påkrevd). Men ved bruk i:

- **High-risk:** Rekruttering, kredittscoring, offentlige ytelser → Krever AI Act compliance (risikovurdering, mennesketilsyn)
- **Generelt:** Klar informasjon til bruker om at AI brukes, mennesketilsyn ved kritiske beslutninger

**Tiltak:**
- Dokumenter modellkvalitet (precision/recall/F1)
- Implementer human-in-the-loop for kritiske beslutninger
- Logg alle prediksjoner for audit-trail

### Forvaltningsloven og saksbehandling

Ved bruk i offentlig saksbehandling:

- ✅ **Kan brukes** til å kategorisere innkommende saker (triage)
- ⚠️ **Krever mennesketilsyn** før vedtak baseres på klassifisering
- ✅ **Anbefales** å gi innsyn i hvordan kategorisering skjedde (forklaring av beslutning)

**Eksempel:** NAV kan bruke Custom Text Classification til å klassifisere søknader, men en saksbehandler må alltid godkjenne før vedtak fattes.

---

## Kostnad og lisensiering

### Prismodell (Custom Text Classification)

| Komponent | Pris (per 1000 text records) |
|-----------|------------------------------|
| **Training** | Gratis (men storage account koster) |
| **Prediction API** | $1-2 USD per 1000 tekster (avhengig av region og commitment tier) |
| **Storage (treningsdata)** | Standard Azure Storage pricing (~$0.02 USD per GB/måned) |

### Prismodell (Custom NER)

| Komponent | Pris (per 1000 text records) |
|-----------|------------------------------|
| **Training** | Gratis (men storage account koster) |
| **Prediction API** | $1-2 USD per 1000 tekster (avhengig av region og commitment tier) |
| **Storage (treningsdata)** | Standard Azure Storage pricing (~$0.02 USD per GB/måned) |

**Viktig:** "Text record" = inntil 1000 characters. Lengre tekster teller som flere records (f.eks. 2500 characters = 3 records).

### Free Tier (F0)

| Feature | Gratis Tier Limit |
|---------|-------------------|
| **Prediction API** | 5000 text records per måned |
| **Training** | Ubegrenset (men storage account må betales) |
| **Deployment** | Max 1 deployment per prosjekt |

**Anbefaling:** Bruk F0 for utvikling/testing, oppgrader til Standard (S) for produksjon.

### Kostoptimaliseringstips

| Teknikk | Besparelse |
|---------|------------|
| **Batch API** | Send flere dokumenter i samme API-kall (opp til 10 dokumenter per request) |
| **Commitment Tier** | Betal forhåndsbetalt for 100K-1M text records per måned (10-30% rabatt) |
| **Caching** | Implementer egen caching-layer for repeterende tekster (unngå unødvendige API-kall) |
| **Regional pricing** | West Europe er billigere enn US East (sjekk pricing calculator) |

### Eksempel TCO (Total Cost of Ownership)

**Scenario:** 100 000 tickets per måned, hver 500 characters (= 0.5 text records per ticket)

| Komponent | Beregning | Kostnad (USD/måned) |
|-----------|-----------|---------------------|
| Prediction API | 50 000 text records × $2 / 1000 | $100 |
| Storage (100 GB treningsdata) | 100 GB × $0.02 | $2 |
| **Total** | | **$102/måned** |

**Sammenligning:** Manuell sortering av 100 000 tickets × 2 min per ticket × 400 NOK/time = ~1.3M NOK/måned. ROI er betydelig.

---

## For arkitekten (Cosmo)

### Spørsmål å stille kunden

1. **Datakvalitet:** Hvor mange merkede eksempler har du per kategori/entity? (Anbefalt minimum: 50-100 per kategori, 15+ per entity)
2. **Ambiguity:** Er kategoriene/entities klart separerbare, eller er det overlapp? (Overlapp krever mer data)
3. **Multilingual:** Trenger du støtte for flere språk? (Custom Classification støtter 100+ språk, men precision faller ved språk-mix)
4. **Real-time vs Batch:** Trenger du real-time klassifisering/ekstraksjon, eller kan du prosessere i batch? (Batch er billigere)
5. **Human-in-the-loop:** Vil dere alltid ha mennesketilsyn, eller er full-automatisering målet? (Påvirker arkitektur)
6. **Data residency:** Må data forbli i Norge/EU? (Påvirker region-valg og compliance)
7. **Existing system:** Hvilke systemer skal integreres? (Azure AI Search, Power Automate, Copilot Studio?)
8. **Performance requirements:** Hva er akseptabel precision/recall? (F1 score under 0.7 betyr modellen trenger mer arbeid)

### Fallgruver å unngå

| Fallgruve | Konsekvens | Mitigering |
|-----------|------------|------------|
| **Starter med for få data** | Modell med F1 score <0.5 (ubrukelig) | Samle minst 50-100 eksempler per kategori før trening |
| **Hopper over data splitting** | Overfitting, overvurdert performance | Alltid bruk 80/20 split, helst manuell split for konsistens |
| **Ignorerer confusion matrix** | Forstår ikke hvilke kategorier/entities som forveksles | Alltid analyser confusion matrix etter trening |
| **Deployer uten testing i produksjonslignende miljø** | Modellen fungerer dårlig på real-world data | Test på data fra produksjon (ikke bare test set) |
| **Glemmer re-training** | Modell degraderer over tid | Sett opp quarterly re-training med nye data |
| **Overfører treningsdata til USA** | GDPR-brudd | Bruk West Europe region og verifiser data residency |
| **Antar at standard NER dekker behov** | Bygger custom NER unødvendig | Test standard NER først (dekker person, location, org, quantity, datetime, etc.) |

### Anbefalinger per modenhetsnivå

#### Nivå 1: Proof of Concept

- ✅ Bruk Language Studio (webportal) for merking og trening
- ✅ Start med **Single Label Classification** eller **Custom NER** (ikke begge samtidig)
- ✅ Bruk F0 Free Tier
- ✅ 50-100 merkede dokumenter totalt (minimum viable dataset)
- ✅ Manuell data split (80/20) for konsistent evaluering
- ⚠️ Aksepter F1 score ned til 0.6 (POC-nivå)

#### Nivå 2: Pilot i produksjon

- ✅ Flytt til Standard Tier (S) for flere deployments
- ✅ Øk til 200-500 merkede dokumenter per kategori/entity
- ✅ Implementer REST API-integrasjon (ikke webportal)
- ✅ Legg til human-in-the-loop for kritiske saker
- ✅ Sett opp monitoring (Azure Monitor + Application Insights)
- ✅ Mål F1 score >0.75 (pilot-nivå)

#### Nivå 3: Full produksjon

- ✅ 500-1000+ merkede dokumenter per kategori/entity
- ✅ Kontinuerlig re-training (quarterly eller ved performance drop)
- ✅ A/B-testing av modellversjoner før deployment
- ✅ Implementer active learning (marker nye eksempler basert på lav confidence score)
- ✅ Commitment Tier for kostnadsoptimalisering
- ✅ Mål F1 score >0.85 (produksjon-nivå)
- ✅ Dokumenter modell i ADR (Architecture Decision Record)

### Når **ikke** bruke Custom Text Classification/NER

| Scenario | Alternativ |
|----------|----------|
| Standard sentiment-analyse (positiv/negativ/nøytral) | Standard Sentiment Analysis (dekker 100+ språk out-of-the-box) |
| Standard entity extraction (person, lokasjon, org) | Standard NER (dekker 18+ entity typer) |
| Klassifisering med <50 merkede eksempler | Pre-trained models (f.eks. GPT-4 med zero-shot classification) |
| Strukturerte skjemaer (tabeller, checkboxes) | Document Intelligence (Form Recognizer) |
| Conversation understanding (chatbot intents) | Conversational Language Understanding (CLU) |

---

## Kilder og verifisering

### Microsoft Learn-dokumentasjon (Verified via MCP)

| URL | Beskrivelse |
|-----|-------------|
| [Custom Text Classification Overview](https://learn.microsoft.com/en-us/azure/ai-services/language-service/custom-text-classification/overview) | Hovedoversikt, project lifecycle, eksempel-scenarios |
| [Custom NER Overview](https://learn.microsoft.com/en-us/azure/ai-services/language-service/custom-named-entity-recognition/overview) | Hovedoversikt, project lifecycle, eksempel-scenarios |
| [Custom Text Classification Quickstart](https://learn.microsoft.com/en-us/azure/ai-services/language-service/custom-text-classification/quickstart) | Steg-for-steg guide for å opprette første prosjekt |
| [Custom NER Quickstart](https://learn.microsoft.com/en-us/azure/ai-services/language-service/custom-named-entity-recognition/quickstart) | Steg-for-steg guide for å opprette første prosjekt |
| [Evaluation Metrics for Custom Text Classification](https://learn.microsoft.com/en-us/azure/ai-services/language-service/custom-text-classification/concepts/evaluation-metrics) | Precision, recall, F1 score, confusion matrix |
| [Evaluation Metrics for Custom NER](https://learn.microsoft.com/en-us/azure/ai-services/language-service/custom-named-entity-recognition/concepts/evaluation-metrics) | Precision, recall, F1 score, entity-level vs model-level |
| [How to Train a Model (Custom Text Classification)](https://learn.microsoft.com/en-us/azure/ai-services/language-service/custom-text-classification/how-to/train-model) | Data splitting, training API, status polling |
| [How to Create Custom NER Project](https://learn.microsoft.com/en-us/azure/ai-services/language-service/custom-named-entity-recognition/how-to/create-project) | Resource setup, storage account, identity management |
| [Language Support for Custom Text Classification](https://learn.microsoft.com/en-us/azure/ai-services/language-service/custom-text-classification/language-support) | 100+ språk, multilingual-funksjonalitet |

### Konfidensnivå per seksjon

| Seksjon | Konfidensnivå | Kilde |
|---------|---------------|-------|
| **Introduksjon** | ✅ Verified | Microsoft Learn (MCP fetch) |
| **Kjernekomponenter** | ✅ Verified | Microsoft Learn + Code Samples (MCP) |
| **Arkitekturmønstre** | ⚠️ Baseline | Utledet fra use cases i Microsoft Learn + modellkunnskap |
| **Beslutningsveiledning** | ⚠️ Baseline | Best practices fra Microsoft Learn + modellkunnskap |
| **Integrasjon** | ✅ Verified | Microsoft Learn (Foundry, Azure AI Search integration) |
| **Offentlig sektor** | ⚠️ Baseline | GDPR/AI Act-kunnskap + Azure compliance docs (ikke MCP-verifisert) |
| **Kostnad** | ⚠️ Baseline | Prismodell fra Azure Pricing Calculator (per 2024 data, ikke 2026-verifisert) |
| **For arkitekten** | ⚠️ Baseline | Best practices syntetisert fra Microsoft Learn + erfaring |

**Viktig:** Prismodell og compliance-detaljer bør verifiseres mot offisiell Azure Pricing Calculator og Microsoft Trust Center før kundeengasjement.
