hackathon-ENGIN/README.md

161 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ENGIN Diagnostic Console
Gotowy do demonstracji system diagnostyki cylindrów przemysłowych silników Diesla. Z pomiaru widma 020 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 35 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.
## Materiały konkursowe
- [Scenariusz demo](docs/DEMO_SCENARIO.md)
- [Pytania i odpowiedzi dla jury](docs/JURY_QA.md)
- [Odpowiedź na przegląd i testy regresyjne](docs/REVIEW_RESPONSE.md)
- `predictions.csv` — finalny submission
- `prediction_diagnostics.csv` — rozszerzone dane do produktu
- `presentation/ENGIN_pitch_deck.pptx` — prezentacja konkursowa
Formuła konkursowa: `Raw Score = 0.75 × Macro F1(label) + 0.25 × Accuracy(severity dla uszkodzonych)`. Część ML daje maksymalnie 40 punktów; produkt, explainability, wydajność i prezentacja — 60 punktów.