predictive-maintenance

German Version

Beschreibung der Funtkionsweise der Klasse Predictive Maintenance Analyzer V5

Die Klasse PredictiveMaintenanceAnalyzer analysiert Sensordaten eines Fahrzeugs, erkennt Anomalien und sagt basierend auf diesen Daten und einem Machine-Learning-Modell zukünftige Defekte voraus. Die Ergebnisse werden in einem strukturierten Format bereitgestellt und können weiterverarbeitet werden.


Klasse: PredictiveMaintenanceAnalyzer

Konstruktor (__init__)

Zweck

Initialisiert die Klasse und stellt die Verbindung zur MongoDB sowie die Fahrzeug-ID her.

Parameter


Methode: analyze_vehicle

Zweck

Die zentrale Methode der Klasse, die:

  1. Fahrzeug- und Sensordaten abruft,
  2. Anomalien erkennt,
  3. Ein Machine-Learning-Modell trainiert und evaluiert,
  4. Die Ergebnisse in strukturierter Form zurückgibt.

Beschreibung der Funktion detect_anomalies

Die Funktion detect_anomalies identifiziert Anomalien in Sensordaten eines Fahrzeugs basierend auf dem Sensortyp. Sie verwendet das maschinelle Lernverfahren Isolation Forest, um ungewöhnliche Datenpunkte zu erkennen, erstellt Visualisierungen für die erkannten Anomalien und gibt die Ergebnisse in einem strukturierten Dictionary zurück.


Funktionalität und Schritte

1. Parameter


2. Rückgabe


3. Ablauf

3.1 Initialisierung

results = {"anomaly": []}
sensor_df['anomaly'] = 0
anomaly_counts = {}

3.2 Iteration durch Sensortypen

for sensor_type in sensor_df['sensorType'].unique():
    sensor_subset = sensor_df[sensor_df['sensorType'] == sensor_type]

3.3 Isolation Forest: Anomalieerkennung

X_anomaly = sensor_subset[['value']]
anomaly_detector = IsolationForest(n_estimators=n_estimators, contamination=contamination, random_state=42)
anomaly_detector.fit(X_anomaly)
predictions = anomaly_detector.predict(X_anomaly)

3.4 Speichern der Ergebnisse

sensor_df.loc[sensor_subset.index, 'anomaly'] = pd.Series(predictions, index=sensor_subset.index)
anomaly_count = (sensor_df.loc[sensor_subset.index, 'anomaly'] == -1).sum()
anomaly_counts[sensor_type] = anomaly_count

3.5 Konvertieren von Anomalie-Markierungen

sensor_df['anomaly'] = sensor_df['anomaly'].apply(lambda x: 1 if x == -1 else 0)

3.6 Ergebnisaggregation

Für jeden Sensortyp werden die Ergebnisse strukturiert gespeichert:

anomalies = sensor_df[(sensor_df['sensorType'] == sensor_type) & (sensor_df['anomaly'] == 1)]
anomaly_entry = {
    "sensor_type": sensor_type,
    "vehicle_id": self.vehicle_id,
    "anomaly_count": int(count),
    "anomaly_data": anomalies[['timestamp', 'value', 'mileage', 'anomaly']].to_dict(orient='records')
}

3.7 Visualisierung

Ein Diagramm wird erstellt, das die Sensorwerte und Anomalien darstellt:

fig, ax = plt.subplots(figsize=(14, 6))
ax.plot(sensor_df[sensor_df['sensorType'] == sensor_type]['timestamp'], sensor_df[sensor_df['sensorType'] == sensor_type]['value'], label='Sensorwert')
ax.scatter(anomalies['timestamp'], anomalies['value'], color='red', label='Anomalie', marker='x')
Debug-Ausgabe
if debug:
    plt.show()
Base64-kodierte Speicherung

Das Diagramm wird als Base64-kodierter String gespeichert:

buf = io.BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
anomaly_entry["plot"] = base64.b64encode(buf.getvalue()).decode('utf-8')

3.8 Rückgabe

Die Ergebnisse werden im Dictionary results gespeichert und zurückgegeben:

