Clarification of output array type when metrics accept multiclass/multioutput

Clarification of how we should handle array output type when a metric outputs several values (i.e. accepts multiclass or multioutput input).

The issue was summarised succinctly in https://github.com/scikit-learn/scikit-learn/pull/30439#issuecomment-2532238196:

> Not sure what should be the output namespace / device in case we output an array, e.g. roc_auc_score with average=None on multiclass problems...

Currently all regression/classification metrics that support array API and multiclass or multioutput, all output an array in the same namespace and device as the input (checked code and manually). Summary of these metrics :

### Regression metrics

Returns array in same namespace/device:
* [explained_variance_score](https://scikit-learn.org/dev/modules/generated/sklearn.metrics.explained_variance_score.html#sklearn.metrics.explained_variance_score)
* [r2_score](https://scikit-learn.org/dev/modules/generated/sklearn.metrics.r2_score.html#sklearn.metrics.r2_score) 
* [mean_absolute_error](https://scikit-learn.org/dev/modules/generated/sklearn.metrics.mean_absolute_error.html#sklearn.metrics.mean_absolute_error)
* [mean_absolute_percentage_error](https://scikit-learn.org/dev/modules/generated/sklearn.metrics.mean_absolute_percentage_error.html#sklearn.metrics.mean_absolute_percentage_error)
* [mean_pinball_loss](https://scikit-learn.org/dev/modules/generated/sklearn.metrics.mean_pinball_loss.html#sklearn.metrics.mean_pinball_loss)
* [mean_squared_error](https://scikit-learn.org/dev/modules/generated/sklearn.metrics.mean_squared_error.html#sklearn.metrics.mean_squared_error)
* [mean_squared_log_error](https://scikit-learn.org/dev/modules/generated/sklearn.metrics.mean_squared_log_error.html#sklearn.metrics.mean_squared_log_error)
* [root_mean_squared_error](https://scikit-learn.org/dev/modules/generated/sklearn.metrics.root_mean_squared_error.html#sklearn.metrics.root_mean_squared_error)
* [root_mean_squared_log_error](https://scikit-learn.org/dev/modules/generated/sklearn.metrics.root_mean_squared_log_error.html#sklearn.metrics.root_mean_squared_log_error)

### Classification metrics
Returns array in same namespace/device:

* [precision_recall_fscore_support](https://scikit-learn.org/dev/modules/generated/sklearn.metrics.precision_recall_fscore_support.html#sklearn.metrics.precision_recall_fscore_support) and family ([f1_score](https://scikit-learn.org/dev/modules/generated/sklearn.metrics.f1_score.html#sklearn.metrics.f1_score), [fbeta_score](https://scikit-learn.org/dev/modules/generated/sklearn.metrics.fbeta_score.html#sklearn.metrics.fbeta_score), [precision_score](https://scikit-learn.org/dev/modules/generated/sklearn.metrics.precision_score.html#sklearn.metrics.precision_score), [recall_score](https://scikit-learn.org/dev/modules/generated/sklearn.metrics.recall_score.html#sklearn.metrics.recall_score))

Looking at the metrics code, if we wanted to support a list of scalars, we'd generally have to do extra processing to convert an array (often output of an xp.** function) to a list of scalars.

Once we arrive at a consensus we should update the array API documentation and update the `check_array_api_metric` in tests such that when the output is array/list - we check that the output type etc is correct.

cc @ogrisel @betatim

COMMENT:
We discussed this topic in the array API meeting today. My impression was that there were no strong opinions either way. Instead we discussed the question of "what are people going to do with the output of these functions?" - some things we could think of was: print values (maybe rounding to N digits), plot values with matplotlib, put into a pandas DF to then `.describe()` them. Something that is unlikely to happen is that they get fed back into the "machinery" that produced them, unlike say fitted attributes of estimators. This question/train of thought was going towards the direction of "numpy array or array-in-original-namespace, which one is going to be more convenient for the user?"

Another question raised was how much code we'd have to change/add to every metric function to, say, always output numpy arrays.

My personal thoughts: I don't know what the state of "array API support" in matplotlib is. I don't think they are working on supporting the array API, but there has been some thought and work around supporting things that aren't numpy arrays. I think, but this is just speculation, that most users will plot the results of the metrics or otherwise compute simple statistics on them. It seems silly to make every user add code that converts the result of a metric function to a numpy array (if that is what is needed for plotting). Especially because there is (currently) no generic way to take a arbitrary array API array and turn it into a numpy array. But if you can feed a GPU pytorch tensor to matplotlib just like a numpy array this problem goes away.

Keeping the namespace and device consistent with the input is less surprising and what other libraries do. Probably also what people expect to happen, given that metrics tend to be simple arithmetic functions of their inputs.

What do people think are typical "next steps" for the return values of metrics? Does anyone have experience with feeding "array API arrays" to matplotlib?

Labels: Needs Decision, Array API