I'm trying to build a model to map job descriptions to ESCO occupations which is a taxonomy for job titles. Every ESCO occupations have a title, a description and some essential skills. Ideally I would have built a classification model but since I don't have labelled data that's out of the question.
So my idea was to generate text embeddings from every ESCO occupation and then for an input job description, and using cosine similarity, find the most similar ESCO occupation to that job description. I'm using this model to generate the embeddings, which is an XLM-roBERTa which was pre-trained on job market data. I use the mean of the embeddings for every token as the job description's final embedding. However the results are very bad, it fails to find most relevant ESCO occupations.
Here's how I compute the embeddings:
from transformers import AutoTokenizer, AutoModel
tokenizer = AutoTokenizer.from_pretrained("jjzha/esco-xlm-roberta-large")
model = AutoModel.from_pretrained("jjzha/esco-xlm-roberta-large")
sample_job_title = "We are looking for a junior software developer with experience in React and Python."
encoded_input = tokenizer(sample_job_title, padding=True, truncation=True, return_tensors="pt")
with torch.inference_mode():
output = model(**encoded_input)
embedding = output.last_hidden_state.mean(dim=1)
From this output I retrieve output.last_hidden_state, which should correspond to the tokens embeddings, and then compute the mean embedding. This returns a pytorch tensor of shape (1, 1024). I have another tensor of shape (3007, 1024), esco_embeddings
which corresponds to the embeddings for every 3007 ESCO occupation.
I then compute cosine similarity by doing:
similarities = torch.nn.functional.cosine_similarity(embedding, esco_embeddings, dim=1)
And find the k most similar ESCO occupations by computing
most_similar = torch.topk(similarities, k)
I thought that the problem might be in the embeddings itself, with XLM-roBERTa generating embeddings for every token and not one emebdding for the whole text.
Does anyone have an idea why that isn't working, and how it could be fixed? Maybe there's a better approach?
Thanks for the help.