geeone 스터디 블로그

Sentence-BERT로 채용 공고 적합도 분석하기 본문

카테고리 없음

Sentence-BERT로 채용 공고 적합도 분석하기

alisongeeone 2025. 5. 19. 17:08

안녕하세요~ 오늘은 저희 졸업 프로젝트의 핵심 기능 중 하나인 채용 공고 적합도 계산에 대해 소개해보려고 합니다.

 

 

저희 프로젝트 Pickin’은 한국에서 취업을 희망하는 외국인 유학생을 위한 맞춤형 채용 공고 추천 서비스입니다.
외국인 유학생들은 다양한 사이트에 흩어진 채용 정보를 한눈에 파악하기 어렵고, 기업들도 적합한 외국인 인재를 찾는 데 어려움을 겪고 있는데요, Pickin’은 이런 문제를 해결하고자 탄생한 서비스입니다. Pickin’은 지원자의 프로필과 채용 공고를 분석하여 ‘채용 공고 적합도(Pickin 지수)’를 예측하고, 이를 바탕으로 적합도가 높은 공고를 자동으로 추천해줍니다.

Pickin의 핵심 기능 중 하나인 Sentence-BERT를 활용한 채용 공고–지원자 간 유사도 분석과 이를 통해 채용공고 적합도 (Pickin 지수)를 계산하는 방법을 튜토리얼 형식으로 포스팅해보려 합니다!

 

목차는 다음과 같습니다.

1. 데이터 수집 :  채용 공고와 지원자 데이터
2. 데이터 전처리 :  텍스트 벡터화를 위한 준비
3. 채용 공고 적합도(Pickin 지수) 계산 : 문장 간 의미 유사도 측정

 


1. 데이터 수집 :  채용 공고와 지원자 데이터

Pickin 지수를 계산하기 위한 첫 단계는 채용 공고와 지원자 데이터를 수집하는 일입니다.

  • 채용 공고 50개를 채용 공고 플랫폼에서 크롤링해 직무, 필요 언어, 비자, 우대사항, 상세 설명 등을 수집
  • 지원자 10명의 더미 데이터는 국적, 제1언어, 전공, 비자 소지 여부, TOPIK 등급, 대외활동 등을 기반으로 직접 생성

이렇게 쌓인 구조화된 데이터가 Pickin 지수의 기반이 됩니다.

 

ex. 채용 공고 데이터

 

ex. 지원자 데이터

 

 

 


 

 

2. 데이터 전처리 :  텍스트 벡터화를 위한 준비

위 데이터를 그대로 벡터화하면 모델이 정보를 제대로 해석하지 못할 수 있기 때문에, 데이터 구조를 자연스럽게 다듬어줍니다.

  • 채용 공고 텍스트 직무 + 우대사항을 중심으로 구성하고, 문장을 자연스럽게 연결하여 “본 직무는 … 우대사항으로는 …” 형태로 조정
df_job = pd.read_excel("jobpost.xlsx")
df_job['job_data'] = (
    '본 직무는 ' + df_job['직무'].fillna('') + ' 를 주 업무로 하며, '
    + '우대사항으로는 ' + df_job['우대사항'].fillna('') + '을(를) 보유한 지원자를 선호합니다.'
)
  • 지원자 텍스트 국적 + 제1언어 + 전공 + 대외활동 + TOPIK 등급 정보를 연결해 “국적을 가진 지원자는 … 전공하였습니다 …” 같은 자기소개 형태로 구성
df_app = pd.read_excel("/applicantsInfo.xlsx")
df_app['app_data'] = (
    df_app['국적'] + ' 국적을 가진 지원자는 '
    + df_app['제 1언어'] + '를 제1언어로 사용하며, '
    + df_app['전공'] + '을 전공하였습니다. '
    + '대외 활동으로는 ' + df_app['대외 활동'] + '을(를) 수행하였고, '
    + '한국어 능력은 TOPIK ' + df_app['TOPIK 등급'] + ' 수준입니다.'
)

 

이처럼 데이터를 의미 있는 자연어 문장으로 가공하는 과정은 문장 임베딩 품질에 큰 영향을 미칩니다.

 

 

 


 

 

3. 채용 공고 적합도 (Pickin 지수) 계산 : 문장 간 의미 유사도 측정

문장 데이터가 준비되었으면 문장 임베딩 모델을 활용해 Pickin 지수를 계산합니다.

  • SentenceTransformer를 사용해 채용 공고와 지원자 문장을 벡터로 변환하고, util.cos_sim을 통해 유사도(=Pickin 지수)를 계산합니다.
# KoBERT 기반으로 학습된 문장 임베딩 전용 모델 사용 
model = SentenceTransformer('snunlp/KR-SBERT-V40K-klueNLI-augSTS')

job_texts = df_job['job_data'].tolist()
app_texts = df_app['app_data'].tolist()

job_embeddings = model.encode(job_texts, convert_to_tensor=True)
app_embeddings = model.encode(app_texts, convert_to_tensor=True)

similarities = util.cos_sim(app_embeddings[idx], job_embeddings)

 

  • SentenceTransformer를 사용해 채용 공고와 지원자 문장을 벡터로 변환하고, util.cos_sim을 통해 유사도(=Pickin 지수)를 계산합니다.
  • 다음과 같이 지원자 데이터와 채용공고 50개간의 유사도를 확인할 수 있습니다. 
print(similarities)
tensor([[0.6660, 0.4567, 0.4950, 0.5698, 0.6541, 0.6486, 0.4583, 0.6204, 0.5875,
         0.6504, 0.6332, 0.6642, 0.3611, 0.5400, 0.4792, 0.5290, 0.5455, 0.5734,
         0.6532, 0.5939, 0.5461, 0.5348, 0.6065, 0.4942, 0.4923, 0.4979, 0.4293,
         0.4764, 0.4940, 0.6103, 0.4975, 0.4703, 0.5918, 0.6047, 0.6362, 0.6138,
         0.6196, 0.6138, 0.3492, 0.5553, 0.4664, 0.6057, 0.5819, 0.5953, 0.6033,
         0.5920, 0.6205, 0.6078, 0.5810, 0.5607]])

 

 

 


이렇게 채용 공고 데이터와 지원자 데이터 간의 유사도를 Sentence-BERT를 활용해 계산해봤습니다!
처음에는 다양한 임베딩 모델을 적용해보며 비교 실험을 진행했는데, 최종적으로 선택한 모델이 실제 유사도를 가장 효과적으로 반영해 주는 것을 확인할 수 있었습니다.

또한, 단순히 모델만 좋다고 끝나는 것이 아니라, 데이터 자체를 자연스러운 문장 구조로 다듬는 튜닝 과정도 중요한 역할을 했습니다.
이러한 반복적인 실험과 개선을 통해, 공고-지원자 매칭의 가능성을 수치화하는 Pickin 지수를 완성할 수 있었고, 앞으로도 이 지표를 기반으로 한 추천 시스템 고도화를 이어나갈 계획입니다~~