setfit icon indicating copy to clipboard operation
setfit copied to clipboard

Using SetFit for regression tasks?

Open ericlinML opened this issue 2 years ago • 6 comments

I was curious about using SetFit for ordinal Likert scale outcomes (ie IMDB movie reviews). It doesn't seem like an obvious option in the SetFit API. Has anyone tried using SetFit for regression tasks?

ericlinML avatar Oct 21 '22 19:10 ericlinML

Can you provide some more details about what you're trying to do I might be able to help : ). If you have ordinal data you could treat it like a multiclass problem and setfit should 🤞 just work for that problem. I haven't tried this but taking a look it appears you can set the head of the setfit model to be whatever you want so you could do something like:

from sentence_transformers.losses import CosineSimilarityLoss

from setfit import SetFitModel, SetFitTrainer
from sklearn.linear_model import LinearRegression
from sentence_transformers import SentenceTransformer

# Choose a sentence transformer for your embedding
model_body = SentenceTransformer("sentence-transformers/paraphrase-mpnet-base-v2")

# Choose whatever head you want for regression
model_head = LinearRegression()

# Load a SetFit model from Hub
model = SetFitModel(model_body=model_body, model_head=model_head)

# Create trainer
trainer = SetFitTrainer(
    model=model,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    loss_class=CosineSimilarityLoss,
    metric="accuracy",
    batch_size=16,
    num_iterations=20, # The number of text pairs to generate for contrastive learning
    num_epochs=1, # The number of epochs to use for constrastive learning
    column_mapping={"sentence": "text", "label": "label"} # Map dataset columns to text/label expected by trainer
)

# Train and evaluate
trainer.train()

I haven't tried it but I suspect instead of using the default LogisticRegression model head you could replace it with any other reasonable estimator from sklearn. Let me know if you want additional help I'd be happy to take a look if you provide some example input and output data you're struggling with.

nbertagnolli avatar Oct 25 '22 03:10 nbertagnolli

The ability to add a different head would be a nice addition to the documentation actually

nsorros avatar Oct 27 '22 07:10 nsorros

I can open a PR if folks want with examples.

nbertagnolli avatar Oct 27 '22 21:10 nbertagnolli

My work (sorry can't share data) involves looking at mental health patient audio journals (vastly longer than 512 tokens) that have some self report emotional rating scale attached to them "How sad were you today (rate from 1-5 with 1 being not at all to 5 being extremely sad)?" Generally stuff like that - our biggest hurdle is that we have long texts/transcripts and also small sample size, so I've been trying to think about how we can use something like SetFit in our lab.

My apologies for the late reply!

ericlinML avatar Nov 02 '22 03:11 ericlinML

I haven't tried it but I suspect instead of using the default LogisticRegression model head you could replace it with any other reasonable estimator from sklearn. Let me know if you want additional help I'd be happy to take a look if you provide some example input and output data you're struggling with.

I can confirm that this is possible. Since the body is basically trained separately from the head, you can train as usual, then embed your training set with the body model and use the embedded data to train a new head. I've since been using a random forest, for example.

Basically:

setfit_model = SetFitModel(model_body = SentenceTransformer(model_id), model_head=RandomForestClassifier()) 

You should be able to attach any sklearn head as long as it supports the required methods.

kgourgou avatar Nov 05 '22 20:11 kgourgou

But @nbertagnolli SetFit model, associates /pair the instances sharing same label (0 or 1) to augment the set size, which underlies contrastive learning. For the regression problem, we pass numeric values instead of 0/1 labels. How do you expect the models associates/pairs the instances!

savasy avatar Feb 01 '23 16:02 savasy