FIX Dataframe support in KNN.predict - #26772
Conversation
|
cc/ @jjerphan |
jjerphan
left a comment
There was a problem hiding this comment.
LGTM. Thank you, @jeremiedbb.
| @@ -96,7 +96,9 @@ def is_usable_for(cls, X, Y, metric) -> bool: | |||
| """ | |||
|
|
|||
| def is_numpy_c_ordered(X): | |||
There was a problem hiding this comment.
Side-note: if there are any other libraries that implement the buffer protocol in Python and that we could support, we might want to adapt this.
|
|
||
| def is_numpy_c_ordered(X): | ||
| return hasattr(X, "flags") and X.flags.c_contiguous | ||
| if not hasattr(X, "flags"): |
There was a problem hiding this comment.
I don't quite understand why this fixes it :( I always thought that something like bool(expr1 and expr2) will not evaluate expr2 if expr1 is False. From the bug report it looks like hasattr(X, "flags") will be False, but then why did it continue into evaluating X.flags.c_contiguous. And even more confusingly the exception is AttributeError: 'Flags' object has no attribute 'c_contiguous', which makes me think that hasattr(X, "flags") evaluates as True when you use a DF as input. But then there is a new test and that passes. So overall I am left confused :-/
There was a problem hiding this comment.
Or is the thing that actually fixes it the getattr(X.flags, "c_contiguous", False)?
There was a problem hiding this comment.
which makes me think that hasattr(X, "flags") evaluates as True when you use a DF as input.
Yep, a dataframe has a flags attribute, but this flags has no c_contiguous attribute :)
There was a problem hiding this comment.
Or is the thing that actually fixes it the getattr(X.flags, "c_contiguous", False)?
indeed. Your understanding of the conditional evaluation of expr1 and expr2 is correct
There was a problem hiding this comment.
So we could have kept a one-liner then:
return hasattr(X, "flags") and getattr(X.flags, "c_contiguous", False)There was a problem hiding this comment.
hi every one so i have same prblm here 'AttributeError: 'Flags' object has no attribute 'c_contiguous''
and i dont understand the solution u given before . any one can help ?
Co-authored-by: Julien Jerphanion <[email protected]>
|
the doc failure is probably due to #26773 |
thomasjpfan
left a comment
There was a problem hiding this comment.
Thanks for the PR! Overall looks good.
| return False | ||
| return getattr(X.flags, "c_contiguous", False) |
There was a problem hiding this comment.
Nit: (Ask for forgiveness and not permission)
def is_numpy_c_ordered(X):
try:
return X.flags.c_contiguous
except AttributeError:
return FalseThere was a problem hiding this comment.
I'm usually not a huge fan of try excepts because it hides stuff. With that it would not have crashed in the first place but it means that we would have never noticed that since we're not validating X at the beginning of predict, passing a dataframe will always take the legacy route.
There was a problem hiding this comment.
jeremiedbb i am very new to this. I have the exact same issue with c_contiguous flag.
Can you please explain what steps I must follow to fix this? I am afraid I can't quite follow what I should do to fix this issue. Please help.
There was a problem hiding this comment.
This bug will be fixed in scikit-learn 1.3.1 that we plan to release soon. In the mean time you can use version 1.2 which does not have this bug.
There was a problem hiding this comment.
@jeremiedbb I upgraded to scikit-learn 1.4.0 but im still getting this issue c_contiguous flag when I run knn.predict. please help!
But shouldn't we just validate the data in |
|
I think it's not the role of the lower level ArgKMin API to have to deal with non-numpy inputs. I think it's the estimators role to make sure that it calls its Cython backend with the proper datastructure. |
|
Yes, but X is validated in |
I agree but I wanted a quick fix. I'm okay to make the refactoring I explained above as part of this PR if you think it's better |
This might be costly to from Fortran-contiguous data to C-contiguous datasets, but we might want to consider a configuration option to specify the behavior. FYI, this is one item of #25888. |
Indeed, this might increase memory usage by a lot for such users. But it should also make the code run significantly faster. Maybe we could extend the pairwise distance + reduction Cython classes to accept large F-aligned input, in which case the outer loop would load rowise slices of the input in parallel into C-contiguous chunks to perform the actual computation in parallel on rows of Ok let's be pragmatic and merge this quick fix and see later what to do in a PR for 1.4. |
Generally in pipeline we might have different steps which necessitates either C- or F-contiguous inputs to work (efficiently). Thus I think converting is a tradeoff whose choice which should be left to the user via the configuration for instance.
I thought of it in the past, and I do not think coming up with equivalent and efficient implementations for F-contiguous data is doable for |
|
hi every one so i have same prblm here 'AttributeError: 'Flags' object has no attribute 'c_contiguous'' |
|
@00kira00: the problem you describe is fixed by this PR. |
|
Should we make an issue to discuss #26772 (comment) and what to do? |
I think it makes sense. |
Co-authored-by: Julien Jerphanion <[email protected]> Co-authored-by: Olivier Grisel <[email protected]>
Co-authored-by: Julien Jerphanion <[email protected]> Co-authored-by: Olivier Grisel <[email protected]>
Co-authored-by: Julien Jerphanion <[email protected]> Co-authored-by: Olivier Grisel <[email protected]>
Co-authored-by: Julien Jerphanion <[email protected]> Co-authored-by: Olivier Grisel <[email protected]>
Fixes #26768
knn.predict doesn't validate X right away because it call
kneighborsthat does validate X.The issue is that
ArgKMin.is_usable_forassumes that it's a numpy array. This PR simply adds a check there. Note that it is not usable for a pandas dataframe anyway because it's not c-contiguous.