results["anomaly"].append(anomaly_entry)
return results

Zusammenfassung der Funktionalität

  1. Die Funktion gruppiert die Sensordaten nach sensorType.
  2. Für jeden Sensortyp wird Isolation Forest verwendet, um Anomalien zu erkennen.
  3. Ergebnisse werden in einem strukturierten Format (Daten und Diagramme) gespeichert.
  4. Optional werden Debug-Diagramme angezeigt.

Beispiel für Rückgabewerte

1. Ergebnisse (Struktur)

{
    "anomaly": [
        {
            "sensor_type": "temperature",
            "vehicle_id": "V001",
            "anomaly_count": 5,
            "anomaly_data": [
                { "timestamp": "2024-01-01T12:00:00", "value": 150, "mileage": 12000, "anomaly": 1 },
                { "timestamp": "2024-01-01T12:05:00", "value": 170, "mileage": 12010, "anomaly": 1 }
            ],
            "plot": "<Base64-kodiertes Diagramm>"
        }
    ]
}

2. Beispielanwendung

anomalies = analyzer.detect_anomalies(sensor_df, debug=True)
print(anomalies)

Stärken der Funktion

  1. Flexibilität:
    • Anpassbare Parameter (contamination, n_estimators).
  2. Strukturierte Rückgabe:
    • Daten und Visualisierungen für jede Anomalie.
  3. Integration mit Visualisierungen:
    • Base64-Diagramme erleichtern die Weiterverarbeitung.

Verbesserungsmöglichkeiten

  1. Speicherverbrauch optimieren:
    • Große Plots können zu Speicherproblemen führen.
  2. Fehlende Daten:
    • Umgang mit fehlenden oder fehlerhaften Werten (NaN) verbessern.
  3. Sensitivität:
    • Dynamische Anpassung des contamination-Parameters basierend auf den Daten.

Beschreibung der Funktion: detect_anomalies_thresholds

Die Funktion detect_anomalies_thresholds dient zur Erkennung von Anomalien in Sensordaten basierend auf vordefinierten oberen und unteren Grenzwerten. Die Grenzwerte können entweder als Parameter übergeben oder aus einer MongoDB-Datenbank abgerufen werden. Die Methode markiert Anomalien im DataFrame und gibt die Ergebnisse in strukturierter Form zurück.


Zweck


Parameter

  1. sensor_df (Pandas DataFrame):
    • Enthält die Sensordaten mit den Spalten:
      • sensorType: Der Typ des Sensors (z. B. Temperatur, Druck).
      • value: Der gemessene Wert des Sensors.
      • Optional: timestamp, mileage für zusätzliche Informationen.
  2. sensor_thresholds (dict):
    • Ein Dictionary, das Grenzwerte für jeden Sensortyp definiert:
      {
          "sensorType1": {"min": min_value, "max": max_value},
          "sensorType2": {"min": min_value, "max": max_value}
      }
      
    • Beispiel:
      {
          "temperature": {"min": -20, "max": 120},
          "pressure": {"min": 0, "max": 300}
      }
      

Rückgabewerte

Ein Dictionary mit den Anomalieergebnissen:

  1. anomaly_threshold (list of dict):
    • Liste der Anomalien pro Sensortyp:
      • sensor_type: Der Sensortyp (z. B. Temperatur).
      • vehicle_id: Die ID des Fahrzeugs.
      • anomaly_count: Die Anzahl der erkannten Anomalien.
      • anomaly_data: Eine Liste von Anomaliedatensätzen (Zeit, Wert, Kilometerstand, Anomalie-Markierung).

Funktionsweise: Schritt-für-Schritt

1. Grenzwerte initialisieren

if sensor_thresholds is None:
    vehicle_data = self.db["vehicles"].find_one({"vehicleId": self.vehicle_id}, {"_id": 0, "sensorGroup": 1})

    if "sensorGroup" in vehicle_data:
        sensor_group = vehicle_data["sensorGroup"]
        threshold_data = self.db["sensorGroups"].find_one({"sensorGroup": sensor_group}, {"_id": 0, "sensorTypes": 1})
        if threshold_data is not None:
            sensor_thresholds = threshold_data["sensorTypes"]

    if sensor_thresholds is None:
        sensor_thresholds = {
            "io58": {"min": 0, "max": 120},  # Standardgrenzwerte
            "io32": {"min": 0, "max": 120},
            "io66": {"min": 13000, "max": 30000}
        }

