fix(ml): type is_working_hours pour que LightGBM accepte une lecture sans valeur
`reading.is_working_hours` est nullable et fait partie des features. Une seule lecture a NULL dans la fenetre suffisait a rendre la colonne `object` au retour de `pd.read_sql`, et LightGBM refuse alors de construire son Dataset : "pandas dtypes must be int, float or bool". La panne n'arrivait qu'au scoring, sur la vraie base, jamais en test. `_typer` coerce donc aussi cette colonne, comme les colonnes mesurees : NaN vaut valeur manquante, que LightGBM gere nativement. Effet de bord voulu, les deux chargeurs rendent enfin le meme dtype : `load_from_csv` faisait un `astype(bool)` qui ecrasait silencieusement une valeur absente en `False`.
This commit is contained in:
@@ -43,6 +43,10 @@ NUMERIC_COLUMNS = [
|
|||||||
"capacity_kw",
|
"capacity_kw",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Piege : `reading.is_working_hours` est nullable et entre dans les features. Une seule lecture a
|
||||||
|
# NULL rend la colonne `object`, que LightGBM refuse ("pandas dtypes must be int, float or bool").
|
||||||
|
FLAG_COLUMNS = ["is_working_hours"]
|
||||||
|
|
||||||
_READING_QUERY = text(
|
_READING_QUERY = text(
|
||||||
"""
|
"""
|
||||||
SELECT
|
SELECT
|
||||||
@@ -126,6 +130,6 @@ def _typer(frame: pd.DataFrame) -> pd.DataFrame:
|
|||||||
scoring -- ce n'est pas un effet de bord limite aux colonnes mesurees.
|
scoring -- ce n'est pas un effet de bord limite aux colonnes mesurees.
|
||||||
"""
|
"""
|
||||||
typee = frame.copy()
|
typee = frame.copy()
|
||||||
for colonne in NUMERIC_COLUMNS:
|
for colonne in (*NUMERIC_COLUMNS, *FLAG_COLUMNS):
|
||||||
typee[colonne] = pd.to_numeric(typee[colonne], errors="coerce")
|
typee[colonne] = pd.to_numeric(typee[colonne], errors="coerce")
|
||||||
return typee
|
return typee
|
||||||
|
|||||||
Reference in New Issue
Block a user