Prétraitement des catégories ou des dates¶
Comment convertir des catégories ou des dates en features ? That is the question.
TableReport¶
Le module skrub propose des outils assez pratiques pour prendre vite la mesure d’un jeu de données.
[2]:
from skrub import TableReport
from teachpyx.datasets import load_wines_dataset
df = load_wines_dataset()
TableReport(df)
Processing column 13 / 13
[2]:
fixed_acidity | volatile_acidity | citric_acid | residual_sugar | chlorides | free_sulfur_dioxide | total_sulfur_dioxide | density | pH | sulphates | alcohol | quality | color | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 7.4 | 0.7 | 0.0 | 1.9 | 0.076 | 11.0 | 34.0 | 0.9978 | 3.51 | 0.56 | 9.4 | 5 | red |
1 | 7.8 | 0.88 | 0.0 | 2.6 | 0.098 | 25.0 | 67.0 | 0.9968 | 3.2 | 0.68 | 9.8 | 5 | red |
2 | 7.8 | 0.76 | 0.04 | 2.3 | 0.092 | 15.0 | 54.0 | 0.997 | 3.26 | 0.65 | 9.8 | 5 | red |
3 | 11.2 | 0.28 | 0.56 | 1.9 | 0.075 | 17.0 | 60.0 | 0.998 | 3.16 | 0.58 | 9.8 | 6 | red |
4 | 7.4 | 0.7 | 0.0 | 1.9 | 0.076 | 11.0 | 34.0 | 0.9978 | 3.51 | 0.56 | 9.4 | 5 | red |
6492 | 6.2 | 0.21 | 0.29 | 1.6 | 0.039 | 24.0 | 92.0 | 0.99114 | 3.27 | 0.5 | 11.2 | 6 | white |
6493 | 6.6 | 0.32 | 0.36 | 8.0 | 0.047 | 57.0 | 168.0 | 0.9949 | 3.15 | 0.46 | 9.6 | 5 | white |
6494 | 6.5 | 0.24 | 0.19 | 1.2 | 0.0409999999999999 | 30.0 | 111.0 | 0.99254 | 2.99 | 0.46 | 9.4 | 6 | white |
6495 | 5.5 | 0.29 | 0.3 | 1.1 | 0.022 | 20.0 | 110.0 | 0.98869 | 3.34 | 0.38 | 12.8 | 7 | white |
6496 | 6.0 | 0.21 | 0.38 | 0.8 | 0.02 | 22.0 | 98.0 | 0.98941 | 3.26 | 0.32 | 11.8 | 6 | white |
fixed_acidity
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 106 (1.6%)
- Mean ± Std
- 7.22 ± 1.30
- Median ± IQR
- 7.00 ± 1.30
- Min | Max
- 3.80 | 15.9
volatile_acidity
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 187 (2.9%)
- Mean ± Std
- 0.340 ± 0.165
- Median ± IQR
- 0.290 ± 0.170
- Min | Max
- 0.0800 | 1.58
citric_acid
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 89 (1.4%)
- Mean ± Std
- 0.319 ± 0.145
- Median ± IQR
- 0.310 ± 0.140
- Min | Max
- 0.00 | 1.66
residual_sugar
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 316 (4.9%)
- Mean ± Std
- 5.44 ± 4.76
- Median ± IQR
- 3.00 ± 6.30
- Min | Max
- 0.600 | 65.8
chlorides
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 214 (3.3%)
- Mean ± Std
- 0.0560 ± 0.0350
- Median ± IQR
- 0.0470 ± 0.0270
- Min | Max
- 0.00900 | 0.611
free_sulfur_dioxide
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 135 (2.1%)
- Mean ± Std
- 30.5 ± 17.7
- Median ± IQR
- 29.0 ± 24.0
- Min | Max
- 1.00 | 289.
total_sulfur_dioxide
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 276 (4.2%)
- Mean ± Std
- 116. ± 56.5
- Median ± IQR
- 118. ± 79.0
- Min | Max
- 6.00 | 440.
density
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 998 (15.4%)
- Mean ± Std
- 0.995 ± 0.00300
- Median ± IQR
- 0.995 ± 0.00465
- Min | Max
- 0.987 | 1.04
pH
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 108 (1.7%)
- Mean ± Std
- 3.22 ± 0.161
- Median ± IQR
- 3.21 ± 0.210
- Min | Max
- 2.72 | 4.01
sulphates
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 111 (1.7%)
- Mean ± Std
- 0.531 ± 0.149
- Median ± IQR
- 0.510 ± 0.170
- Min | Max
- 0.220 | 2.00
alcohol
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 111 (1.7%)
- Mean ± Std
- 10.5 ± 1.19
- Median ± IQR
- 10.3 ± 1.80
- Min | Max
- 8.00 | 14.9
quality
Int64DType- Null values
- 0 (0.0%)
- Unique values
- 7 (0.1%)
- Mean ± Std
- 5.82 ± 0.873
- Median ± IQR
- 6 ± 1
- Min | Max
- 3 | 9
color
ObjectDType- Null values
- 0 (0.0%)
- Unique values
- 2 (< 0.1%)
Most frequent values
No columns match the selected filter: . You can change the column filter in the dropdown menu above.
Column | Column name | dtype | Null values | Unique values | Mean | Std | Min | Median | Max |
---|---|---|---|---|---|---|---|---|---|
0 | fixed_acidity | Float64DType | 0 (0.0%) | 106 (1.6%) | 7.22 | 1.30 | 3.80 | 7.00 | 15.9 |
1 | volatile_acidity | Float64DType | 0 (0.0%) | 187 (2.9%) | 0.340 | 0.165 | 0.0800 | 0.290 | 1.58 |
2 | citric_acid | Float64DType | 0 (0.0%) | 89 (1.4%) | 0.319 | 0.145 | 0.00 | 0.310 | 1.66 |
3 | residual_sugar | Float64DType | 0 (0.0%) | 316 (4.9%) | 5.44 | 4.76 | 0.600 | 3.00 | 65.8 |
4 | chlorides | Float64DType | 0 (0.0%) | 214 (3.3%) | 0.0560 | 0.0350 | 0.00900 | 0.0470 | 0.611 |
5 | free_sulfur_dioxide | Float64DType | 0 (0.0%) | 135 (2.1%) | 30.5 | 17.7 | 1.00 | 29.0 | 289. |
6 | total_sulfur_dioxide | Float64DType | 0 (0.0%) | 276 (4.2%) | 116. | 56.5 | 6.00 | 118. | 440. |
7 | density | Float64DType | 0 (0.0%) | 998 (15.4%) | 0.995 | 0.00300 | 0.987 | 0.995 | 1.04 |
8 | pH | Float64DType | 0 (0.0%) | 108 (1.7%) | 3.22 | 0.161 | 2.72 | 3.21 | 4.01 |
9 | sulphates | Float64DType | 0 (0.0%) | 111 (1.7%) | 0.531 | 0.149 | 0.220 | 0.510 | 2.00 |
10 | alcohol | Float64DType | 0 (0.0%) | 111 (1.7%) | 10.5 | 1.19 | 8.00 | 10.3 | 14.9 |
11 | quality | Int64DType | 0 (0.0%) | 7 (0.1%) | 5.82 | 0.873 | 3 | 6 | 9 |
12 | color | ObjectDType | 0 (0.0%) | 2 (< 0.1%) |
No columns match the selected filter: . You can change the column filter in the dropdown menu above.
fixed_acidity
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 106 (1.6%)
- Mean ± Std
- 7.22 ± 1.30
- Median ± IQR
- 7.00 ± 1.30
- Min | Max
- 3.80 | 15.9
volatile_acidity
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 187 (2.9%)
- Mean ± Std
- 0.340 ± 0.165
- Median ± IQR
- 0.290 ± 0.170
- Min | Max
- 0.0800 | 1.58
citric_acid
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 89 (1.4%)
- Mean ± Std
- 0.319 ± 0.145
- Median ± IQR
- 0.310 ± 0.140
- Min | Max
- 0.00 | 1.66
residual_sugar
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 316 (4.9%)
- Mean ± Std
- 5.44 ± 4.76
- Median ± IQR
- 3.00 ± 6.30
- Min | Max
- 0.600 | 65.8
chlorides
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 214 (3.3%)
- Mean ± Std
- 0.0560 ± 0.0350
- Median ± IQR
- 0.0470 ± 0.0270
- Min | Max
- 0.00900 | 0.611
free_sulfur_dioxide
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 135 (2.1%)
- Mean ± Std
- 30.5 ± 17.7
- Median ± IQR
- 29.0 ± 24.0
- Min | Max
- 1.00 | 289.
total_sulfur_dioxide
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 276 (4.2%)
- Mean ± Std
- 116. ± 56.5
- Median ± IQR
- 118. ± 79.0
- Min | Max
- 6.00 | 440.
density
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 998 (15.4%)
- Mean ± Std
- 0.995 ± 0.00300
- Median ± IQR
- 0.995 ± 0.00465
- Min | Max
- 0.987 | 1.04
pH
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 108 (1.7%)
- Mean ± Std
- 3.22 ± 0.161
- Median ± IQR
- 3.21 ± 0.210
- Min | Max
- 2.72 | 4.01
sulphates
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 111 (1.7%)
- Mean ± Std
- 0.531 ± 0.149
- Median ± IQR
- 0.510 ± 0.170
- Min | Max
- 0.220 | 2.00
alcohol
Float64DType- Null values
- 0 (0.0%)
- Unique values
- 111 (1.7%)
- Mean ± Std
- 10.5 ± 1.19
- Median ± IQR
- 10.3 ± 1.80
- Min | Max
- 8.00 | 14.9
quality
Int64DType- Null values
- 0 (0.0%)
- Unique values
- 7 (0.1%)
- Mean ± Std
- 5.82 ± 0.873
- Median ± IQR
- 6 ± 1
- Min | Max
- 3 | 9
color
ObjectDType- Null values
- 0 (0.0%)
- Unique values
- 2 (< 0.1%)
Most frequent values
No columns match the selected filter: . You can change the column filter in the dropdown menu above.
Column 1 | Column 2 | Cramér's V |
---|---|---|
total_sulfur_dioxide | color | 0.800 |
volatile_acidity | color | 0.693 |
residual_sugar | density | 0.672 |
chlorides | color | 0.611 |
free_sulfur_dioxide | color | 0.535 |
fixed_acidity | color | 0.510 |
sulphates | color | 0.460 |
citric_acid | color | 0.431 |
free_sulfur_dioxide | total_sulfur_dioxide | 0.391 |
chlorides | sulphates | 0.376 |
density | alcohol | 0.373 |
density | color | 0.358 |
residual_sugar | color | 0.338 |
pH | color | 0.321 |
fixed_acidity | density | 0.284 |
total_sulfur_dioxide | density | 0.248 |
residual_sugar | total_sulfur_dioxide | 0.244 |
volatile_acidity | citric_acid | 0.238 |
alcohol | quality | 0.217 |
residual_sugar | free_sulfur_dioxide | 0.215 |
Please enable javascript
The skrub table reports need javascript to display correctly. If you are displaying a report in a Jupyter notebook and you see this message, you may need to re-execute the cell or to trust the notebook (button on the top right or "File > Trust notebook").
Catégories¶
Les catégories sont assez simples à transformer en variable numériques. La plus populaire des transformations est celle ou une catégorie est diluée sur plusieurs colonnes, une par catégorie : OneHotEncoder.
[4]:
import pandas
from sklearn.preprocessing import OneHotEncoder
data = pandas.DataFrame([{"A": "cat1"}, {"A": "cat2"}, {"A": "cat3"}, {"A": "cat1"}])
ohe = OneHotEncoder()
ohe.fit(data)
ohe.transform(data)
[4]:
<Compressed Sparse Row sparse matrix of dtype 'float64'
with 4 stored elements and shape (4, 3)>
Sparse avez-vous dit ?
[5]:
ohe.transform(data).todense()
[5]:
matrix([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.],
[1., 0., 0.]])
Cette approche fonctionne bien excepté que si il y a beaucoup de catégories ou beaucoup de colonnes catégorielles, le nombre de colonnes explose. Pour y remédier, on peut soit compresser le nombre de colonnes en prenant un hash, la représentation binaire, en éliminant les catégories sous représentées, en les regroupant, en la remplaçant par une valeur numérique TargetEncoder. On peut faire aussi une ACP… Il n’y a pas de bonne ou mauvaise solution dans le cas général. Il faut essayer.
Catégories mal orthographiées¶
Quand elles sont mal orthographiées, les catégories se multiplient. Dans ce cas, on peut soit chercher à corriger manuellement les erreurs soit faire avec, comme par exemple à SimilarityEncoder. Cet estimateur s’appuie sur la proximité des mots ou des caractères.
[9]:
import pandas
from skrub import SimilarityEncoder
data = pandas.DataFrame(
[
{"A": "data scientist"},
{"A": "data scientiste"},
{"A": "datascientist"},
{"A": "alpiniste"},
]
)
sim = SimilarityEncoder()
sim.fit(data)
sim.transform(data)
[9]:
array([[0.04545455, 1. , 0.8125 , 0.6875 ],
[0.14285714, 0.8125 , 1. , 0.55555556],
[0.04761905, 0.6875 , 0.55555556, 1. ],
[1. , 0.04545455, 0.14285714, 0.04761905]])
D’autres options.
[11]:
import pandas
from skrub import StringEncoder
data = pandas.DataFrame(
[
{"A": "data scientist"},
{"A": "data scientiste"},
{"A": "datascientist"},
{"A": "alpiniste"},
]
)
sim = StringEncoder(2)
sim.fit(data.A)
sim.transform(data.A)
[11]:
A_0 | A_1 | |
---|---|---|
0 | 0.943822 | -0.123520 |
1 | 0.907826 | 0.113797 |
2 | 0.824866 | -0.170536 |
3 | 0.157073 | 0.980073 |
Dates¶
Les dates sont toujours à prendre avec des pincettes. Si les données sont corrélées avec le temps, cela montre qu’il y a une tendance mais il y a toujours un risque que le modèle apprennent un comportement attaché à une époque précise, altérant ses performances dans le futur. Il faut donc distinguer ce qui est une tendance et ce qui est lié à la saisonnalité, le jour de la semaine, le mois de l’année. La saisonnalité est une information qui se répète. Aucune année passé ne revient donc l’année est une information qui ne devrait pas faire partie des bases d’apprentissage. L’objet DatetimeEncoder automatise cela mais le plus simple est sans doute d’utiliser le module datetime.
[14]:
import pandas
from skrub import DatetimeEncoder
login = pandas.to_datetime(
pandas.Series(["2024-05-13T12:05:36", None, "2024-05-15T13:46:02"], name="login")
)
dt = DatetimeEncoder(add_weekday=True)
dt.fit(login)
dt.transform(login)
[14]:
login_year | login_month | login_day | login_hour | login_total_seconds | login_weekday | |
---|---|---|---|---|---|---|
0 | 2024.0 | 5.0 | 13.0 | 12.0 | 1.715602e+09 | 1.0 |
1 | NaN | NaN | NaN | NaN | NaN | NaN |
2 | 2024.0 | 5.0 | 15.0 | 13.0 | 1.715781e+09 | 3.0 |