150 lines
6.1 KiB
Markdown
150 lines
6.1 KiB
Markdown
# ENGIN Diagnostic Console
|
||
|
||
Gotowy do demonstracji system diagnostyki cylindrów przemysłowych silników Diesla. Z pomiaru widma 0–20 kHz rozpoznaje stan każdego cylindra, przewiduje nasilenie usterki i pokazuje mechanikowi, które pasma oraz cylindry wymagają uwagi.
|
||
|
||
## Uruchomienie
|
||
|
||
Wymagany jest Python 3.12 (3.11 również powinien działać).
|
||
|
||
```bash
|
||
python -m venv .venv
|
||
source .venv/bin/activate
|
||
pip install -r requirements-lock.txt
|
||
streamlit run app.py
|
||
```
|
||
|
||
Windows PowerShell:
|
||
|
||
```powershell
|
||
py -m venv .venv
|
||
.venv\Scripts\Activate.ps1
|
||
pip install -r requirements-lock.txt
|
||
streamlit run app.py
|
||
```
|
||
|
||
Aplikacja otworzy się pod `http://localhost:8501`. Od razu uruchamia bezpieczne demo na `test.csv`; w panelu bocznym można przełączyć się na własny CSV.
|
||
|
||
Alternatywnie przez Docker:
|
||
|
||
```bash
|
||
docker build -t engin-console .
|
||
docker run --rm -p 8501:8501 engin-console
|
||
```
|
||
|
||
## Co zawiera produkt
|
||
|
||
- mapa 8-, 12- i 16-cylindrowych silników z diagnozą każdego cylindra,
|
||
- typ usterki: `ok`, `zakoksowany`, `lejacy`, `pompa`, `iglica` lub `unknown`,
|
||
- nasilenie: `male`, `srednie`, `duze`; dla `ok` i `unknown` zawsze `nie_dotyczy`,
|
||
- status silnika, najwyższe rzeczywiste severity i kolejka cylindrów do kontroli,
|
||
- heatmapa odchyleń całego silnika,
|
||
- porównanie widma cylindra z medianą pozostałych cylindrów tej samej jednostki,
|
||
- trzy najbardziej anomalne pasma, niekalibrowany score modelu oraz rekomendowany następny krok,
|
||
- pobieranie `predictions.csv` i rozszerzonej diagnostyki,
|
||
- ścisła walidacja CSV i bezpieczne komunikaty błędów,
|
||
- lokalne działanie na CPU, bez wysyłania danych do zewnętrznych usług.
|
||
|
||
## Architektura
|
||
|
||
Interfejs jest cienką warstwą prezentacji. Zależności są wstrzykiwane do `DiagnosticService`, dlatego odczyt pliku, walidator i model można niezależnie wymieniać oraz testować.
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
UI["Streamlit UI"] --> S["DiagnosticService"]
|
||
S --> R["FrameReader"]
|
||
S --> V["FrameValidator"]
|
||
S --> M["PredictionModel"]
|
||
S --> E["Explainability + wykresy"]
|
||
```
|
||
|
||
Najważniejsze katalogi i pliki:
|
||
|
||
```text
|
||
app.py cienka warstwa Streamlit
|
||
engin/io.py adapter odczytu CSV
|
||
engin/validation.py kontrakt i walidacja danych
|
||
engin/model.py adapter modelu i fallback demo
|
||
engin/service.py przypadek użycia / dependency injection
|
||
engin/explainability.py status, porządkowy triage i uzasadnienia
|
||
engin/charts.py czyste, testowalne fabryki Plotly
|
||
final_pipeline.py finalny pipeline konkursowy
|
||
tests/ testy aplikacji, błędów i komponentów
|
||
docs/DEMO_SCENARIO.md gotowy scenariusz prezentacji 3–5 min
|
||
docs/JURY_QA.md odpowiedzi na typowe pytania jury
|
||
```
|
||
|
||
## Model i wynik
|
||
|
||
Finalna architektura została wybrana w walidacji `StratifiedGroupKFold` po `engine_id`, bez mieszania cylindrów tego samego silnika:
|
||
|
||
- label: odchylenie od mediany pozostałych cylindrów + Logistic Regression (`C=10`),
|
||
- OOD: `ok` zmienia się na `unknown` tylko po przekroczeniu progu 7.25 mV oraz 2.5× mediany anomalii własnego silnika,
|
||
- severity: cechy odchylenia + Extra Trees (`max_features=0.3`),
|
||
- braki widma: interpolacja wzdłuż częstotliwości z deterministycznym fallbackiem,
|
||
- inference na CPU, bez CNN i bez GPU.
|
||
|
||
| Scenariusz walidacji | Macro F1 | Severity accuracy | Raw Score | Punkty ML |
|
||
| --- | ---: | ---: | ---: | ---: |
|
||
| clean | 0.9811 | 0.9298 | 0.9683 | 33.65/40 |
|
||
| dokładnie 5% braków | 0.9829 | 0.9333 | 0.9705 | 34.10/40 |
|
||
|
||
To średnie z pięciu seedów walidacji grupowej, nie wynik ukrytego testu. Negative control dla severity pozostaje w okolicy losowego poziomu, co zmniejsza ryzyko pozornego wyniku przez leakage.
|
||
|
||
Jedynym źródłem finalnych metryk jest `ml_polish_benchmark.py` oraz pliki `ml_polish_summary.csv`/`ml_polish_runs.csv`. Starsze eksperymenty zostały przeniesione do `archive/legacy_experiments/` i jawnie oznaczone jako niewłaściwe do raportowania finalnego wyniku.
|
||
|
||
Score zwracany przez `predict_proba` służy tylko do względnego porównania predykcji i nie jest przedstawiany jako skalibrowane prawdopodobieństwo awarii. Dla decyzji OOD score label jest celowo pusty, ponieważ OOD jest regułą bezpieczeństwa, a nie klasą modelu probabilistycznego.
|
||
|
||
Finalne pliki można odtworzyć poleceniem:
|
||
|
||
```bash
|
||
python final_pipeline.py
|
||
```
|
||
|
||
Powstają `predictions.csv` (600/600 rekordów, bez duplikatów i braków) oraz `prediction_diagnostics.csv` używany przez aplikację do explainability.
|
||
|
||
## Kontrakt danych wejściowych
|
||
|
||
Każdy wiersz reprezentuje cylinder. Wymagane kolumny:
|
||
|
||
- `engine_id`,
|
||
- `cylinder`,
|
||
- `n_cylinders` równe 8, 12 albo 16,
|
||
- `mV_0` … `mV_20`.
|
||
|
||
Każdy silnik musi zawierać dokładnie cylindry `1..n_cylinders`. Aplikacja odrzuca między innymi puste i zbyt duże pliki, brakujące kolumny, duplikaty cylindrów, tekst w widmie, wartości ujemne/nieskończone, niespójny rozmiar jednostki i ponad 50% braków w jednym cylindrze. Mniejsza liczba braków jest uzupełniana tak samo jak podczas walidacji modelu.
|
||
|
||
## Testy i weryfikacja
|
||
|
||
Pełna kontrola projektu:
|
||
|
||
```bash
|
||
python -m unittest discover -v
|
||
```
|
||
|
||
Pakiet zawiera 32 testy:
|
||
|
||
- testy braku leakage, cech, OOD i kontraktu submission,
|
||
- testy jednostkowe walidatora i błędnych CSV,
|
||
- testy serwisu z fake reader/validator/model — weryfikują dependency injection,
|
||
- testy explainability, rankingu i wykresów,
|
||
- testy smoke Streamlit dla demo, pustego uploadu i synchronizacji mapy cylindrów ze szczegółami.
|
||
|
||
Szybka kontrola serwera:
|
||
|
||
```bash
|
||
streamlit run app.py --server.headless true
|
||
# drugi terminal
|
||
curl --fail http://localhost:8501/_stcore/health
|
||
```
|
||
|
||
Oczekiwana odpowiedź: `ok`.
|
||
|
||
## Odporność operacyjna
|
||
|
||
- Model jest trenowany raz i przechowywany w cache procesu.
|
||
- Nieoczekiwany błąd inicjalizacji modelu uruchamia read-only fallback dla danych demo.
|
||
- Nieprawidłowe dane nie docierają do modelu.
|
||
- Błędy użytkownika mają stabilne kody i nie pokazują tracebacków w interfejsie.
|
||
- Zależności produkcyjne są przypięte w `requirements-lock.txt`.
|
||
- Aplikacja nie zmienia przesłanego pliku i nie wykonuje połączeń zewnętrznych.
|