Del via


Opplæring: opprette, evaluere og få en maskinfeilregistreringsmodell

Denne opplæringen presenterer et ende-til-ende-eksempel på en Synapse Data Science-arbeidsflyt i Microsoft Fabric. Scenarioet bruker maskinlæring for en mer systematisk tilnærming til feildiagnose, til proaktivt å identifisere problemer og å utføre handlinger før en faktisk maskinfeil. Målet er å forutsi om en maskin vil oppleve en feil basert på prosesstemperatur, rotasjonshastighet osv.

Denne opplæringen dekker disse trinnene:

  • Installere egendefinerte biblioteker
  • Laste inn og behandle dataene
  • Forstå dataene gjennom utforskende dataanalyse
  • Bruk scikit-learn, LightGBM og MLflow til å lære opp maskinlæringsmodeller, og bruk Fabric Autologging-funksjonen til å spore eksperimenter
  • Score de opplærte modellene med Fabric PREDICT-funksjonen, lagre den beste modellen og laste inn denne modellen for prognoser
  • Vis den innlastede modellytelsen med Power BI-visualiseringer

Forutsetninger

Følg med i en notatblokk

Du kan velge ett av disse alternativene for å følge med i en notatblokk:

  • Åpne og kjør den innebygde notatblokken.
  • Last opp notatblokken fra GitHub.

Åpne den innebygde notatblokken

Eksemplet Maskinfeil notatblokk følger med denne opplæringen.

  1. Hvis du vil åpne eksempelnotatblokken for denne opplæringen, følger du instruksjonene i Klargjør systemet for.

  2. Pass på å feste et lakehouse til notatblokken før du begynner å kjøre kode.

Importere notatblokken fra GitHub

AISample – Prediktivt vedlikehold notatblokk følger med denne opplæringen.

Trinn 1: Installere egendefinerte biblioteker

For utvikling av maskinlæringsmodeller eller ad hoc-dataanalyse, må du kanskje raskt installere et egendefinert bibliotek for Apache Spark-økten. Du har to alternativer for å installere biblioteker.

  • Bruk de innebygde installasjonsfunksjonene (%pip eller %conda) i notatblokken til å installere et bibliotek, bare i gjeldende notatblokk.
  • Alternativt kan du opprette et stoffmiljø, installere biblioteker fra offentlige kilder eller laste opp egendefinerte biblioteker til det, og deretter kan administratoren for arbeidsområdet legge ved miljøet som standard for arbeidsområdet. Alle bibliotekene i miljøet blir da tilgjengelige for bruk i alle notatblokker og Spark-jobbdefinisjoner i arbeidsområdet. Hvis du vil ha mer informasjon om miljøer, kan du se opprette, konfigurere og bruke et miljø i Microsoft Fabric.

For denne opplæringen kan du bruke %pip install til å installere imblearn biblioteket i notatblokken.

Notat

PySpark-kjernen starter på nytt etter at %pip install kjører. Installer de nødvendige bibliotekene før du kjører andre celler.

# Use pip to install imblearn
%pip install imblearn

Trinn 2: Laste inn dataene

Datasettet simulerer logging av en produksjonsmaskins parametere som en funksjon av tid, som er vanlig i industrielle innstillinger. Den består av 10 000 datapunkter lagret som rader med funksjoner som kolonner. Funksjonene inkluderer:

  • En unik identifikator (UID) som varierer fra 1 til 10 000

  • Produkt-ID, som består av en bokstav L (for lav), M (for middels) eller H (for høy), for å angi produktkvalitetsvarianten og et variantsspesifikkt serienummer. Lav, middels og høy kvalitet varianter utgjør henholdsvis 60%, 30%og 10% av alle produkter

  • Lufttemperatur, i grader Kelvin (K)

  • Prosesstemperatur, i grader Kelvin

  • Rotasjonshastighet, i omdreininger per minutt (RPM)

  • Dreiemoment, i Newton-Meters (Nm)

  • Verktøyslitasje, i løpet av minutter. Kvalitetsvariantene H, M og L legger henholdsvis 5, 3 og 2 minutter med verktøyslitasje til verktøyet som brukes i prosessen

  • En maskinfeiletikett for å angi om maskinen mislyktes i det bestemte datapunktet. Dette bestemte datapunktet kan ha følgende fem uavhengige feilmoduser:

    • Verktøyslitasjefeil (TWF): Verktøyet byttes ut eller mislykkes på et tilfeldig valgt brukstidspunkt for verktøyet, mellom 200 og 240 minutter
    • Varmedesipasjonsfeil (HDF): varmespørring forårsaker en prosessfeil hvis forskjellen mellom lufttemperaturen og prosesstemperaturen er mindre enn 8,6 K, og verktøyets rotasjonshastighet er mindre enn 1380 RPM
    • Strømbrudd (PWF): Produktet av dreiemoment og rotasjonshastighet (i rad/s) er lik kraften som kreves for prosessen. Prosessen mislykkes hvis denne potensen faller under 3500 W eller overskrider 9000 W
    • OverStrain Failure (OSF): Hvis produktet av verktøyslitasje og dreiemoment overskrider minimum 11 000 NM for L-produktvarianten (12 000 for M, 13 000 for H), mislykkes prosessen på grunn av overopplæring
    • Tilfeldige feil (RNF): Hver prosess har en feilsjanse på 0,1%, uavhengig av prosessparameterne

