Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/multilabel confusion matrix #51

Merged
merged 13 commits into from
May 14, 2024
Merged

Conversation

tiaguinho-code
Copy link
Collaborator

@tiaguinho-code tiaguinho-code commented May 13, 2024

What it do?

Give dataloader capability to decode target arrays from test and prediction set.
Should fix Issue #50 .

How?

Added internal function to dataloader that usess the same label binarizer that it used to encode the different categories.
It does the inverse encoding then and returns that for an arbitrary target array.

In the current implementaiton the dataloader is passed to the evaluation script to do translation in there but we can of course also translate inside the trainer script and pass the decoded arrays and labels.

TiagoW added 8 commits May 13, 2024 11:43
Function takes binarrized encoded target array and decodes it back.
useful for confusion matrix.
The one dimensional stuff wasn't working due to some places expecting
lists of lists and only getting lists. Fixed now
Dataloader was added to evaluation to label the confusion matrix. If
this is too much mixing of the dataloader we can also of course just
pass the decoded y_pred and y_test.
@tiaguinho-code tiaguinho-code self-assigned this May 13, 2024
@tiaguinho-code tiaguinho-code added the bug Something isn't working label May 13, 2024
@tiaguinho-code tiaguinho-code linked an issue May 13, 2024 that may be closed by this pull request
@tiaguinho-code tiaguinho-code marked this pull request as ready for review May 13, 2024 15:54
@tiaguinho-code
Copy link
Collaborator Author

Just noticed there is undefined behavior if the Model Chooses multiple elements for one row for example THF and Et2O on the same molecule. Looks like the Binarizer somehow chooses one, but I guess this shouldn't be an issue as it will work out in the statistics.

@mlederbauer
Copy link
Owner

Thanks a lot for the contribution! Checking the code asap
I was wondering if you could add 1 or 2 example confusion matrices that are generated when running the code? (I guess this might change a bit wth our discussion on Discord)
Typically, you can “Copy Image” directly from VSCode and Cmd+V it here on Github.

@tiaguinho-code
Copy link
Collaborator Author

willco tomorrow 👍🏼

Tiago Würthner added 3 commits May 14, 2024 08:39
Some setup for adding the multi dimensional support for the Confusion
matrix the way it produces multiple cms for each target of the
--targets.
This function returns a list of list of the columns of each target. This
is needed to make multiple confusion matrices.
Added support for one target, one dim target array and
multiple targets, multidimensional target array
single target, multidimensional target array for confusion matrices.
@tiaguinho-code
Copy link
Collaborator Author

tiaguinho-code commented May 14, 2024

Current state

The code has now been refactored quite a bit, especially the training script. It can handle all sorts of dataset mixtures. Roc etc only are generated for binary tasks and depending on the target dimensionality, different things are executed.

Todo

Fix the algorithm to make the subplots and add that cool color bar, but I feel like this depends on how exactly we want to plot it. The technically painful part is done, which is generate all the sub cms and bring along the right labels.

Examples of generated confusion matrices

Images

image

image

image

tiaguinho-code

This comment was marked as duplicate.

mlederbauer
mlederbauer previously approved these changes May 14, 2024
"""
Plots the confusion matrix.
Parameters:
- cm (array-like): Confusion matrix data.
- classes (list): List of classes for the axis labels.
- title (str): Title of the plot.
- full (bool): If true plots one big, else many smaller.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the description hehe

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively for the final review round in the end, we could rename to “Plots single confusion matrix for all targets combined vs one CM per target” or something like that

plt.savefig(path)
plt.close()

elif not full: # Plot many small cms of each target
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could rewrite this to else: as full is either True or False

sub_classes = classes[
slice(columns_set[i][0], columns_set[i][-1] + 1)
]
axs[i].imshow(sub_cm, interpolation="nearest", cmap=plt.cm.Blues)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super nice! in the final review, we can add our minecraft color scheme here

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because we obtain the cmap from the setup_style() function in nmrcraft/analysis/plotting.py

"""
y_decoded = self.binarized_target_decoder(y)
flat_y_decoded = [y for ys in y_decoded for y in ys]
return flat_y_decoded
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That must have been technically difficult to implement! Thanks for taking care of this. In the final review, we could add a bit more detailed documentation here so that the TAs know what’s going on in this function.

from typing import Any, Dict, Tuple

from sklearn.base import BaseEstimator
from sklearn.metrics import (
accuracy_score,
auc,
# confusion_matrix,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for cleaning up the code alongside!



def model_evaluation_nD(
model: BaseEstimator,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice. Also a note for final review (I’m creating an issue out of this: add type hints for all functions and classes. The purpose of this is to enforce that a function takes inputs only of a certain type, and also only outputs a certain type.

instead of

def confusion_matric_plotter_or_whatever(target, full=True):
   return 1+1

Write

def confusion_matric_plotter_or_whatever(target: np.array, full: bool = True) -> int:
   return 1+1

This seems a bit useless at first but its a game changer when writing code that takes in many different inputs, and saves some amount of error messages!

X_test: Any,
y_test: Any,
y_labels: Any,
dataloader: dataset.DataLoader,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, for example, you have such type hints

print(f"Accuracy: {metrics['accuracy']}")
mlflow.log_artifact(get_cm_path())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for cleaning up! We might need to adapt this to the script @strsamue is writing.

@mlederbauer mlederbauer dismissed their stale review May 14, 2024 17:40

Something not right

@mlederbauer mlederbauer merged commit 8eba2a7 into main May 14, 2024
1 check passed
@mlederbauer mlederbauer deleted the fix/multilabel-confusion-matrix branch May 14, 2024 19:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bug: multilabel confusion matrix
2 participants