기존(1) 에 이어서...
단계 2 / 기초 전처리 추가 진행
전처리를 추가로 진행하였다. 우선 추가로 진행한 사항은 다음과 같다.
(1) category를 대분류, 중분류로 나누어 각 분야별로 분석이 가능하게 텍스트 분리
(2) 주요 업무 / 자격 요건 / 우대 사항을 분리하여 분석할 수 있도록 만듬
(3) 공백, 특수 문자등에 대한 전처리 실시
(4) 형용사 등은 공고의 핵심어와는 상관없으므로 명사만 취급하며 별도의 stopword를 지정하여 제외
가장 어려운 부분은 stopwords의 목록을 만드는 일이다. 현재도 분석하면서 계속적으로 stopword를 추가 중,
import pandas as pd
import re
job_df = pd.read_csv('C:/Users/USER/Desktop/personal_project/wanted_JD_analysis/wanted_crawling.csv',
encoding = 'utf-8-sig')
# 공고 재업로드 등으로 인해 완벽하게 같은 공고가 들어 왔을 수 있음
# 그러나 drop을 실시하면 안 되는 것이, 수요 재발생 등의 고려 필요
# job_df = job_df.drop_duplicates().reset_index(drop = True)
# 전처리 계획
# 1) date : 연-월만 있어도 분석에 충분
# 2) category : 대분류>중분류>... 방식, 전체적으로 중분류만 있어도 충분
# 3) descriptions : 주요 업무, 자격 요건, 우대 사항만 추출 방법...
# 방법 : 주요 업무 ~ 혜택 및 복지 전까지만 추출하면 됨
# 그 이후 구분 방법을 찾아 효율적 구분 필요
#
job_df['dt_ym'] = job_df.date.apply(lambda x : x[0:7])
job_df['ct_brief'] = job_df.category.apply(lambda x : list(x.split(','))[0:2])
job_df['job_due'] = job_df.descriptions.apply(lambda x: x[x.find('주요업무')+5:
x.find('자격요건')])
job_df['job_due'] = job_df.job_due.apply(lambda x : list(x.split('\n')))
job_df['job_req'] = job_df.descriptions.apply(lambda x: x[x.find('자격요건')+5:
x.find('우대사항')])
job_df['job_req'] = job_df.job_req.apply(lambda x : list(x.split('\n')))
job_df['job_add'] = job_df.descriptions.apply(lambda x: x[x.find('우대사항')+5:
x.find('혜택 및 복지')])
job_df['job_add'] = job_df.job_add.apply(lambda x : list(x.split('\n')))
# 대분류, 소분류를 미리 만들자.
job_df['ct_1st'] = job_df.ct_brief.apply(lambda x : x[0])
job_df['ct_2nd'] = job_df.ct_brief.apply(lambda x : x[1].strip())
# 마지막으로 필요없는 항목에 대한 제거 실시
job_df = job_df[['company_name','industry', 'dt_ym', 'ct_1st','ct_2nd',
'job_req', 'job_add', 'job_due', 'title']]
def del_special_letter(s):
# 한글, 숫자, 영어, 띄어쓰기만 살아남기고 모두 지워버리는 정규표현식
new_str = re.sub(r"[^\uAC00-\uD7A30-9a-zA-Z\s]", "", s)
return new_str
def handle_space(s_list):
for i in range(len(s_list)):
s_list[i] = s_list[i].strip()
while '' in s_list:
s_list.remove('')
return s_list
job_df['job_due'] = job_df.job_due.apply(lambda x: [del_special_letter(s) for s in x])
job_df['job_due'] = job_df.job_due.apply(lambda x: handle_space(x))
job_df['job_req'] = job_df.job_req.apply(lambda x: [del_special_letter(s) for s in x])
job_df['job_req'] = job_df.job_req.apply(lambda x: handle_space(x))
job_df['job_add'] = job_df.job_add.apply(lambda x: [del_special_letter(s) for s in x])
job_df['job_add'] = job_df.job_add.apply(lambda x: handle_space(x))
# 특수문자와 다양한 것들에 대해 제외 처리 완료.
# Next step : 불용어 처리 및, 중복단어 제거로 핵심어만 추출
# TF-IDF 활용하여 할 수 있을까? / keywordrank 등의 사용도 고려
# step / 한국어 전처리 후, 명사 태깅 사용 -> 해당 명사로 빈도분석 실시
# 주요 어휘가 무엇인지 등등을 보는 것이므로, 명사만 가져와야 유의미함
# 같은 단어가 반복해서 나온다면 중요한 것이므로 굳이 중복이라고 지우지 말 것
# 불용어 사전을 정의해서 쓰자. 1글자만 하기에는 딥러닝 등의 변수가 있어 불가
# 추가로 각종 공고에서 반복적으로 쓰이나 큰 차별화 단어가 아닌 단어도 포함한다.
stop_words = ['및', '은', '는', '이', '가', '을', '를', '등', '로', '와','준',
'과', '수', '각', '각각', '의', '더', '사람', '같', '아니', '분',
'경험', '유관', '업무', '대한', '사', '근무', '우대', '필수', '그',
'역량', '일', '저', '통한', '것']
from konlpy.tag import Okt
okt = Okt()
def get_noun_list(s):
noun_list = []
for cur_s in s:
cur_nouns = okt.nouns(cur_s)
noun_list += cur_nouns
return [n for n in noun_list if n not in stop_words]
job_df['job_due_noun'] = job_df.job_due.apply(lambda x : get_noun_list(x))
job_df['job_req_noun'] = job_df.job_req.apply(lambda x : get_noun_list(x))
job_df['job_add_noun'] = job_df.job_add.apply(lambda x : get_noun_list(x))
# 이제 남은 것으로 빈도 분석 등을 진행하고 언어 분석 등 다른 것을 진행할거라
# 전처리 대신 이제 실제 분석으로 진행한다.
job_df_final = job_df[['company_name','industry', 'dt_ym', 'ct_1st','ct_2nd',
'job_req_noun', 'job_add_noun', 'job_due_noun', 'title']]
job_df_final.to_csv('C:/Users/USER/Desktop/personal_project/wanted_JD_analysis/wanted_data_prep.csv',
encoding = 'utf-8-sig', index = False)
print('end of preprocessing')
단계 3 / 시각화 및 분석
가장 어려운 부분은 핵심어 파악을 위한 tf-idf 부분이었다. 문서별로 중요도를 따지는 것이 아니라 공고 목록들 내에서 하나의 tf-idf를 만들어야 하여 직접 유도하도록 만들었다. 정의 있는 그대로 활용하여 제작. 효율적인 방법에 대해서는 고민해야 한다. 마지막에 중요 어휘부터 볼 수 있게 바로 정렬해서 줄 수 있도록 dict 정렬 실시.
# 주의사항 여러개의 공고에 대해서 하나의 중요어휘를 만들어야 하므로 직접 만든다.
# tf-idf 직접 유도.
import math
from ast import literal_eval
def get_tfidf(s_list, len_df):
word_count_dict = {}
page_count_dict = {}
# step 1 .tf, df 를 세자
for cur_list in s_list:
cur_page_word = []
cur_list = literal_eval(cur_list)
for cur_word in cur_list:
# 문제 : cur_word가 지금 리스트 형태가 아닌 문자열로 들어와버림
if cur_word not in word_count_dict:
# 새로 본 단어라면
word_count_dict[cur_word] = 1
page_count_dict[cur_word] = 1
cur_page_word.append(cur_word)
else:
# 이미 봤던 단어라면
word_count_dict[cur_word] += 1
if cur_word not in cur_page_word:
cur_page_word.append(cur_word)
page_count_dict[cur_word] += 1
# step 2. idf로 변경하자
idf_dict = {}
for cur_word in page_count_dict:
idf_dict[cur_word] = math.log(len_df / (1 + page_count_dict[cur_word]))
tf_idf_dict = {}
for cur_word in word_count_dict:
tf_idf_dict[cur_word] = word_count_dict[cur_word] * idf_dict[cur_word]
return sorted(tf_idf_dict.items(), key=lambda x : x[1], reverse = True)
남은 것은 이제 최종 분석 목표 설정과 적당한 시각화들, 그리고 인사이트 도출이다.
'Project 관련 기록' 카테고리의 다른 글
[Project] 원티드 채용 공고 분석 및 인사이트 도출 (1) (0) | 2024.01.02 |
---|---|
[DevCourse] Monthly EDA Project(3) 최종 결과 및 회고 (0) | 2021.05.22 |
[DevCourse] Monthly EDA Project (2) 배포는 어떻게 할 건가? (0) | 2021.05.22 |
[DevCourse] Monthly EDA Project (1) EDA Baseline을 작성하면서 배운 시각화 방법 (0) | 2021.05.12 |