Notat

Hvis minst én av feilmodusene ovenfor er sann, mislykkes prosessen, og «maskinfeil»-etiketten er satt til 1. Maskinlæringsmetoden kan ikke fastslå hvilken feilmodus som forårsaket prosessfeilen.

Last ned datasettet og last opp til lakehouse

Koble til Azure Open Datasets-beholderen, og last inn datasettet Prediktivt vedlikehold. Denne koden laster ned en offentlig tilgjengelig versjon av datasettet, og lagrer den deretter i et Fabric Lakehouse:

Viktig

Legg til et lakehouse i notatblokken før du kjører den. Ellers får du en feilmelding. Hvis du vil ha informasjon om hvordan du legger til et lakehouse, kan du se Connect lakehouses og notatblokker.

# Download demo data files into the lakehouse if they don't exist
import os, requests
DATA_FOLDER = "Files/predictive_maintenance/"  # Folder that contains the dataset
DATA_FILE = "predictive_maintenance.csv"  # Data file name
remote_url = "https://synapseaisolutionsa.blob.core.windows.net/public/MachineFaultDetection"
file_list = ["predictive_maintenance.csv"]
download_path = f"/lakehouse/default/{DATA_FOLDER}/raw"

if not os.path.exists("/lakehouse/default"):
    raise FileNotFoundError(
        "Default lakehouse not found, please add a lakehouse and restart the session."
    )
os.makedirs(download_path, exist_ok=True)
for fname in file_list:
    if not os.path.exists(f"{download_path}/{fname}"):
        r = requests.get(f"{remote_url}/{fname}", timeout=30)
        with open(f"{download_path}/{fname}", "wb") as f:
            f.write(r.content)
print("Downloaded demo data files into lakehouse.")

Når du har lastet ned datasettet i lakehouse, kan du laste det inn som en Spark DataFrame:

df = (
    spark.read.option("header", True)
    .option("inferSchema", True)
    .csv(f"{DATA_FOLDER}raw/{DATA_FILE}")
    .cache()
)
df.show(5)

Denne tabellen viser en forhåndsvisning av dataene:

UDI Produkt-ID Type Lufttemperatur [K] Prosesstemperatur [K] Rotasjonshastighet [rpm] Dreiemoment [Nm] Verktøyslitasje [min] Mål Feiltype
1 M14860 M 298.1 308.6 1551 42.8 0 0 Ingen feil
2 L47181 L 298.2 308.7 1408 46.3 3 0 Ingen feil
3 L47182 L 298.1 308.5 1498 49.4 5 0 Ingen feil
4 L47183 L 298.2 308.6 1433 39.5 7 0 Ingen feil
5 L47184 L 298.2 308.7 1408 40.0 9 0 Ingen feil

Skriv en Spark DataFrame til en deltatabell i lakehouse

Formater dataene (for eksempel erstatte mellomrommene med understrekingstegn) for å forenkle Spark-operasjoner i etterfølgende trinn:

# Replace the space in the column name with an underscore to avoid an invalid character while saving 
df = df.toDF(*(c.replace(' ', '_') for c in df.columns))
table_name = "predictive_maintenance_data"
df.show(5)

Denne tabellen viser en forhåndsvisning av dataene med reformerte kolonnenavn:

