average_precision_score produces unexpected output when scoring a single sample

### Describe the bug

When using `average_precision_score` and scoring a single sample, the metric ignores `y_score` and will always produce a score of 1.0 if `y_true = [1]` and otherwise will return a score of 0. I would have expected that it would instead raise an exception.

Potentially related to #30147, however I'm focusing on the minimal example with just a single sample.

### Steps/Code to Reproduce

```python
from sklearn.metrics import average_precision_score

y_score = [0]
y_true = [1]
score = average_precision_score(y_true=y_true, y_score=y_score)
print(score)  # 1.0

y_score = [1]
y_true = [1]
score = average_precision_score(y_true=y_true, y_score=y_score)
print(score)  # 1.0

y_score = [0.5]
y_true = [1]
score = average_precision_score(y_true=y_true, y_score=y_score)
print(score)  # 1.0

y_score = [0]
y_true = [0]
score = average_precision_score(y_true=y_true, y_score=y_score)
print(score)  # 0.0

y_score = [1]
y_true = [0]
score = average_precision_score(y_true=y_true, y_score=y_score)
print(score)  # 0.0

y_score = [0.5]
y_true = [0]
score = average_precision_score(y_true=y_true, y_score=y_score)
print(score)  # 0.0
```

Additionally, you can see that the average_precision_score returns a score opposite of what precision and recall return:

```python
from sklearn.metrics import average_precision_score, precision_score, recall_score

y_score = [0]
y_true = [1]

score = average_precision_score(y_true=y_true, y_score=y_score)
print(score)  # 1.0
score = precision_score(y_true=y_true, y_pred=y_score)
print(score)  # 0.0
score = recall_score(y_true=y_true, y_pred=y_score)
print(score)  # 0.0
```

### Expected Results

I would have expected the metric to raise an exception, similar to what happens when ROC_AUC is called with a single sample:

```python
score = roc_auc_score(y_true=y_true, y_score=y_score)
print(score)

```

```
ValueError: Only one class present in y_true. ROC AUC score is not defined in that case.
```

### Actual Results

Refer to code snippets above.

### Versions

```shell
System:
    python: 3.11.10 | packaged by conda-forge | (main, Sep 30 2024, 18:08:57) [GCC 13.3.0]
executable: /opt/conda/envs/ag-311/bin/python
   machine: Linux-5.15.0-1056-aws-x86_64-with-glibc2.31

Python dependencies:
      sklearn: 1.5.1
          pip: 24.2
   setuptools: 60.2.0
        numpy: 1.26.4
        scipy: 1.12.0
       Cython: None
       pandas: 2.2.3
   matplotlib: 3.9.2
       joblib: 1.4.2
threadpoolctl: 3.5.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
    num_threads: 128
         prefix: libopenblas
       filepath: /opt/conda/envs/ag-311/lib/libopenblasp-r0.3.28.so
        version: 0.3.28
threading_layer: pthreads
   architecture: SapphireRapids

       user_api: blas
   internal_api: openblas
    num_threads: 64
         prefix: libopenblas
       filepath: /opt/conda/envs/ag-311/lib/python3.11/site-packages/scipy.libs/libopenblasp-r0-23e5df77.3.21.dev.so
        version: 0.3.21.dev
threading_layer: pthreads
   architecture: Cooperlake

       user_api: openmp
   internal_api: openmp
    num_threads: 192
         prefix: libgomp
       filepath: /opt/conda/envs/ag-311/lib/python3.11/site-packages/scikit_learn.libs/libgomp-a34b3233.so.1.0.0
        version: None
```
```

COMMENT:
If it turns out that 1 sample should be valid, it might be good for somewhere in the docstring to mention the behavior in this special case, since the current behavior is due to the additional synthetic sample appended to the input as detailed in #30147.

The confusion on my end came from the concept of the average being an "area", but there is no area under the curve for a single sample, because there is no curve.

For context, I'm trying to categorize most of scikit-learn's metrics [by their behavior characteristics in AutoGluon](https://github.com/autogluon/autogluon/blob/789ec59deb344340beb836f03ff8f9ea1e559b46/core/src/autogluon/core/metrics/__init__.py#L23-L234) so that I can programmatically check if a certain metric will raise an exception in a given situation (or become a degenerate score) and then implement safeguards (for example, dropping rare classes, stratified splits, warnings to the user, adding epsilons, etc.), as well as for optimization (is the mean of scores from two halves of the data the same as the score on the full data). I don't think there is anything like that in sklearn, but it would be a really awesome feature if it was added at some point.

Labels: Bug, Needs Investigation