Steg 9 (R4): unified migrate-corpus.mjs --write over engineering/governance/ infrastructure/security. 327 filer mutert, verified=null, prosa byte-identisk (fra første ## seksjon), advisor urørt (0 endringer). To applier-fixes oppdaget under kjøring (TDD, RED→GREEN): - insertHeaderFields: anker faller nå tilbake når en meta-linje selv passerer 500B (2 filer pakket et avsnitt i **Status:** → Type/Source landet utenfor scan-vinduet, applierens post-write-assertion fanget + restaurerte). - normalizeStaleVerified: fjerner nå ALLE stale non-date **Verified:** i 500B-vinduet, inkl. stray body-dup rett under --- (9 mlops-genaiops-filer var ellers falskt "verified"/fresh, droppet fra worklist). Operatør-godkjent utvidelse av carve-out; kun stray metadata-linjer, aldri prosa. test-transform-criterion: precondition oppdatert til post-migrasjons-sannhet (fila bærer nå Source). Suite 728/728 grønn.
17 KiB
Feature Stores and Feature Engineering
Last updated: 2026-06-24 Status: GA Category: Data Engineering for AI Type: reference Source: https://learn.microsoft.com/azure/machine-learning/concept-what-is-managed-feature-store
Innhold
- Introduksjon
- Feature Definition and Storage in Silver Layer
- Point-in-Time Lookups for Training
- Feature Freshness and Refresh Cadences
- Data Wrangler for Exploratory Feature Engineering
- Feature Monitoring and Drift Detection
- Referanser
- For Cosmo
Introduksjon
Feature stores er et sentralt mønster i moderne MLOps som løser problemet med feature-gjenbruk, konsistens mellom trening og inferens, og operasjonalisering av feature-pipelines. Azure Machine Learning Managed Feature Store og Microsoft Fabric Data Science gir en komplett plattform for å definere, materialisere, dele og overvåke features på tvers av ML-prosjekter.
For norsk offentlig sektor innebærer feature store-tilnærmingen at data science-team kan dele beregninger på tvers av prosjekter -- for eksempel kan trafikkdata-features brukes både for ulykkesprediksjonsmodeller og køvarslingsmodeller uten redundant feature engineering. Dette reduserer kostnader, forbedrer konsistens og forkorter tid fra eksperimentering til produksjon.
Denne referansen dekker feature-definisjon og lagring, point-in-time lookups for trening, feature-oppdateringsstrategier, Data Wrangler for utforskende feature engineering, og overvåking av feature-kvalitet og drift.
Feature Definition and Storage in Silver Layer
Feature Store Arkitektur
┌──────────────────────────────────────────────────────────────┐
│ Azure ML Managed Feature Store │
│ ┌──────────────┐ ┌──────────────────┐ ┌───────────────┐ │
│ │ Feature Set │ │ Materialization │ │ Feature │ │
│ │ Specification│ │ Store (ADLS Gen2) │ │ Retrieval │ │
│ │ │ │ Offline + Online │ │ Component │ │
│ └──────┬───────┘ └────────┬─────────┘ └───────┬───────┘ │
│ │ │ │ │
│ └───────────────────┴─────────────────────┘ │
└──────────────────────────────┬───────────────────────────────┘
│
┌──────────────────────────────▼───────────────────────────────┐
│ Microsoft Fabric │
│ ┌──────────┐ ┌──────────────┐ ┌────────────────────────┐ │
│ │ Bronze │ │ Silver Layer │ │ Gold Layer │ │
│ │ (raw) │──│ (features) │──│ (training datasets) │ │
│ └──────────┘ └──────────────┘ └────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
Feature Set Specification
En feature set-spesifikasjon definerer features og valgfri transformasjonslogikk:
# Feature set specification (YAML)
# feature_set_spec/transactions/spec.yaml
"""
name: transactions
version: "1"
description: "Customer transaction features"
entities:
- name: customer
version: "1"
join_keys:
- customer_id
source:
type: parquet
path: "abfss://silver@onelake.dfs.fabric.microsoft.com/transactions"
timestamp_column: transaction_date
features:
- name: transaction_7day_count
type: integer
description: "Number of transactions in last 7 days"
- name: transaction_7day_sum
type: double
description: "Total transaction amount in last 7 days"
- name: transaction_30day_avg
type: double
description: "Average transaction amount in last 30 days"
"""
Feature Transformations med PySpark
from pyspark.sql import functions as F
from pyspark.sql.window import Window
# Kildedataer fra Silver layer
transactions = spark.read.format("delta").table("silver.transactions")
# Definer vindus-spesifikasjoner
window_7d = (
Window
.partitionBy("customer_id")
.orderBy(F.col("transaction_date").cast("long"))
.rangeBetween(-7 * 86400, 0) # 7 dager i sekunder
)
window_30d = (
Window
.partitionBy("customer_id")
.orderBy(F.col("transaction_date").cast("long"))
.rangeBetween(-30 * 86400, 0)
)
# Beregn features
customer_features = (
transactions
.withColumn("txn_7d_count", F.count("*").over(window_7d))
.withColumn("txn_7d_sum", F.sum("amount").over(window_7d))
.withColumn("txn_30d_avg", F.avg("amount").over(window_30d))
.withColumn("txn_30d_max", F.max("amount").over(window_30d))
.withColumn("days_since_last_txn",
F.datediff(F.current_date(), F.max("transaction_date").over(
Window.partitionBy("customer_id"))))
)
# Lagre features i Silver layer
customer_features.write.format("delta") \
.mode("overwrite") \
.saveAsTable("silver.customer_transaction_features")
Feature-lagring i Medallion Architecture
| Lag | Innhold | Oppdateringsfrekvens |
|---|---|---|
| Bronze | Råtransaksjoner fra Dataverse/kildesystemer | Sanntid / daglig |
| Silver | Feature-beregninger (aggregater, vindus-funksjoner) | Daglig / per time |
| Gold | Ferdige treningsdatasett (features + labels) | Ved behov |
| Feature Store | Registrerte, versjonerte features | Materialisert etter plan |
Point-in-Time Lookups for Training
Temporal Joins (tidsreise-joiner)
Point-in-time lookups er kritisk for å unngå datalekasje i ML-trening:
# FEIL: Standard join inkluderer fremtidige data (data leakage!)
# features_at_prediction_time = features.join(labels, "customer_id")
# RIKTIG: Point-in-time join
from pyspark.sql.functions import col
# Observations: tidspunkter der vi vil ha features
observations = spark.createDataFrame([
("C001", "2026-01-15"),
("C002", "2026-01-20"),
("C003", "2026-02-01")
], ["customer_id", "observation_date"])
# Features: tidsseriedata
features = spark.read.format("delta").table("silver.customer_transaction_features")
# Point-in-time join: hent features som var gjeldende PÅ observation_date
pit_features = (
observations.alias("obs")
.join(
features.alias("feat"),
(col("obs.customer_id") == col("feat.customer_id")) &
(col("feat.feature_date") <= col("obs.observation_date")),
"left"
)
.withColumn("rank", F.row_number().over(
Window
.partitionBy("obs.customer_id", "obs.observation_date")
.orderBy(F.desc("feat.feature_date"))
))
.filter(col("rank") == 1) # Siste feature-verdi FØR observation_date
.drop("rank")
)
Azure ML Feature Retrieval Component
# Deklarativ feature retrieval i Azure ML pipeline
from azure.ai.ml import MLClient
from azure.ai.ml.entities import FeatureRetrievalSpec
# Definer feature retrieval spec
feature_retrieval_spec = FeatureRetrievalSpec(
feature_store_name="my-feature-store",
features=[
{
"feature_set": "transactions:1",
"features": ["txn_7d_count", "txn_7d_sum", "txn_30d_avg"]
},
{
"feature_set": "demographics:1",
"features": ["age_group", "region", "income_band"]
}
]
)
# Feature retrieval støtter automatisk point-in-time joins
# basert på timestamp-kolonne i feature set specification
Feature Freshness and Refresh Cadences
Materialiseringsstrategi
| Feature-type | Oppdateringsfrekvens | Materialiseringsmetode |
|---|---|---|
| Statiske (demografi) | Ukentlig / månedlig | Batch materialisering |
| Langsom endring (score) | Daglig | Scheduled materialisering |
| Rask endring (transaksjoner) | Per time / sanntid | Streaming + backfill |
| Sanntid (lokasjon) | Kontinuerlig | Online store (Redis) |
Materialiserings-oppsett
from azure.ai.ml.entities import (
MaterializationSettings,
MaterializationComputeResource,
RecurrenceTrigger
)
# Konfigurer materialisering for en feature set
materialization = MaterializationSettings(
schedule=RecurrenceTrigger(
interval=1,
frequency="Day",
time_of_day="02:00" # Kjør kl 02:00 UTC
),
resource=MaterializationComputeResource(
instance_type="standard_e4s_v3"
),
spark_configuration={
"spark.driver.cores": 4,
"spark.driver.memory": "36g",
"spark.executor.cores": 4,
"spark.executor.memory": "36g"
}
)
# Backfill for historisk data
from azure.ai.ml import MLClient
fs_client = MLClient(credential, subscription_id, resource_group, feature_store_name)
poller = fs_client.feature_sets.begin_backfill(
name="transactions",
version="1",
feature_window_start_time="2025-01-01T00:00:00Z",
feature_window_end_time="2026-02-11T00:00:00Z",
data_status=["None", "Incomplete"]
)
# Stream jobb-logger
fs_client.jobs.stream(poller.result().job_ids[0])
Online vs. Offline Materialization
| Aspekt | Offline Store (ADLS Gen2) | Online Store (Redis) |
|---|---|---|
| Bruksområde | Trening, batch-inferens | Real-time inferens |
| Latens | Sekunder-minutter | Millisekunder |
| Volum | Ubegrenset | Begrenset av Redis-minne |
| Kostnad | Lav (lagring) | Høyere (compute) |
| Format | Delta/Parquet | Key-value |
Data Wrangler for Exploratory Feature Engineering
Data Wrangler i Fabric
Data Wrangler er et notebook-basert verktøy for visuell datautforsking og feature engineering:
# Steg 1: Last data i Notebook
import pandas as pd
df = spark.read.format("delta").table("silver.customer_data").toPandas()
# Steg 2: Start Data Wrangler
# Klikk "Data" > "Launch Data Wrangler" i Notebook-menyen
# Velg DataFrame "df"
# Steg 3: Data Wrangler UI tilbyr:
# - Grid-visning med statistikk per kolonne
# - Innebygde visualiseringer (histogrammer, scatter plots)
# - Over 300 transformasjoner
# - AI-drevne forslag (PROSE)
# - Copilot for naturlig språk → kode
# Steg 4: Eksporter kode tilbake til Notebook
Vanlige feature engineering-operasjoner i Data Wrangler
| Operasjon | Eksempel | Autogenerert kode |
|---|---|---|
| One-hot encoding | Kategoriske variabler | pd.get_dummies(df, columns=[...]) |
| Binning | Aldersgrupper | pd.cut(df['age'], bins=[...]) |
| Missing values | Imputering | df['col'].fillna(df['col'].median()) |
| Standardisering | Z-score | (df['col'] - mean) / std |
| Feature crossing | Kombinasjoner | df['new'] = df['a'] * df['b'] |
| Dato-features | Dag, uke, måned | df['month'] = df['date'].dt.month |
PySpark Feature Engineering Templates
from pyspark.sql import functions as F
from pyspark.ml.feature import VectorAssembler, StandardScaler, StringIndexer
# Kategorisk encoding
indexer = StringIndexer(inputCol="region", outputCol="region_index")
# Numerisk standardisering
assembler = VectorAssembler(
inputCols=["age", "income", "txn_count"],
outputCol="features_raw"
)
scaler = StandardScaler(
inputCol="features_raw",
outputCol="features_scaled",
withStd=True,
withMean=True
)
# Dato-baserte features
df_features = (
df
.withColumn("day_of_week", F.dayofweek("event_date"))
.withColumn("month", F.month("event_date"))
.withColumn("is_weekend", F.when(
F.dayofweek("event_date").isin([1, 7]), 1).otherwise(0))
.withColumn("hour_of_day", F.hour("event_timestamp"))
.withColumn("days_since_registration",
F.datediff(F.current_date(), "registration_date"))
)
Feature Monitoring and Drift Detection
Feature Drift-typer
| Drift-type | Beskrivelse | Deteksjonsmetode |
|---|---|---|
| Data drift | Endring i feature-distribusjon | KS-test, PSI |
| Concept drift | Endring i forholdet mellom features og target | Modell-ytelse over tid |
| Schema drift | Endring i datastruktur | Schema-validering |
| Freshness drift | Data er ikke oppdatert | Timestamp-sjekk |
Monitoring i Azure ML Feature Store
from azure.ai.ml.entities import (
FeatureSetMonitoringSpec,
MonitorSignal
)
# Konfigurer feature-monitoring
monitoring = FeatureSetMonitoringSpec(
signal=MonitorSignal(
feature_data_type_override={
"txn_7d_count": "numerical",
"region": "categorical"
},
metric_thresholds={
"numerical": {
"jensen_shannon_distance": 0.1,
"population_stability_index": 0.2
},
"categorical": {
"jensen_shannon_distance": 0.1
}
}
),
notification_emails=["team@example.no"]
)
Manuell drift-deteksjon i Fabric Notebook
from scipy.stats import ks_2samp
import numpy as np
def detect_feature_drift(reference_df, current_df, features, threshold=0.05):
"""Detekter feature drift mellom referanse- og nåværende data."""
drift_report = {}
for feature in features:
ref_values = reference_df[feature].dropna().values
curr_values = current_df[feature].dropna().values
# Kolmogorov-Smirnov test
stat, p_value = ks_2samp(ref_values, curr_values)
# Population Stability Index (PSI)
psi = calculate_psi(ref_values, curr_values, buckets=10)
drift_report[feature] = {
"ks_statistic": round(stat, 4),
"ks_p_value": round(p_value, 4),
"psi": round(psi, 4),
"drifted": p_value < threshold or psi > 0.2
}
return drift_report
def calculate_psi(reference, current, buckets=10):
"""Beregn Population Stability Index."""
breakpoints = np.linspace(
min(reference.min(), current.min()),
max(reference.max(), current.max()),
buckets + 1
)
ref_counts = np.histogram(reference, breakpoints)[0] / len(reference)
curr_counts = np.histogram(current, breakpoints)[0] / len(current)
# Unngå log(0)
ref_counts = np.clip(ref_counts, 0.001, None)
curr_counts = np.clip(curr_counts, 0.001, None)
psi = np.sum((curr_counts - ref_counts) * np.log(curr_counts / ref_counts))
return psi
Referanser
- What is managed feature store? -- Konseptoversikt
- What is a Feature Store? (AI Playbook) -- Arkitektur og implementasjon
- Tutorial 1: Develop and register a feature set -- Hands-on tutorial
- Tutorial 4: Enable online materialization -- Online feature serving
- Manage access control for managed feature store -- RBAC og sikkerhet
- Accelerate data prep with Data Wrangler -- Data Wrangler guide
- Automated ML in Fabric -- AutoML med feature engineering
For Cosmo
- Bruk denne referansen når brukeren planlegger ML-infrastruktur, trenger feature-gjenbruk på tvers av prosjekter, eller ønsker å operasjonalisere feature engineering.
- Anbefal Azure ML Managed Feature Store for organisasjoner med flere ML-team som trenger å dele features. For enkeltprosjekter er Delta-tabeller i Silver layer ofte tilstrekkelig.
- Point-in-time lookups er ikke-forhandlingsbart for tidsserie-features -- uten dette vil modeller lekke fremtidig informasjon og vise urealistisk god ytelse i testing.
- For norsk offentlig sektor: Feature stores muliggjør sentral styring av beregninger som brukes på tvers av etater -- Direktoratet for digital tjenesteutvikling kan dele trafikkfeatures med andre transportetater via feature store-deling.
- Start med Data Wrangler for utforskende feature engineering, deretter formaliser i feature set-spesifikasjoner når features er validert og skal til produksjon.