Поделиться через


Руководство по созданию, оценке и оценке модели обнаружения ошибок компьютера

В этом руководстве представлен полный пример рабочего процесса Обработки и анализа данных Synapse в Microsoft Fabric. Сценарий использует машинное обучение для более систематического подхода к диагностике сбоев, для упреждающего выявления проблем и принятия действий до фактического сбоя компьютера. Цель состоит в том, чтобы предсказать, будет ли компьютер испытывать сбой на основе температуры процесса, скорости поворота и т. д.

В этом руководстве рассматриваются следующие действия.

  • Установка пользовательских библиотек
  • Загрузка и обработка данных
  • Понять данные с помощью исследовательского анализа данных
  • Использование scikit-learn, LightGBM и MLflow для обучения моделей машинного обучения и использования функции автологирования Fabric для отслеживания экспериментов
  • Оценка обученных моделей с помощью функции PREDICT Fabric, сохранение оптимальной модели и загрузка модели для прогнозирования
  • Отображение загруженной производительности модели с помощью визуализаций Power BI

Необходимые условия

  • Получите подписку Microsoft Fabric. Или зарегистрируйтесь, чтобы получить бесплатную пробную версию Microsoft Fabric.

  • Войдите в Microsoft Fabric.

  • Используйте переключатель интерфейса в левой нижней части домашней страницы, чтобы перейти на Fabric.

    снимок экрана меню переключателя режима, в котором показано, где выбрать Data Science.

Следуйте инструкциям в записной книжке

Вы можете выбрать один из следующих вариантов для использования в записной книжке:

  • Откройте и запустите встроенную записную книжку.
  • Отправьте записную книжку из GitHub.

Открытие встроенной записной книжки

Пример неисправности машины тетрадь прилагается к этому руководству.

  1. Чтобы открыть пример блокнота для этого руководства, следуйте инструкциям в Подготовьте систему для руководств по анализу данных.

  2. Перед началом выполнения кода обязательно подключите lakehouse к ноутбуку.

Импорт записной книжки из GitHub

Блокнот AISample — прогнозное обслуживание идет в комплекте с этим руководством.

Шаг 1. Установка пользовательских библиотек

Для разработки моделей машинного обучения или нерегламентированного анализа данных может потребоваться быстро установить пользовательскую библиотеку для сеанса Apache Spark. Существует два варианта установки библиотек.

  • Используйте встроенные функции установки (%pip или %conda) вашей записной книжки для установки библиотеки только в данной записной книжке.
  • Кроме того, можно создать среду Fabric, установить библиотеки из общедоступных источников или отправить в нее пользовательские библиотеки, а затем администратор рабочей области может присоединить среду в качестве значения по умолчанию для рабочей области. Все библиотеки в среде будут доступны для использования в любых записных книжках и определениях заданий Spark в рабочей области. Дополнительные сведения о средах см. в создание, настройка и использование среды в Microsoft Fabric.

В этом руководстве используйте %pip install для установки библиотеки imblearn в блокноте.

Заметка

Ядро PySpark перезапускается после %pip install запусков. Установите необходимые библиотеки перед запуском любых других ячеек.

# Use pip to install imblearn
%pip install imblearn

Шаг 2. Загрузка данных

Набор данных имитирует регистрацию параметров производственной машины в зависимости от времени, что распространено в промышленной среде. Он состоит из 10 000 точек данных, хранящихся в виде строк с функциями в виде столбцов. К ним относятся следующие функции:

  • Уникальный идентификатор (UID), диапазон от 1 до 10000

  • Идентификатор продукта, состоящий из буквы L (для низкого), M (для среднего) или H (для высокого), чтобы указать вариант качества продукта и серийный номер конкретного варианта. Низкие, средние и высококачественные варианты составляют 60%, 30%и 10% всех продуктов соответственно

  • Температура воздуха, в градусах Келвин (K)

  • Температура процесса, в градусах Келвин

  • Частота вращения в оборотах в минуту (RPM)

  • Крутящий момент, в Newton-Meters (Nm, ньютон-метры)

  • Износ инструмента, в минутах. Варианты качества H, M и L увеличивают износ инструмента в процессе на 5, 3 и 2 минуты соответственно.

  • Метка сбоя компьютера, чтобы указать, произошел ли сбой компьютера в определенной точке данных. Эта конкретная точка данных может иметь любой из следующих пяти независимых режимов сбоя:

    • Износ инструмента (TWF): инструмент заменяется или выходит из строя при случайно выбранном времени износа инструмента в период от 200 до 240 минут
    • Сбой разбиения тепла (HDF): разбиение тепла приводит к сбою процесса, если разница между температурой воздуха и температурой процесса меньше 8,6 K, а скорость вращения средства меньше 1380 RPM
    • Сбой питания (PWF): произведение крутящего момента и скорости поворота (в ради/с) равно мощности, необходимой для процесса. Процесс прерывается, если эта мощность опускается ниже 3500 Вт или превышает 9000 Вт.
    • Отказ из-за перегрузки (OverStrain Failure, OSF): если произведение износа и крутящего момента превышает 11 000 минимальных Нм для варианта продукта L (12 000 для M, 13 000 для H), процесс завершается сбоем из-за перегрузки.
    • Случайные сбои (RNF): каждый процесс имеет вероятность сбоя 0,1%независимо от параметров процесса

