-
-
Notifications
You must be signed in to change notification settings - Fork 25.8k
META OHE / OrdinalEncoder: NaN support, unfrequent cat. and pd.Categorical #15796
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I note that OrdinalEncoder does not currently have any handling of categories not seen at fit.
If we want to support estimators, here and elsewhere, that learn directly from data with missing values, we're best propagating the missingness rather than imputing.
I think so. I think ordering should be respected even when ordered=False, since ordered=False is the default, and since it would be easier to use s.codes than to remap them. But I could be persuaded to respect the order only when ordered=True.
I think if there is a categorical dtype at fit time, then unknown categories appearing at transform time should raise an error. This should be included in
I'm not certain, but maybe just make the column with 0s, for correspondence with when one explicitly sets the categories.
This does not pertain to OrdinalEncoder, where we don't even know how to handle unknowns. But infrequent category handling is more straightforward than unknowns when ordinal encoding, because at least in the case of infrequents, we "know" the order where the value should appear, and either conflate with the greater or lesser category.
I think in OrdinalEncoder, the only encoding of NaN should be as NaN. I don't think that handling NaN as a separate category is a problem in OHE (and I don't see why we need to modify the dtype). When absent from training, I would just output a row of zeros.
My instinct is to treat it as special, not an infrequent cat, but I am not wedded to this position.
I don't get why we're modifying the dtype, except for efficiency. And if for efficiency, then we do whatever is pragmatic, as long as it's hidden from the user, i.e. creates no API stability issues.
The convention is to return a list from
It's fine to ask the user to handle infrequents themselves (with the caveat that they'll likely mess up the train-test split)... but if we want to handle it in our encoders, then I don't think we can do that by modifying the input... so I don't understand this suggestion, until I read the next paragraph where I see you are considering handling infrequent categories in a different transformer. If we can design an InfrequentCategoryTransformer, I'm okay with that... I'm not yet convinced that it will work without duplicating a lot of the stuff (either the implementation, or the need to specify parameters redundantly) from OHE or OrdinalEncoder, nor am I convinced that we can decouple the handling of pd.Categorical from encoders entirely. I'd be keen to see this framed around some test cases as @thomasjpfan has done for one small piece of the pie. |
Are the above-proposed improvements now implemented in OneHotEncoder ? |
Still in progress |
There is also another feature request for a small but usability improvement to make it possible to use a shared encoding value for unknowns and infrequent features (as done in |
There have been 3 significant improvements proposed for
OneHotEncoder
(and to a lesser extentOrdinalEncoder
), often with an associated PR,pd.Categorical
dtype (issue Handle pd.Categorical in encoders #14953, PR [MRG] ENH Adds categories='dtypes' option to OrdinalEncoder and OneHotEncoder #15396)the goal of this issue to have a high level agreement on the desired solution, that it is consistent/compatible for different available encoders, or encoders that we may want to add in the near future (e.g. target encoder, #5853). Some of the possible solutions for the above 3 features are mutually exclusive. Also putting aside aside backward compatibility constraints for a start, what default options we would want ideally.
I have not followed in detail all past discussions about encoders (in particular about ordering concerns #15050). Following are some of the observations / open questions I have, please add more if I missed something/link with existing comments.
NaN support
pd.Categorical support
categories='dtype'
would make OHE categories match categories in the dtype? Including the ordering? But then, this means only at fit since, for transform, the test set could have unknown categories.
fit_transform
, or disregard this column breaking the assumption of conforming to dtype categories? Solution proposed by @thomasjpfan in [MRG] ENH Adds categories='dtypes' option to OrdinalEncoder and OneHotEncoder #15396 (comment)pd.Categorical
for computational efficiency internally, what is the point of defining acategories='dtype'
in the first place (or warning that categories order doesn't match the order of categories in dtype [MRG] ENH Adds warning with pandas category does not match lexicon ordering #15050).Infrequent categories
Overall the plan seems fairly clear in #12153 (comment)
NaN & pd.Categorical
NaN
as a separate category, means we are no longer using purely the categories from the dtype (even withdtype='category'
) which can be fine as long as we agree on it.CategoricalPreprocessor
to addNaN
as a new dtype category in a separate preprocessing step,df[column].value_counts()
would then show NaN properly and one might want to do it for exploratory analysis in any case.NaN & infrequent categories
pd.Categorical and infrequent categories
infrequent
as a category to dtype, instead of doing that internally in encoders. Say to evaluate how many infrequent elements one has, I find that doing (approximately),df['col'].cat.categories
previously and we are using all the nice features ofpd.Categorical
.So there is some tension here between adding these features to scikit-learn and keeping exploratory analysis with pandas user friendly (and not asking users to implement the same thing twice).
Given the complexity of this interaction, maybe separating "Imputer + Unfrequent categories conversion with pd.Categorical support" and "OneHot, Ordinal, Target etc encoder" into 2 or 3 estimators might be easier to understand? Not sure about usability though. The alternative that would mean we also plan to add these features (and enforce consistency) for any future encoder.
cc @thomasjpfan @NicolasHug @glemaitre @jorisvandenbossche @amueller @jnothman @ogrisel
The text was updated successfully, but these errors were encountered: