데이콘 뉴스 토픽 분류 AI 경진대회를 통해 자연어 처리를 경험했다.
어간추출, 조사, 어미, 구두점 제거 및 불용어 제거 후 TfidfVectorizer를 이용해 벡터화하여 학습 및 예측을 했다.
데이터 로드
train = pd.read_csv("train_data.csv")
test = pd.read_csv("test_data.csv")
train은 45654행 3열, test는 9131행 2열의 데이터다.
뉴스 제목과 토픽 인덱스를 학습시킨 후, 뉴스 제목을 통해 토픽을 예측하는 경진대회다.
총 7개의 토픽으로 분류되어 있다.
텍스트 전처리
정규표현식을 사용하여 한글, 영문, 숫자가 아닌 경우 공백으로 대체했다. 그 결과 특수문자와 한자가 제거되었다.
화살표, 점, 美 등이 제거된 것을 확인할 수 있다.
어간 추출
konlpy의 Okt를 통해 품사 태깅을 할 수 있다.
from konlpy.tag import Okt가 선행된다.
okt_pos = okt.pos('버스의 운행시간을 문의한다. 어?!', norm=True, stem=True)
okt_pos
위 문장을 어간 추출한 결과를 아래와 같다.
동사, 명사, 조사 등 품사가 태깅되어 튜플의 리스트 형태로 반환되었다. 또한 동사는 원형을 얻을 수 있다.
# 조사, 어미, 구두점 제거
word_list = []
for word in okt_pos:
if word[1] not in ['Josa', 'Eomi', 'Punctuation']:
word_list.append(word[0])
' '.join(word_list)
# 실행 결과
'버스 운행 시간 문의 하다'
조사, 어미, 구두점인 '의', '을', '.', '어', '?!' 가 제거된 형태가 되었다.
불용어 제거
# 불용어 제거 함수
def remove_stopwords(text):
tokens = text.split(' ')
stops = [ '합니다', '하는', '할', '하고', '한다',
'그리고', '입니다', '그', '등', '이런', '및','제', '더']
meaningful_words = [w for w in tokens if not w in stops]
return ' '.join(meaningful_words)
이후 불용어를 제거하여 의미있는 단어만을 남긴다.
train["title"] = train["title"].map(remove_stopwords)
test["title"] = test["title"].map(remove_stopwords)
train set과 test set의 title에 적용하여 아래와 같은 형태로 바꿨다.
조사, 어미, 구두점과 불용어가 제거된 형태가 되었다. 이제 전처리가 완료되었고 벡터화 후 학습한다.
학습 및 예측
X_train_text = train['title']
X_test_text = test['title']
y_train = train['topic_idx]
학습과 예측을 위해 X_train_text, X_test_text, y_train으로 나누어 준비했다.
벡터화
tfidfvect = TfidfVectorizer(min_df=2, max_df=0.95)
tfidfvect.fit(X_train_text)
X_train = tfidfvect.transform(X_train_text)
X_test = tfidfvect.transform(X_test_text)
X_train.shape, X_test.shape
# 실행 결과
((45654, 17830), (9131, 17830))
TfidfVectorizer를 임포트 한 후 생성했고, 변환할 어휘를 학습하고 transform하여 X_train, X_test에 할당했다. 벡터화 결과 차원이 매우 높아진 것을 확인할 수 있다.
모델 생성, cross validation
model_lgbm = LGBMClassifier(random_state=42)
y_val_predict = cross_val_predict(model_lgbm, X_train, y_train, cv=3)
y_val_predict
# 실행 결과
array([2, 0, 4, ..., 1, 3, 2])
모델은 lightgbm의 분류모델을 사용하여 cross_val_predict 했다.
score = (y_train == y_val_predict2).mean()
score
# 실행 결과
0.7801726026197048
그 결과 정확도는 약 0.78을 얻었다.
이제 데이콘에 제출하기 위해 X_train, y_train을 학습하고 X_test에 대한 예측을 해보자.
y_pred = model_lgbm.fit(X_train, y_train).predict(X_test)
y_pred
# 실행 결과
array([2, 3, 2, ..., 4, 0, 6])
X_test에 대한 토픽 예측 결과가 y_pred에 담겼다.
각 index에 대한 토픽 예측을 topic_idx에 할당한 형태다.
데이콘에 예측 결과를 제출하여 public score 0.76254, private score 0.75186이라는 점수를 받았다.
NLP는 정형 데이터에 비해 훨씬 더 복잡한 개념인 것 같다. 재미있었다.
'AI SCHOOL > TIL' 카테고리의 다른 글
[DAY 66] Week 15 Insight Day 미드프로젝트2 시작 (0) | 2023.03.30 |
---|---|
[DAY 65] Numpy를 이용한 SVD(특이값 분해) (0) | 2023.03.30 |
[DAY 63] 자연어 처리, BoW, Vectorizer, TF-IDF (0) | 2023.03.27 |
[DAY 62] Tableau 분산형 차트, 히스토그램, 박스플롯 (0) | 2023.03.25 |
[DAY 61] Week 14 Insight Day 미니프로젝트4 시작, 미드프로젝트1 리뷰 리포트 (0) | 2023.03.23 |
댓글