[카카오 아레나] 쇼핑몰 상품 카테고리 분류 대회 리뷰 Part 2 — 분류기

전처리에 비해서 분류기는 굉장히 단순합니다. 자연어처리(Natual Language Processing, NLP) 문제에는 흔히 LSTM, GRU와 같은 RNN 모듈을 사용하는 경우가 많은데, 이번 대회에서는 MLP(Multi Layer Perceptron) 위주로 사용했습니다.

전체 구조

분류기

전처리는 이전 포스트에서 다룬 것과 동일합니다. 그 이외의 분류기는 크게 3층의 Fully Connected로 구성했습니다. 첫번째 FC(4096)에서 입력 텍스트의 특징(Feature)를 뽑고 다음 층의 FC에서 카테고리를 예측합니다.

FC: b-m-s-d

대/중/소/세분류 카테고리를 한 번에 예측하는 FC입니다. 전처리 포스트에서 언급했듯이 총 4205개의 클래스가 있습니다. 대회 주최측에서 제공한 코드에서도 모든 카테고리를 한 번에 예측하는 FC를 사용하고 있습니다.

FC: b

대분류만 예측하는 FC입니다. 대분류의 카테고리가 가장 적고 대분류를 정확하게 분류해야 다음 카테고리 예측을 잘하지 않을까?라는 생각을 가지고 도입했습니다. 실제로는 정확도 향상에 큰 도움을 주지 않았습니다.

FC: m

중분류만 예측하는 FC입니다. FC: b와 다른 점은 소, 세분류를 예측할때 중분류의 값(Logit)을 참고(Concatenation)합니다.

FC: s, d

소분류와 세분류를 각각 예측하는 FC입니다. 카테고리가 계층적인(hierarchical) 상하관계를 가지고 있기 때문에 상위 카테고리의 결과를 참고하는게 도움이 될 것이라고 생각했습니다.

  1. 대분류(b), 중분류(m)을 모두 참고하는 경우
  2. 대분류(b)만 참고하는 경우
  3. 중분류(m)만 참고하는 경우

총 3가지에 대해서 실험해보았는데 중분류만 참고하는 것이 가장 성능이 좋았습니다. 대분류와 소/세분류 사이의 거리가 멀기 때문에 좋은 가이드가 되기 보다는 노이즈로 작용한 것 같습니다.

Loss

총 5개 FC에 대응하는 라벨로 Cross Entropy Loss를 계산했습니다. 모든 Loss를 사용하며 대회 점수 계산식

score = 1.0*acc_b + 1.2*acc_m + 1.3*acc_s + 1.4*acc_d

에 맞게 각 Loss간의 가중치를 조절했습니다.

total_loss = loss_bmsd + (1.0*loss_b + 1.2*loss_m + 1.3*loss_s + 1.4*loss_d)

최종 결과 예측(Predictions)

대회 중 가장 흥미로웠던 부분이기도 하고 수상에 결정적으로 작용했습니다. 대회에 참여하셨던 분들은 아시겠지만 소/세분류가 없는(-1로 카테고리가 분류된) 상품들이 꽤 많습니다. 이런 조건 때문에 카테고리 분류가 안된 카테고리에 대해서는 어떤 값으로 예측해도 점수면에서 페널티를 받지 않습니다. 반대로 생각하면 -1의 예측값을 얻었더라도 아무 값이나 바꿔서 제출하면 정확도 향상을 기대할 수 있습니다.

  1. FC: b-m-s-d로만 예측하기
  2. FC: b-m-s-d로 예측하고 -1인 부분만 FC: s, FC: d 예측값으로 대체하기
  3. FC: b-m-s-d로 b, m만 예측하고 FC: s, FC:d로 s, d 예측하기

총 3가지 방법의 결과를 비교했는데 3번째 방법이 가장 정확도가 좋았습니다.

큰 그림(b, m)은 모든 카테고리를 보면서 예측하는 것이 유리하고 디테일(s, d)은 개별적으로 보는게 유리하다

라고 결과를 해석해볼 수 있겠습니다.

다음 포스트에서 하이퍼파라미터 튜닝 및 성능 쥐어짜기에 대해서 다뤄보겠습니다.