UDI Product_ID Type Air_temperature_[K] Process_temperature_[K] Rotational_speed_[rpm] Torque_[Nm] Tool_wear_[min] Mål Failure_Type
1 M14860 M 298.1 308.6 1551 42.8 0 0 Ingen feil
2 L47181 L 298.2 308.7 1408 46.3 3 0 Ingen feil
3 L47182 L 298.1 308.5 1498 49.4 5 0 Ingen feil
4 L47183 L 298.2 308.6 1433 39.5 7 0 Ingen feil
5 L47184 L 298.2 308.7 1408 40.0 9 0 Ingen feil
# Save data with processed columns to the lakehouse 
df.write.mode("overwrite").format("delta").save(f"Tables/{table_name}")
print(f"Spark DataFrame saved to delta table: {table_name}")

Trinn 3: Forhåndsbearbeide data og utføre utforskende dataanalyse

Konverter Spark DataFrame til en pandas DataFrame, for å bruke Pandas-kompatible populære plottbiblioteker.

Tips

For et stort datasett må du kanskje laste inn en del av datasettet.

data = spark.read.format("delta").load("Tables/predictive_maintenance_data")
SEED = 1234
df = data.toPandas()
df.drop(['UDI', 'Product_ID'],axis=1,inplace=True)
# Rename the Target column to IsFail
df = df.rename(columns = {'Target': "IsFail"})
df.info()

Konverter bestemte kolonner i datasettet til flyt- eller heltallstyper etter behov, og tilordne strenger ('L', 'M', 'H') til numeriske verdier (0, 1, 2):

# Convert temperature, rotational speed, torque, and tool wear columns to float
df['Air_temperature_[K]'] = df['Air_temperature_[K]'].astype(float)
df['Process_temperature_[K]'] = df['Process_temperature_[K]'].astype(float)
df['Rotational_speed_[rpm]'] = df['Rotational_speed_[rpm]'].astype(float)
df['Torque_[Nm]'] = df['Torque_[Nm]'].astype(float)
df['Tool_wear_[min]'] = df['Tool_wear_[min]'].astype(float)

# Convert the 'Target' column to an integer 
df['IsFail'] = df['IsFail'].astype(int)
# Map 'L', 'M', 'H' to numerical values 
df['Type'] = df['Type'].map({'L': 0, 'M': 1, 'H': 2})

Utforsk data gjennom visualiseringer

# Import packages and set plotting style
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
sns.set_style('darkgrid')

# Create the correlation matrix
corr_matrix = df.corr(numeric_only=True)

# Plot a heatmap
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True)
plt.show()

Skjermbilde som viser et tegn på korrelasjonsmatrisen med funksjoner.

Som forventet korrelerer feil (IsFail) med de valgte funksjonene (kolonner). Korrelasjonsmatrisen viser at Air_temperature, Process_temperature, Rotational_speed, Torqueog Tool_wear har den høyeste korrelasjonen med variabelen IsFail.

