| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
Tags
- ASR
- UMAP
- 데이터 시각화
- 힙정렬
- TTS
- 랭그래프
- RDBMS
- 트랜스포머
- python기초
- 머신러닝
- 소프트웨어 개발
- CNN
- 데이터엔지니어
- python 기초
- CLIP
- Transformer
- 객체지향
- 자연어처리
- 에이전트
- dementional reduction
- 기초
- RNN
- 알고리즘
- SQL
- Python
- 딥러닝
- LangGraph
- 정보처리기사
- 생성형 인공지능
- 캐글
Archives
- Today
- Total
수달이네 기술 블로그
3. NSMC를 활용한 단어 분류 본문
NSMC(Naver Sentiment Movie Corpus)
네이버 영화 리뷰를 기반으로 구축된 한국어 감성 분석 데이터셋
- 200,000개의 리뷰
- 긍정(1), 부정 (0) 레이블로 분류
- 위 데이터셋을 분석해서 자연어를 분석할 것이다.
!pip install konlpy # 형태소분석기(이 안의 기능을 사용할 것)
!pip install mecab-python # 형태소 분석기 (형태소분석기는 이걸 사용)
!bash <(curl -s <https://raw.githubusercontent.com/konlpy/konlpy/master/scripts/mecab.sh>)
- 형태소분석기: 토크나이징 시킬때 형태소 별로 분석해서 나눔
사전 import
import urllib.request
from konlpy.tag import Mecab
from gensim.models.word2vec import Word2Vec
import pandas as pd
import matplotlib.pyplot as plt
데이터 가져오기
urllib.request.urlretrieve("<https://raw.githubusercontent.com/e9t/nsmc/master/ratings.txt>", filename="ratings.txt")
- request를 이용해 파일을 다운 받아온다.
- csv파일형식이나 txt파일로 저장되어있다.
train_data = pd.read_table('ratings.txt')
train_data[:5] # 상위 5개 출력
- read_table: txt파일을 데이터프레임으로 가져오는 함수
len(train_data)
# 200000
- train_Data가 잘 들어왔는지 확인하면 200000개의 리뷰가 들어온 것을 확인 가능하다.
train_data.isnull().values.any()
# np.True_
- isnull(): train_data에 null값이 있으면 true가 된다.
- values: 값만 나오게 된다.(False, True)
- any(): 한 값이라도 True일경우 np.True_를 반환
**train_data = train_data.dropna(how='any')**
- Na를 모두 지운다.
train_data['document'] = train_data['document'].str.replace("[^ㄱ-ㅎㅏ-ㅣ가-힣]","")
- ㄱ~ㅎ, ㅏ~ㅣ, 가~힣: 한글을 제외한 모든 문자는 지워버려
# 불용어 정의
stopwords = ['도', '는', '다', '의', '가', '이', '은', '한', '에', '하', '고', '을', '를', '인', '듯', '과', '와', '네', '들', '듯', '지', '임', '게']
- 핵심 의미를 담고 있지 않는 단어들으로, 분석 성능을 높이기 위해 사전에 제거하는 단어.
Mecab 형태소 분석
mecab = Mecab(dicpath='C:/mecab/mecab-ko-dic')
mecab.morphs('아버지가방에들어가신다')
# ['아버지', '가', '방', '에', '들어가', '신다']
mecab을 정의하고, mecab안에 문장을 집어 넣게 된다면 위와 같은 결과가 출력된다.
- mecab을 이용하면 형태소별로 다 단어가 쪼개진다.
- 그런데 가, 에 등의 조사는 사실상 의미가 없다. 따라서 위에서 등록한 불용어를 이용해준다.
tokenized_data = []
for sentence in train_data['document']:
temp_X = mecab.morphs(sentence)
temp_X = [word for word in temp_X if not word in stopwords]
tokenized_data.append(temp_X)
위처럼 문장을 형태소로 나눈 이후, 불용어를 제거해준다.
이후 해당 단어를 tokenized_data 리스트에 추가해주는 방식
tokenized_data[:3]
# [['어릴', '때', '보', '지금', '다시', '봐도', '재밌', '어요', 'ㅋㅋ'],
# ['디자인',
# '배우',
# '학생',
# '으로',
# ',',
# '외국',
# '디자이너',
# '그',
# '일군',
# '전통',
# '통해',
# '발전',
# '해',
# '문화',
# '산업',
# '부러웠',
# '는데',
# '.',
# '사실',
# '우리',
# '나라',
# '에서',
# '그',
# '어려운',
# ...
# '음',
# '.',
# '.',
# '최고',
# '.']]
# Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings...
- 위처럼 잘 나눠져 있는 것을 확인 가능하다.
Word2Vec
from gensim.models import Word2Vec
model = Word2Vec(
sentences=tokenized_data, #학습에 사용할 문장 데이터
vector_size = 100,# 벡터 표현
window = 5, # 중심 문자를 기준으로 주변 문자를 보는 범위
min_count = 5, # 몇 번 이상 등장한 단어만 학습에 포함
workers = 4, # 데이터를 로드해올때 병렬로 가져오는데 그 cpu를 몇개씩 사용할지
sg = 0 # 0: CBOW, 1: skipgram(다양하게 학습, 오래걸림)
)
문장데이터를 이용하여 실제 벡터로 표현
model.wv.vectors.shape
# (18937, 100)
- 18937개의 단어를 100차원으로 설명
- 위에서 설정한 vector_size
model.wv.most_similar('블록버스터')
# [('무협', 0.8200684189796448),
# ('헐리우드', 0.8104481101036072),
# ('느와르', 0.7927355170249939),
# ('호러', 0.7889633178710938),
# ('sf', 0.7870503664016724),
# ('히어로', 0.7753642797470093),
# ('SF', 0.7681315541267395),
# ('액션물', 0.7672512531280518),
# ('스릴러물', 0.7659397721290588),
# ('C', 0.7574071288108826)]
- 블록버스터라는 단어와 가깝게 설정된 단어 리스트를 출력
- 확인해보니 대체적으로 영화의 장르가 가깝게 표현된 것이 보인다. 그중 액션관련이 가까움.
model.wv['블록버스터']
# array([-0.0330137 , 0.6282359 , 0.42973697, -0.17335516, -0.17651196,
# -0.6970459 , -0.03660379, 1.071796 , -0.7118055 , -0.30753678,
# -0.6684205 , -0.36423868, 0.1587452 , 0.18972148, 0.13022877,
# -0.79741156, -0.77113366, -0.4358335 , 0.4195775 , -0.05206894,
# 0.2992659 , 0.09521263, 0.14125888, 0.44383216, 0.07732219,
# 0.1721758 , 0.5292899 , 0.28355977, -0.55120987, -0.15320441,
# 0.3874145 , 0.14900902, 0.89165574, -0.28329527, -0.29780605,
# 0.18838125, 0.31465304, 0.34367123, 0.3343019 , -0.09478841,
# -0.00584204, -0.5636469 , -0.32309744, -0.1949582 , -0.5196094 ,
# -0.1435047 , 0.11556148, 0.10881115, -0.14614736, -0.41629446,
# 0.47400606, -0.26186278, 0.16051935, -0.42663282, 0.33087805,
# 0.18830375, 0.41369492, -0.00120364, -0.3141201 , -0.2904882 ,
# 0.23806211, -0.11021748, -0.31155202, 0.19804363, 0.67300314,
# 0.46709877, 0.10293837, -0.15151775, -0.9722892 , 0.18762997,
# -0.31436935, -0.3784705 , 0.27354518, 0.1285775 , 0.14355294,
# 0.02435796, -0.9902095 , -0.4039165 , 0.12447012, 0.2442918 ,
# 0.18859306, 0.286661 , -0.53241134, 0.01927105, -0.0408907 ,
# 0.01711621, 0.37362412, -0.02828276, 0.70699257, 0.33849493,
# 0.42881256, -0.13219772, -0.49409807, 0.13272044, 0.28636417,
# 0.2736745 , 0.4566587 , -0.01637852, -0.13629532, 0.23960957],
# dtype=float32)
- 해당 단어를 설명하고 있는 100개의 실수 차원
from gensim.models import keyedvectors
model.wv.save_word2vec_format('kor_w2v')
- 위에서 형태소 분석을 하여 만든 가중치 데이터를 저장해주는 파일

- 실제로 잘 저장 된 것을 확인할 수 있다.
'AI공부 > 자연어처리' 카테고리의 다른 글
| 5. RNN(Recurrent Neural Network)기초 (1) | 2026.02.22 |
|---|---|
| 4. FastText (0) | 2026.02.21 |
| 2. 자연어 처리(벡터화) (1) | 2026.02.16 |
| 1. 자연어처리 (0) | 2026.02.16 |
| 0. 텐서플로우 (1) | 2026.02.14 |