Заметка

Если по крайней мере один из указанных выше режимов сбоя имеет значение true, процесс завершается ошибкой, а метка "сбой компьютера" имеет значение 1. Метод машинного обучения не может определить, какой режим сбоя вызвал сбой процесса.

Скачайте набор данных и отправьте его в lakehouse

Подключитесь к контейнеру Открытых наборов данных Azure и загрузите набор данных прогнозного обслуживания. Этот код загружает общедоступную версию набора данных, а затем сохраняет её в Lakehouse Fabric:

Важный

Добавьте lakehouse в записную книжку перед его запуском. В противном случае вы получите ошибку. Для получения информации о добавлении lakehouse см. раздел Подключение lakehouses и записных книжек.

# 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.")

После скачивания набора данных в хранилище данных (lakehouse) его можно загрузить в виде DataFrame Spark:

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

В этой таблице показана предварительная версия данных:

UDI Идентификатор продукта Тип Температура воздуха [K] Температура процесса [K] Скорость вращения [rpm] Крутящий момент [Н·м] Износ инструмента [min] Цель Тип сбоя
1 M14860 M 298.1 308.6 1551 42.8 0 0 Нет сбоя
2 L47181 L 298.2 308.7 1408 46.3 3 0 Нет сбоя
3 L47182 L 298.1 308.5 1498 49.4 5 0 Нет сбоя
4 L47183 L 298.2 308.6 1433 39.5 7 0 Нет сбоя
5 L47184 L 298.2 308.7 1408 40.0 9 0 Нет сбоя

Запись кадра данных Spark в разностную таблицу Lakehouse

Отформатируйте данные (например, замените пробелы символами подчеркивания), чтобы упростить операции Spark в последующих шагах:

# 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)

В этой таблице показана предварительная версия данных с именами переформатированных столбцов:

UDI Идентификатор_продукта Тип Температура_воздуха_[K] Температура_процесса_[K] Скорость вращения [об/мин] Torque_[Nm] Износ инструмента [мин] Цель Тип_Неисправности
1 M14860 M 298.1 308,6 1551 42.8 0 0 Нет сбоя
2 L47181 L 298.2 308.7 1408 46.3 3 0 Нет сбоя
3 L47182 L 298.1 308,5 1498 49.4 5 0 Нет сбоя
4 L47183 L 298.2 308.6 1433 39.5 7 0 Нет сбоя
5 L47184 L 298.2 308.7 1408 40.0 9 0 Нет сбоя
# 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}")

Шаг 3. Предварительная обработка данных и выполнение анализа исследуемых данных

Преобразуйте кадр данных Spark в кадр данных pandas, чтобы использовать популярные библиотеки графиков, совместимые с Pandas.

Совет

Для большого набора данных может потребоваться загрузить часть этого набора данных.

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()

Преобразуйте определенные столбцы набора данных в типы с плавающей запятой или целочисленные типы по мере необходимости, и сопоставьте строки ('L', 'M', 'H') с числовыми значениями (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})

Изучение данных с помощью визуализаций

# 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()

снимок экрана, показывающий график матрицы корреляции признаков.

Как ожидалось, сбой (IsFail) коррелирует с выбранными признаками (столбцами). Матрица корреляции показывает, что Air_temperature, Process_temperature, Rotational_speed, Torqueи Tool_wear имеют самую высокую корреляцию с переменной 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])

