1
$\begingroup$

I want to do cross-validation in sklearn like below, but the predicted result of X still need to be transformed to reduce the distance from y. How to do that with adding a custom function?

model = XGBRegressor(n_estimator = 500,
                     learn_rate = 0.05,
                     random_state = 0)

pipeline = Pipeline( steps = [('preprocessor', preprocessor),
                            ('model', model)
                            ])

scores = -1 * cross_val_score(pipeline, X, y,
                            cv = 3,
                            scoring = 'neg_mean_absolute_error',
                            verbose = 0)

There are only 0 and 1 in y, so I want to round and cut decimals off in the result of X, just after the step for predicting of X.

I maybe need other operations on y in the future. For example, fitting the correct result only includes the numbers like 0.5, 1.5, 2.5 ...

Example:

X - The input

ID Column_1 Column_2 Column_3
0    'A'       10     True
1    'A'       20     False
2    'B'       30     True

y - The correct result

ID Result
0  1
1  0
2  1

The current output

ID Result
0   0.899
1  -0.001
2   1.102

The expected output

ID Result
0    1
1    0
2    1

I have posted this question on Stack Overflow but also get no answers.

$\endgroup$
5
  • $\begingroup$ can you clarify what custom function your are talking about and in which step of your process it comes in? $\endgroup$ Commented Mar 2, 2020 at 15:01
  • $\begingroup$ @BrunoGL There are only 0 and 1 in y, so I want to round and cut decimals off in the result of X, just after the step for predicting of X. $\endgroup$
    – UniversE
    Commented Mar 2, 2020 at 15:09
  • 1
    $\begingroup$ If y is binary, why are you using XGBRegressor instead of XGBClassifier? The actual question sounds like a programming one rather than a data science one; consider moving to stackoverflow? $\endgroup$
    – Ben Reiniger
    Commented Mar 2, 2020 at 15:12
  • $\begingroup$ @BenReiniger Sorry, I am a newbie for data science and don't know much about that. I don't oppose moving the question to SO if that is more appropriate. $\endgroup$
    – UniversE
    Commented Mar 2, 2020 at 15:24
  • $\begingroup$ I think this issue can be solved by simpy using the correct type of model for the problem at hand, i.e. use a classifier instead of a regressor since y is either 0 or 1. I expect XGBClassifier to automatically return binary values. $\endgroup$
    – Oxbowerce
    Commented Mar 22, 2020 at 16:09

1 Answer 1

1
$\begingroup$

If your target values are just 0 and 1, you should probably be treating it as classification, and use e.g. XGBClassifier instead of XGBRegressor.

You brought up (originally in the comments on your SO post, now edited into your questions) a scenario when your true values might be limited to 0.5, 1.5, 2.5. That's unusual enough that I suspect the best answer depends on context, but:

  1. Consider ordinal regression, which treats the target values as ordered but non-numeric.

  2. If the values really are to be treated numerically, then you're left with (I think) doing it manually, which is closest to your original question. (I'd like to stress one more time that this is odd, and optimizing your loss function may do something unintuitive.) Since the predictions out of sklearn will be numpy arrays, maybe try numpy.digitize.

    Notes: This is useful for post-processing, but won't be easy to incorporate into the model fitting nor a pipeline (since sklearn's predict doesn't behave the same way as transform). If you really need to process the continuous predictions before scoring inside a model fit, I think you're left with hacking the model's code a bit; and with xgboost, that'd be quite a task.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.