2. Anomalien initialisieren

sensor_df["anomaly_threshold"] = 0
anomaly_threshold_counts = {}

3. Iteration durch Sensortypen

for sensor_type, thresholds in sensor_thresholds.items():
    min_value = thresholds["min"]
    max_value = thresholds["max"]

    is_anomaly = (sensor_df["sensorType"] == sensor_type) & (
        (sensor_df["value"] < min_value) | (sensor_df["value"] > max_value)
    )
    sensor_df.loc[is_anomaly, "anomaly_threshold"] = 1

4. Anomalien zählen

anomaly_threshold_count = (
    sensor_df.loc[sensor_df['sensorType'] == sensor_type, 'anomaly_threshold'] == 1).sum()
anomaly_threshold_counts[sensor_type] = anomaly_threshold_count

5. Ergebnisse erstellen

Für jeden Sensortyp wird ein Eintrag in den Ergebnissen erstellt:

anomalies = sensor_df[(sensor_df['sensorType'] == sensor_type) & (sensor_df['anomaly_threshold'] == 1)]
anomaly_threshold_entry = {
    "sensor_type": sensor_type,
    "vehicle_id": self.vehicle_id,
    "anomaly_count": int(count),
    "anomaly_data": anomalies[['timestamp', 'value', 'mileage', 'anomaly_threshold']].to_dict(orient='records')
}
results["anomaly_threshold"].append(anomaly_threshold_entry)

6. Rückgabe

return results

Beispiel für Rückgabewerte

Input: Sensordaten

| sensorType | value | timestamp | mileage | |————-|——-|———————|———| | temperature | 150 | 2024-01-01 12:00:00 | 12000 | | pressure | 350 | 2024-01-01 12:01:00 | 12010 | | temperature | 100 | 2024-01-01 12:02:00 | 12020 |

Input: Grenzwerte

{
    "temperature": {"min": -20, "max": 120},
    "pressure": {"min": 0, "max": 300}
}

Output: Ergebnisse

{
    "anomaly_threshold": [
        {
            "sensor_type": "temperature",
            "vehicle_id": "V001",
            "anomaly_count": 1,
            "anomaly_data": [
                { "timestamp": "2024-01-01T12:00:00", "value": 150, "mileage": 12000, "anomaly_threshold": 1 }
            ]
        },
        {
            "sensor_type": "pressure",
            "vehicle_id": "V001",
            "anomaly_count": 1,
            "anomaly_data": [
                { "timestamp": "2024-01-01T12:01:00", "value": 350, "mileage": 12010, "anomaly_threshold": 1 }
            ]
        }
    ]
}

Zusammenfassung

Die Funktion detect_anomalies_thresholds ist ein effektives Werkzeug zur Überprüfung von Sensordaten auf Basis vordefinierter Grenzwerte. Sie ist flexibel, da die Grenzwerte entweder als Parameter übergeben oder dynamisch aus der MongoDB geladen werden können. Die Ergebnisse werden strukturiert bereitgestellt und können für weitere Analysen verwendet werden.


Zusammenfassung

Die Klasse PredictiveMaintenanceAnalyzer bietet ein leistungsstarkes Werkzeug für die Überwachung und Analyse von Fahrzeugdaten. Durch die Kombination von Anomalieerkennung und maschinellem Lernen liefert sie präzise Vorhersagen, die in Wartungssysteme integriert werden können. Die klare Trennung von Datenverarbeitung, Modellierung und Ergebnisausgabe macht die Klasse flexibel und anpassungsfähig.

—‚

Lizenz

Autor: Jörg Harzmann

Dieser Inhalt ist unter einer CC BY-NC Lizenz veröffentlicht. Jeglicher Quellcode ist urheberrechtlich geschützt!