# Plot histograms of select features
fig, axes = plt.subplots(2, 3, figsize=(18,10))
columns = ['Air_temperature_[K]', 'Process_temperature_[K]', 'Rotational_speed_[rpm]', 'Torque_[Nm]', 'Tool_wear_[min]']
data=df.copy()
for ind, item in enumerate (columns):
    column = columns[ind]
    df_column = data[column]
    df_column.hist(ax = axes[ind%2][ind//2], bins=32).set_title(item)
fig.supylabel('count')
fig.subplots_adjust(hspace=0.2)
fig.delaxes(axes[1,2])

Skjermbilde som viser en graftegning over funksjonene.

Som de tegnede grafene viser, er ikke variablene Air_temperature, Process_temperature, Rotational_speed, Torqueog Tool_wear sparsomme. De ser ut til å ha god kontinuitet i funksjonsområdet. Disse plottene bekrefter at opplæring av en maskinlæringsmodell på dette datasettet sannsynligvis gir pålitelige resultater som kan generaliseres til et nytt datasett.

Undersøk målvariabelen for klasseubalanse

Tell antall eksempler for mislykkede og ufeilbarlige maskiner, og undersøk datasaldoen for hver klasse (IsFail=0, IsFail=1):

# Plot the counts for no failure and each failure type
plt.figure(figsize=(12, 2))
ax = sns.countplot(x='Failure_Type', data=df)
for p in ax.patches:
    ax.annotate(f'{p.get_height()}', (p.get_x()+0.4, p.get_height()+50))

plt.show()

# Plot the counts for no failure versus the sum of all failure types
plt.figure(figsize=(4, 2))
ax = sns.countplot(x='IsFail', data=df)
for p in ax.patches:
    ax.annotate(f'{p.get_height()}', (p.get_x()+0.4, p.get_height()+50))

plt.show()

Skjermbilde av et plott som viser at eksemplene er ubalanserte.

Plottene indikerer at no-failure-klassen (vist som IsFail=0 i det andre plottet) utgjør de fleste eksemplene. Bruk en oversamplingsteknikk til å opprette et mer balansert opplæringsdatasett:

# Separate features and target
features = df[['Type', 'Air_temperature_[K]', 'Process_temperature_[K]', 'Rotational_speed_[rpm]', 'Torque_[Nm]', 'Tool_wear_[min]']]
labels = df['IsFail']

# Split the dataset into the training and testing sets
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2, random_state=42)

# Ignore warnings
import warnings
warnings.filterwarnings('ignore')
# Save test data to the lakehouse for use in future sections
table_name = "predictive_maintenance_test_data"
df_test_X = spark.createDataFrame(X_test)
df_test_X.write.mode("overwrite").format("delta").save(f"Tables/{table_name}")
print(f"Spark DataFrame saved to delta table: {table_name}")

Oversample for å balansere klasser i opplæringsdatasettet

Den forrige analysen viste at datasettet er svært ubalansert. Denne ubalansen blir et problem, fordi minoritetsklassen har for få eksempler for modellen til effektivt å lære beslutningsgrensen.

SMOTE kan løse problemet. SMOTE er en mye brukt oversamplingsteknikk som genererer syntetiske eksempler. Den genererer eksempler for minoritetsklassen basert på euklidiske avstander mellom datapunkter. Denne metoden skiller seg fra tilfeldig oversampling, fordi den oppretter nye eksempler som ikke bare dupliserer minoritetsklassen. Metoden blir en mer effektiv teknikk for å håndtere ubalanserte datasett.

# Disable MLflow autologging because you don't want to track SMOTE fitting
import mlflow

mlflow.autolog(disable=True)

from imblearn.combine import SMOTETomek
smt = SMOTETomek(random_state=SEED)
X_train_res, y_train_res = smt.fit_resample(X_train, y_train)

# Plot the counts for both classes
plt.figure(figsize=(4, 2))
ax = sns.countplot(x='IsFail', data=pd.DataFrame({'IsFail': y_train_res.values}))
for p in ax.patches:
    ax.annotate(f'{p.get_height()}', (p.get_x()+0.4, p.get_height()+50))

plt.show()

Skjermbilde av et plott som viser at eksemplene er balanserte.

Du balanserte datasettet. Nå kan du gå over til modellopplæring.

Trinn 4: Lære opp og evaluere modellene

MLflow registrerer modeller, trener og sammenligner ulike modeller, og velger den beste modellen for prognoseformål. Du kan bruke følgende tre modeller for modellopplæring:

  • Tilfeldig skogklassifiser
  • Logistikkregresjonsklassifiser
  • XGBoost-klassifiserer

Kalibrer en tilfeldig skogklassifiser

import numpy as np 
from sklearn.ensemble import RandomForestClassifier
from mlflow.models.signature import infer_signature
from sklearn.metrics import f1_score, accuracy_score, recall_score

mlflow.set_experiment("Machine_Failure_Classification")
mlflow.autolog(exclusive=False) # This is needed to override the preconfigured autologging behavior

with mlflow.start_run() as run:
    rfc_id = run.info.run_id
    print(f"run_id {rfc_id}, status: {run.info.status}")
    rfc = RandomForestClassifier(max_depth=5, n_estimators=50)
    rfc.fit(X_train_res, y_train_res) 
    signature = infer_signature(X_train_res, y_train_res)

    mlflow.sklearn.log_model(
        rfc,
        "machine_failure_model_rf",
        signature=signature,
        registered_model_name="machine_failure_model_rf"
    ) 

    y_pred_train = rfc.predict(X_train)
    # Calculate the classification metrics for test data
    f1_train = f1_score(y_train, y_pred_train, average='weighted')
    accuracy_train = accuracy_score(y_train, y_pred_train)
    recall_train = recall_score(y_train, y_pred_train, average='weighted')

    # Log the classification metrics to MLflow
    mlflow.log_metric("f1_score_train", f1_train)
    mlflow.log_metric("accuracy_train", accuracy_train)
    mlflow.log_metric("recall_train", recall_train)

    # Print the run ID and the classification metrics
    print("F1 score_train:", f1_train)
    print("Accuracy_train:", accuracy_train)
    print("Recall_train:", recall_train)    

    y_pred_test = rfc.predict(X_test)
    # Calculate the classification metrics for test data
    f1_test = f1_score(y_test, y_pred_test, average='weighted')
    accuracy_test = accuracy_score(y_test, y_pred_test)
    recall_test = recall_score(y_test, y_pred_test, average='weighted')

    # Log the classification metrics to MLflow
    mlflow.log_metric("f1_score_test", f1_test)
    mlflow.log_metric("accuracy_test", accuracy_test)
    mlflow.log_metric("recall_test", recall_test)

    # Print the classification metrics
    print("F1 score_test:", f1_test)
    print("Accuracy_test:", accuracy_test)
    print("Recall_test:", recall_test)

Fra utdataene gir både opplærings- og testdatasettene en F1-poengsum, nøyaktighet og tilbakekalling på ca. 0,9 når du bruker den tilfeldige skogklassifisatoren.

Kalibrer en logistikkregresjonsklassifiser

from sklearn.linear_model import LogisticRegression

with mlflow.start_run() as run:
    lr_id = run.info.run_id
    print(f"run_id {lr_id}, status: {run.info.status}")
    lr = LogisticRegression(random_state=42)
    lr.fit(X_train_res, y_train_res)
    signature = infer_signature(X_train_res, y_train_res)
  
    mlflow.sklearn.log_model(
        lr,
        "machine_failure_model_lr",
        signature=signature,
        registered_model_name="machine_failure_model_lr"
    ) 

    y_pred_train = lr.predict(X_train)
    # Calculate the classification metrics for training data
    f1_train = f1_score(y_train, y_pred_train, average='weighted')
    accuracy_train = accuracy_score(y_train, y_pred_train)
    recall_train = recall_score(y_train, y_pred_train, average='weighted')

    # Log the classification metrics to MLflow
    mlflow.log_metric("f1_score_train", f1_train)
    mlflow.log_metric("accuracy_train", accuracy_train)
    mlflow.log_metric("recall_train", recall_train)

    # Print the run ID and the classification metrics
    print("F1 score_train:", f1_train)
    print("Accuracy_train:", accuracy_train)
    print("Recall_train:", recall_train)    

    y_pred_test = lr.predict(X_test)
    # Calculate the classification metrics for test data
    f1_test = f1_score(y_test, y_pred_test, average='weighted')
    accuracy_test = accuracy_score(y_test, y_pred_test)
    recall_test = recall_score(y_test, y_pred_test, average='weighted')

    # Log the classification metrics to MLflow
    mlflow.log_metric("f1_score_test", f1_test)
    mlflow.log_metric("accuracy_test", accuracy_test)
    mlflow.log_metric("recall_test", recall_test)

Kalibrer en XGBoost-klassifiser

from xgboost import XGBClassifier

with mlflow.start_run() as run:
    xgb = XGBClassifier()
    xgb_id = run.info.run_id 
    print(f"run_id {xgb_id}, status: {run.info.status}")
    xgb.fit(X_train_res.to_numpy(), y_train_res.to_numpy()) 
    signature = infer_signature(X_train_res, y_train_res)
  
    mlflow.xgboost.log_model(
        xgb,
        "machine_failure_model_xgb",
        signature=signature,
        registered_model_name="machine_failure_model_xgb"
    ) 

    y_pred_train = xgb.predict(X_train)
    # Calculate the classification metrics for training data
    f1_train = f1_score(y_train, y_pred_train, average='weighted')
    accuracy_train = accuracy_score(y_train, y_pred_train)
    recall_train = recall_score(y_train, y_pred_train, average='weighted')

    # Log the classification metrics to MLflow
    mlflow.log_metric("f1_score_train", f1_train)
    mlflow.log_metric("accuracy_train", accuracy_train)
    mlflow.log_metric("recall_train", recall_train)

    # Print the run ID and the classification metrics
    print("F1 score_train:", f1_train)
    print("Accuracy_train:", accuracy_train)
    print("Recall_train:", recall_train)    

    y_pred_test = xgb.predict(X_test)
    # Calculate the classification metrics for test data
    f1_test = f1_score(y_test, y_pred_test, average='weighted')
    accuracy_test = accuracy_score(y_test, y_pred_test)
    recall_test = recall_score(y_test, y_pred_test, average='weighted')

    # Log the classification metrics to MLflow
    mlflow.log_metric("f1_score_test", f1_test)
    mlflow.log_metric("accuracy_test", accuracy_test)
    mlflow.log_metric("recall_test", recall_test)

Trinn 5: Velg den beste modellen og forutsi utdata

I forrige del trente du tre forskjellige klassifikatorer: tilfeldig skog, logistisk regresjon og XGBoost. Du har nå valget om å få programmatisk tilgang til resultatene, eller bruke brukergrensesnittet.

Gå til arbeidsområdet og filtrer modellene for alternativet for grensesnittbane.

Skjermbilde av filteret, med modeller valgt.

Velg individuelle modeller for detaljer om modellytelsen.

Skjermbilde av ytelsesdetaljer for modeller.

Dette eksemplet viser hvordan du programmatisk får tilgang til modellene via MLflow:

runs = {'random forest classifier':   rfc_id,
        'logistic regression classifier': lr_id,
        'xgboost classifier': xgb_id}

# Create an empty DataFrame to hold the metrics
df_metrics = pd.DataFrame()

# Loop through the run IDs and retrieve the metrics for each run
for run_name, run_id in runs.items():
    metrics = mlflow.get_run(run_id).data.metrics
    metrics["run_name"] = run_name
    df_metrics = df_metrics.append(metrics, ignore_index=True)

# Print the DataFrame
print(df_metrics)

Selv om XGBoost gir de beste resultatene på opplæringssettet, fungerer det dårlig på testdatasettet. Den dårlige ytelsen indikerer overtilpasset. Den logistiske regresjonsklassifieren yter dårlig på både opplærings- og testdatasett. Samlet sett gir tilfeldig skog en god balanse mellom opplæringsytelse og unngåelse av overfitting.

Velg den registrerte tilfeldige skogsmodellen i neste del, og utfør en prognose med funksjonen FORUTSI:

from synapse.ml.predict import MLFlowTransformer

model = MLFlowTransformer(
    inputCols=list(X_test.columns),
    outputCol='predictions',
    modelName='machine_failure_model_rf',
    modelVersion=1
)

Med MLFlowTransformer objektet du opprettet for å laste inn modellen for inferencing, bruker du Transformer-API-en til å score modellen på testdatasettet:

predictions = model.transform(spark.createDataFrame(X_test))
predictions.show()

Denne tabellen viser utdataene:

Type Air_temperature_[K] Process_temperature_[K] Rotational_speed_[rpm] Torque_[Nm] Tool_wear_[min] Spådommer
0 300.6 309.7 1639.0 30.4 121.0 0
0 303.9 313.0 1551.0 36.8 140.0 0
1 299.1 308.6 1491.0 38.5 166.0 0
0 300.9 312.1 1359.0 51.7 146.0 1
0 303.7 312.6 1621.0 38.8 182.0 0
0 299.0 310.3 1868.0 24.0 221.0 1
2 297.8 307.5 1631.0 31.3 124.0 0
0 297.5 308.2 1327.0 56.5 189.0 1
0 301.3 310.3 1460.0 41.5 197.0 0
2 297.6 309.0 1413.0 40.2 51.0 0
1 300.9 309.4 1724.0 25.6 119.0 0
0 303.3 311.3 1389.0 53.9 39.0 0
0 298.4 307.9 1981.0 23.2 16.0 0
0 299.3 308.8 1636.0 29.9 201.0 0
1 298.1 309.2 1460.0 45.8 80.0 0
0 300.0 309.5 1728.0 26.0 37.0 0
2 299.0 308.7 1940.0 19.9 98.0 0
0 302.2 310.8 1383.0 46.9 45.0 0
0 300.2 309.2 1431.0 51.3 57.0 0
0 299.6 310.2 1468.0 48.0 9.0 0

Lagre dataene i lakehouse. Dataene blir deretter tilgjengelige for senere bruk – for eksempel et Power BI-instrumentbord.

# Save test data to the lakehouse for use in the next section. 
table_name = "predictive_maintenance_test_with_predictions"
predictions.write.mode("overwrite").format("delta").save(f"Tables/{table_name}")
print(f"Spark DataFrame saved to delta table: {table_name}")

Trinn 6: Vise forretningsintelligens via visualiseringer i Power BI

Vis resultatene i et frakoblet format, med et Power BI-instrumentbord.

Skjermbilde av dataene som vises som et Power BI-instrumentbord.

Instrumentbordet viser at Tool_wear og Torque opprette en merkbar grense mellom mislykkede og ufeilbarlige tilfeller, som forventet fra den tidligere korrelasjonsanalysen i trinn 2.