The error at the end of the stacktrace is the key to understand what's going on here.

ValueError: pos_label=1 is not a valid label: array(['ham', 'spam'],
dtype='|S4')

You're trying to score your model with precision and recall. Recall that these scoring methods are formulated in terms of true positives, false positives, and false negatives. But how does sklearn know what is positive and what is negative? Is it 'ham' or 'spam'? We need a way to tell sklearn that we consider 'spam' the positive label and 'ham' the negative label. According to the sklearn documentation, the precision and recall scorers by default expect a positive label of 1, hence the pos_label=1 part of the error message.

There are at least 3 ways to go about fixing this.

1. Encode 'ham' and 'spam' values as 0 and 1 directly from the data source in order to accommodate the precision/recall scorers:

As the documentation says, the precision and recall scores by default have a pos_label argument of 1, but this can be changed to inform the scorer which string represents the positive label. You can construct scorer objects that have different arguments with make_scorer.