Repository: evidentlyai/evidently
Issue: Bug: Classification metrics do not support label names containing numbers
Root cause: Validation Gap

In Evidently 0.4.19 with Python 3.10, the ClassificationQualityMetric() and ClassificationConfusionMatrix() (these are the one I tested but i suspect other metrics to be impacted) throw an error when some data labels contain numerical values. Even if the dataframe column type is specified as string.
See sample code below:
```
from evidently.report import Report
from evidently.metrics import *
import pandas as pd

label_target = ['foo', 'bar', 'fun', 'foo', 'fun', 'foo', '101', '102']
label_predict = ['foo', 'bar', 'fun', 'bar', 'fun', 'fun', '101', '101']
data_df = pd.DataFrame({'target': label_target, 'prediction': label_predict}, dtype="string")

report = Report(metrics=[
    ClassificationQualityMetric(),
    ClassificationConfusionMatrix(),
])
report.run(reference_data=None, current_data=data_df)
report
```
It ends up with the following error:
```
File ~/anaconda3/envs/python3/lib/python3.10/site-packages/evidently/calculations/classification_performance.py:316, in calculate_matrix(target, prediction, labels)
    315 def calculate_matrix(target: pd.Series, prediction: pd.Series, labels: List[Union[str, int]]) -> ConfusionMatrix:
--> 316     sorted_labels = sorted(labels)
    317     matrix = metrics.confusion_matrix(target, prediction, labels=sorted_labels)
    318     return ConfusionMatrix(labels=sorted_labels, values=[row.tolist() for row in matrix])

TypeError: '<' not supported between instances of 'str' and 'int'
```
Adding a char (like a dot) at the end of the label name numbers fixes the issue:
```
label_target = ['foo', 'bar', 'fun', 'foo', 'fun', 'foo', '101.', '102-']
label_predict = ['foo', 'bar', 'fun', 'bar', 'fun', 'fun', '101.', '101.']
```
But I do not think that this is the expected behavior and that the dataframe column type should be respected all along the metric(s) computation.

@florianbodr I looked into this error this weekend and its because there is an implicit conversion happening for classification metrics. With classification labels, the resulting data type `PredictionData` always tries to first convert each unique label to type `int` and if it can't, then it just returns the value. This is why you're seeing that behavior where it keeps the strings (because they can't be converted to ints) and converts them otherwise. 

This is where it's happening in `metric_results.py`, the strings `'101', '102'` are preserved up until it tries to deliver the cleaned/formatted data and uses this validator.

<img width="382" alt="Image" src="https://github.com/user-attachments/assets/8791c472-f823-405c-8c8b-8fe8a189c0fe" />

Specifically, the `labels` object here in `classification_performance.py` is the data that takes on this new `Label` type that can be a list of types `int` or `string`.

<img width="381" alt="Image" src="https://github.com/user-attachments/assets/e31e6d6e-50ef-4a2f-b394-8fddac16b2f7" />

@elenasamuylova I'm not sure if this is a "bug" or not, but its something that could be improved especially since the part that fails is the `sorted(labels)` part that is not involved in the actual calculation, more of just an aesthetic for the output. 

<img width="614" alt="Image" src="https://github.com/user-attachments/assets/3694f784-518c-4aba-ba42-6a1afcc347ed" />

Happy to work on this as well, just depends on the desired behavior.