khiops icon indicating copy to clipboard operation
khiops copied to clipboard

multi-tables unsupervised training, one-column root table : khiops assumes wrongly the additional table has no header line

Open tramora opened this issue 1 year ago • 2 comments

Description

Our colleague Romain T. raised the issue on automl a few weeks ago. After a few recent tests it seems that the problem is on the khiops side (even on the today latest stable 10.2.2-1 version).

On "a multi-tables unsupervised training with only one column root table : khiops assumes wrongly the additional table has no header line" and treats this line as data even if the HeaderLineUsed flag is set to true (cf minimal_scenario.kh)

It makes the data preparation fail.

Extract of the error logs :

Train unsupervised model
warning : Data table /tmp/S_Adult_by_label.txt : Record 1 : Numerical variable age: value <age> converted to <> (Unconverted string)
warning : Data table /tmp/S_Adult_by_label.txt : Record 1 : Numerical variable fnlwgt: value <fnlwgt> converted to <> (Unconverted string)
warning : Data table /tmp/S_Adult_by_label.txt : Record 1 : Numerical variable education_num: value <education_num> converted to <> (Unconverted end of string)
warning : Data table /tmp/S_Adult_by_label.txt : Record 1 : Numerical variable capital_gain: value <capital_gain> converted to <> (Unconverted string)
warning : Data table /tmp/S_Adult_by_label.txt : Record 1 : Numerical variable capital_loss: value <capital_loss> converted to <> (Unconverted string)
warning : Data table /tmp/S_Adult_by_label.txt : Record 1 : Numerical variable hours_per_week: value <hours_per_week> converted to <> (Unconverted string)
error : Data table /tmp/S_Adult_by_label.txt : Record 2 : Unsorted record Adult_data[1], with key inferior to that of the preceding record Adult_data[Label]
Data preparation interrupted because of errors

Workaround 1 (Thierry)

The first obvious workourand I found is to manually remove the header lines on BOTH the root table and the additional table (removing it on the additional table only is not enough)

Workaround 2 (Romain)

Romain proposed another strange workaround that works :

  • transform the root table from one column to a multi-columns in adding a dummy column
  • modify accordinly the kdic file to refer to this dummy column

Question about sorting

If sorting steps are inserted before the training one (cf scenario_with_sorting.kh), the header line is systematically written by khiops in the sorted file and this "breaks" the workaround 1.

Context

  • Khiops version : 10.2.2-1
  • Log file (use khiops -e log.txt) : extract provided above
  • Scenario files : mininal_scenario.kh, scenario_with_sorting.kh (files.zip)
  • OS description (use khiops -s) : Linux/Ubuntu/20.04/Focal

Thanks in advance for your explanation and the possible fixes !

tramora avatar Aug 08 '24 15:08 tramora

Le scénario n'est pas minimal

  • cf. lignes 23 à 25 de minimal_scenario._kh
TrainDatabase.HeaderLineUsed true
TrainDatabase.FieldSeparator 
TrainDatabase.DatabaseFormatDetector.DetectFileFormat
  • un "DetectFileFormat" est ajouté suite a la spécification du flag HeaderLineUsed à true, ce qui l'annule
  • on le voit d'ailleurs dans le log:
File format detected: no header line and field separator tabulation
warning: Database format detector ./Labels_from_Adult.txt : one single field has been detected in the file 
  and a default field separator has been choosen

Bug connu dans pykhiops, à corriger

Ce problème provient probablement de pykhiops, pour une issue déjà identifiée:

  • cf. https://github.com/KhiopsML/khiops-python/issues/208

Bug à corriger dans khiops

Sinon, le DetectFileFormat ne devrait pas échouer dans ce cas, même s'il s'agit d'une heuristique. Dans cet effet de bord, comme la première ligne contient correctement le nom de l'unique champs natif du dictionnaire, on devrait reconnaitre correctement qu'il y a une ligne d'entête.

Amélioration à considérer également:

  • dans le cas multi-table, avec la table principale ayant un seul champ, il n'est pas possible de détecter correctement le séparateur de champs
  • dans ce cas, se servir si possible d'une table secondaire ayant au moins deux champs pour détecter le format
    • faut-il préciser dans le message utilisateur que ce n'est pas le premier fichier qui a été utilisé?

Question sur le sort

Dans le scénario scenario_with_sorting.kh, une ligne d'entête est explicitement spécifée pour la table en sortie (cf. TargetDataTable.HeaderLineUsed true). Il est possible de spécifier que l'on ne veut pas de ligne d'entête en sortie.

Problème probablement lié à l'utilisation de la fonction sort_data_table de pykhiops, dont le paramètre optionnel output_header_line est à true par défaut. Cf. https://khiopsml.github.io/khiops-python/core/generated/khiops.core.api.html#khiops.core.api.sort_data_table

marcboulle avatar Aug 12 '24 12:08 marcboulle

Merci pour ta réponse détaillée @marcboulle.

khiops-python se fie déjà sur la précédence du DetectFileFormat sur HeaderLineUsed lorsque les 2 sont fournis pour obtenir le comportement attendu mais tu as raison il faut que nous générions des directives non ambiguës pour un lecteur humain. (remarque faite dans khiops-python#208).

Pour résumer dans ce cas précis de defect,

  • le scenario minimal passe si le paramètre TrainDatabase.HeaderLineUsed seul est positionné à true -- correction à faire côté khiops-python (plus précisement khiops_api_base)
  • il échoue si on laisse l'auto détection se faire (TrainDatabase.DatabaseFormatDetector.DetectFileFormat) -- correction à faire côté khiops

tramora avatar Aug 12 '24 17:08 tramora