снимок экрана с графиком функций.

Как показано на графиках, переменные Air_temperature, Process_temperature, Rotational_speed, Torqueи Tool_wear не разрежены. Они, кажется, имеют хорошую непрерывность в пространстве функций. Эти графики подтверждают, что обучение модели машинного обучения в этом наборе данных, скорее всего, дает надежные результаты, которые могут обобщать новый набор данных.

Проверка на наличие дисбаланса классов в целевой переменной

Подсчитайте количество образцов для вышедших из строя и исправных машин и проверьте баланс данных для каждого класса (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()

#Снимок экрана графика, показывающего несбалансированность выборки.

Графики указывают на то, что класс no-failure (показан как IsFail=0 во втором графике) представляет собой большую часть выборок. Используйте метод дополнительной выборки для создания более сбалансированного набора данных для обучения.

# 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}")

Пересэмплирование для балансировки классов в обучающем наборе данных

Предыдущий анализ показал, что набор данных сильно несбалансирован. Этот дисбаланс становится проблемой, поскольку класс меньшинства имеет слишком мало примеров для модели для эффективного изучения границы принятия решений.

SMOTE может решить проблему. SMOTE — это широко используемый метод увеличения выборки, который создает синтетические образцы. Он создает примеры для класса меньшинства на основе расстояний Евклида между точками данных. Этот метод отличается от случайного превышения, так как он создает новые примеры, которые не просто дублируют класс меньшинства. Метод становится более эффективным способом обработки несбалансированных наборов данных.

# 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()

снимок экрана: график, показывающий, что примеры сбалансированы.

Вы успешно сбалансировали набор данных. Теперь вы можете перейти к обучению модели.

Шаг 4. Обучение и оценка моделей

MLflow регистрирует модели, обучает и сравнивает различные модели и выбирает лучшую модель для прогнозирования. Для обучения модели можно использовать следующие три модели:

  • Классификатор случайного леса
  • Классификатор логистической регрессии
  • Классификатор XGBoost

Обучение случайного классификатора леса

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)

Из выходных данных наборы данных обучения и тестирования дают оценку F1, точность и отзыв около 0,9 при использовании случайного классификатора леса.

Обучение классификатора логистической регрессии

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)

Обучение классификатора XGBoost

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)

Шаг 5. Выбор оптимальной модели и прогнозирование выходных данных

В предыдущем разделе вы обучили три разных классификатора: "случайный лес", логистическую регрессию и XGBoost. Теперь у вас есть возможность программного доступа к результатам или использовать пользовательский интерфейс.

Для параметра пути пользовательского интерфейса перейдите в рабочую область и отфильтруйте модели.

снимок экрана фильтра с выбранными моделями.

Выберите отдельные модели для получения подробных сведений о производительности модели.

снимок экрана: сведения о производительности моделей.

В этом примере показано, как программно получить доступ к моделям с помощью 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)

Хотя XGBoost дает лучшие результаты в обучаемом наборе, он плохо работает на тестовом наборе данных. Эта низкая производительность означает переобучение. Классификатор логистической регрессии плохо работает как на обучающие, так и тестовые наборы данных. В целом, случайный лес обеспечивает хороший баланс между производительностью обучения и избеганием переобучения.

В следующем разделе выберите зарегистрированную модель случайного леса и выполните прогноз с помощью функции PREDICT:

from synapse.ml.predict import MLFlowTransformer

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

С помощью объекта MLFlowTransformer, созданного для загрузки модели для предсказания, используйте API Transformer для оценки модели на тестовом наборе данных.

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

В этой таблице показаны выходные данные:

Тип Температура_воздуха_[K] Температура_процесса_[K] Скорость вращения [об/мин] Torque_[Nm] Tool_wear_[мин] Предсказания
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

Сохраните данные в lakehouse. Затем данные становятся доступными для последующих использования — например, панель мониторинга Power BI.

# 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}")

Шаг 6. Просмотр бизнес-аналитики с помощью визуализаций в Power BI

Отображение результатов в автономном формате с помощью панели мониторинга Power BI.

снимок экрана: данные, отображаемые в виде панели мониторинга Power BI.

На панели мониторинга показано, что Tool_wear и Torque создают заметные границы между неудачными и успешными случаями, как ожидалось в предыдущем анализе корреляции на шаге 2.