본문 바로가기
  • 데이터에 가치를 더하다, 서영석입니다.
도전 : 더 나은 사람으로/텍스트 산업 분류 공모전

[2022 통계청 공모전] 1. bigword split

by 꿀먹은데이터 2022. 5. 6.

이름을 bigword split이라고 지은 이유는..  tokenized를 봤을 때, noun(명사)로 토큰화하였다고 할지어도,

'이벌게임'처럼 명사화가 잘 되지 않은 문장들을 더 잘게 쪼개주어 의미를 부여할 수 있도록 하기 위해서

단어수가 긴 단어의 경우, 잘게 쪼개주면 좋지 않을까 싶었다.

 

 나중에 임베딩 모델을 구현할 때, 단어수의 빈도가 50 이상인 단어들로만 이뤄지게 하기에.

단어수의 빈도가 50 미만인 (임베딩에 영향을 주지 않는) 단어들을 Split 해주기로 하였다.

 

count={}
for j in range(len(bigword_split_okt)):
  for i in bigword_split_okt[j]:
      try: count[i] += 1
      except: count[i]=1
print(count)

단어들의 빈도수를 측정하였다.

bigword = {key: value for key, value in count.items() if len(key)==4 and value <50}
bw= list(bigword)
bw_copy = bw.copy()
bigword

4글자인 경우 2|2로 나누기도, 3|1로 나누기도, 1|3으로 나눈 뒤, 다시 그 리스트에 넣어버리면 

벡터를 임베딩하여 찾는데 있어서 도움이 되지 않을까하는 생각이 들었다.

 

예를 들어 ['사업', '일반인', '대상', '숙박시설', '고시원'] 의 경우 4글자인 수를 split해준다면,

['사업', '일반인', '대상', '숙박시설', '고시원','숙박','시설','숙','박시설','숙박시','설'] 로 해주는 것이다.

 

그렇다면 너무 많은 단어들로 인해 저 리스트가 산업분류하는데 오히려 방해가 되지 않을까?

 

대답은 NO이다. 임베딩 모델을 만드는데 있어 영향을 주지 않는 '50 미만'의 단어들을 쪼개주는 것이기에

쪼개주었을 때, 50 이상이 넘어간다면 오히려 산업분류하는데 도움을 줄 것이다.

(예를 들어, 숙박시설 -> 숙박, 시설로 쪼갰을 때,

'50 미만'이였던 숙박이 '50 이상'이 되어버려 임베딩 모델을 만드는데 긍정적인 영향을 줄 것이다.)

 

방식은 이러하다.

  1. 8글자부터 4글자까지 차례대로 쪼개준다. (9글자 이상인 경우는 거의 없음을 확인했다.)
  2. 모든 글자를 다 쪼개준다. (8글자의 경우 1|7, 2|6 , ... , 7|1까지 쪼개준다.)
  3. 쪼개준 뒤, 본래의 단어는 제거한다. (remove 함수 이용)
  4. 4글자인 경우, 1|3, 2|2, 3|1 로 쪼개준 뒤, 원래의 값 4글자는 그대로 냅둔다. (remove 함수 이용 x)

8글자의 count 및 50미만의 단어들 리스트화

count={}
for j in range(len(okt2_copy)):
  for i in okt2_copy[j]:
      try: count[i] += 1
      except: count[i]=1
bigword8 = {key: value for key, value in count.items() if len(key)==8 and value <50}
bw8= list(bigword8)
bw8_copy=bw8.copy()

split8 함수 생성 : 1|7 , 2|6 , .... , 7|1 로 split 하는 함수

def split8(data_name,i):
  data_name =bw8.copy()
  for k in range(len(bw8)):
    d=[]
    d.append(data_name[k][0:i])
    d.append(data_name[k][i:8])
    data_name[k]=d
  return data_name

예시 : 2|6 , 4|4 , 6|2 로 split 해주는 역할.

b8_2=[]
b8_4=[]
b8_6=[]
b8_2=split8(b8_2,2)
b8_4=split8(b8_4,4)
b8_6=split8(b8_6,6)
for i in range(len(bw8_copy)):
  for j in range(len(okt2_copy)):
    for item in okt2_copy[j]:
      if item ==bw8_copy[i]:
         okt2_copy[j].remove(bw8_copy[i])
         okt2_copy[j].append(b8_2[i][0])
         okt2_copy[j].append(b8_2[i][1])
         okt2_copy[j].append(b8_4[i][0])
         okt2_copy[j].append(b8_4[i][1])    
         okt2_copy[j].append(b8_6[i][0])
         okt2_copy[j].append(b8_6[i][1])

4글자의 경우, for문에 remove 함수 불필요.

for i in range(len(bw4_copy)):
  for j in range(len(okt2_copy)):
    for item in okt2_copy[j]:
      if item ==bw4_copy[i]:
        okt2_copy[j].append(b4_1[i][0])
        okt2_copy[j].append(b4_1[i][1])
        okt2_copy[j].append(b4_2[i][0])
        okt2_copy[j].append(b4_2[i][1])
        okt2_copy[j].append(b4_3[i][0])
        okt2_copy[j].append(b4_3[i][1])  
      else: continue

이후 다시 pickle 패키지로 리스트를 재저장하는 과정을 거치게 되면 이후 불용어 처리를 하면 된다.

 

 

관련 github code

https://github.com/rootofdata/NLP_AI_Industry_classification.git

 

GitHub - rootofdata/NLP_AI_Industry_classification

Contribute to rootofdata/NLP_AI_Industry_classification development by creating an account on GitHub.

github.com