2. IMDB 영화리뷰 데이터 분류
IMDB 영화리뷰 데이터 분류
데이터셋
🔶 영문 영화 리뷰 데이터셋
🔶 라벨 : neg(부정), pos(긍정), unsup(라벨없음 - 비지도학습용)
🔶 100,000개 데이터로 구성
1. 데이터 셋 불러오기
코드
df = pd.read_csv(base_path + 'imdb_master.csv', encoding='latin-1')
df.head(5)
결과
![[Screenshot_426.png]]
2. 전처리
🔶사용할 컬럼만 선택 (review, label)
코드
df_2 = df[['review','label']]
결과
![[Screenshot_427.png]]
3. EDA
🔶EDA : 데이터를 수정하지 않고 눈으로 확인하는 작업 ◻ 오류, 결측치 , 이상치 유무 확인 ◻ 편향유무 ◻ 분산,평균확인 ◻ 시각화
🔶 피쳐엔지니어링 : 요구사항에 맞게 데이터를 가공하는 작업
🔶 라벨 클래스의 갯수확인 -> 범주형 데이터의 편향을 확인
코드
df2['label'].value_counts()
결과
![[Screenshot_428.png]]
🔶 unsup 제거
코드
filter_mask = df2['label'] == 'unsup'
df2.drop(df2[filter_mask].index, inplace=True)
df2['label'].value_counts()
결과
![[Screenshot_429.png]]
🔶 review 컬럼 에 영문만 남기기 코드
df['review'] = df2['review'].apply(lambda x: re.sub('[^A-Za-z\\\\s]','',x))
결과 ![[Screenshot_430.png]]
🔶 review 컬럼 에 비어있는지 확인
코드
df2[df2['review'] == '']
결과
![[Screenshot_431.png]]
- --> 빈 데이터는 따로 없음
4. 학습준비
🔶 훈련/검증 데이터 분리
코드
X = df2['review']
y = df2['label']
X_train,X_val, y_train, y_val = train_test_split(X,y, test_size=0.25, random_state=SEED)
X_train.shape, X_val.shape, y_train.shape, y_val.shape
결과 ((37500,), (12500,), (37500,), (12500,))
🔶 텍스트마이닝
◻ 토큰화/인코딩 ◽ Count Vectorizer
cv = CountVectorizer(max_features=10000)
cv.fit(X_train)
X_train_cv = cv.transform(X_train).toarray()
X_val_cv = cv.transform(X_val).toarray()
◽ TF-IFD Vectorizer
tf = TfidfVectorizer(max_features=10000)
tf.fit(X_train)
X_train_tf = tf.transform(X_train).toarray()
X_val_tf = tf.transform(X_val).toarray()
5. 학습/검증
◻ 사용모델 ◽ Linear Regression ◽ Random Forest ◽ Light GBM
◻ 훈련 ◽ Count Vectorizer
# 훈련(CountVectorizer)
lr_model = LogisticRegression(C=10,max_iter=15000)
lr_model.fit(X_train_cv, y_train)
train_score_cv = lr_model.score(X_train_cv, y_train)
valid_score_cv = lr_model.score(X_val_cv, y_val)
print(f'train score : {train_score_cv*100:.2f}%')
print(f'valid score : {valid_score_cv*100:.2f}%')
◽ TF-IFD Vectorizer
# 훈련(TF-IDF Vectorizer)
lr_model = LogisticRegression(C=10,max_iter=15000)
lr_model.fit(X_train_tf, y_train)
train_score_tf = lr_model.score(X_train_tf, y_train)
valid_score_tf = lr_model.score(X_val_tf, y_val)
print(f'train score : {train_score_tf*100:.2f}%')
print(f'valid score : {valid_score_tf*100:.2f}%')
6. 예측
◻ 예측 ◽ 랜덤포레스트
# 랜덤 포레스트 모델 훈련/예측
rf_model = RandomForestClassifier()
rf_model.fit(X_train_cv, y_train)
train_score_cv = rf_model.score(X_train_cv, y_train)
valid_score_cv = rf_model.score(X_val_cv, y_val)
print(f'train score : {train_score_cv*100:.2f}%')
print(f'valid score : {valid_score_cv*100:.2f}%')
# 예측(CountVectorizer)
pred = rf_model.predict(X_val_cv)
score = accuracy_score(pred,y_val)
print(f'accuracy score : {score*100:.1f}%')
◽ LightGBM
# LightGBM 모델 훈련/예측
lgbm_model = LGBMClassifier(verbose=-1)
lgbm_model.fit(X_train_tf, y_train)
train_score_tf = lgbm_model.score(X_train_tf, y_train)
valid_score_tf = lgbm_model.score(X_val_tf, y_val)
print(f'train score : {train_score_cv*100:.2f}%')
print(f'valid score : {valid_score_cv*100:.2f}%')
# 예측(TF-IDF Vectorizer)
pred = lgbm_model.predict(X_val_tf)
score = accuracy_score(pred,y_val)
print(f'accuracy score : {score*100:.1f}%')
7. 임베딩후 훈련
임베딩 사용을 위한 gensim 설치 주의! : Colab이용시, numpy와 충돌발생하므로 설치후 세션 재시작
!pip install gensim
🔶 토큰화 코드
# 토큰화
from tqdm.auto import tqdm
def tokenize_text(texts) :
return [word_tokenize(text) for text in tqdm(texts)]
X_train_token = tokenize_text(X_train)
X_val_token = tokenize_text(X_val)
🔶FastText로 임베딩 코드
fasttext_model = FastText(sentences=tqdm(X_train_token), vector_size=100, window=3, min_count=1, sg=1)
def get_sentence_vector(tokens,model):
vectors = [model.wv[word] for word in tokens if word in model.wv]
return np.mean(vectors, axis=0) if vectors else np.zeros(model.vector_size)
X_train_vec = np.array([get_sentence_vector(tokens,fasttext_model) for tokens in X_train_token])
X_valid_vec = np.array([get_sentence_vector(tokens,fasttext_model) for tokens in X_val_token])
🔶 훈련/검증 코드
lr_model = LogisticRegression(C=10,max_iter=15000)
lr_model.fit(X_train_vec, y_train)
rf_model = RandomForestClassifier(random_state=SEED,n_estimators=100)
rf_model.fit(X_train_vec, y_train)
lgbm_model = LGBMClassifier(verbose=-1)
lgbm_model.fit(X_train_vec, y_train)
# 훈련/검증
lr_score_train = lr_model.score(X_train_vec, y_train)
rf_score_train = rf_model.score(X_train_vec, y_train)
lgbm_score_train = lgbm_model.score(X_train_vec, y_train)
lr_score_val = lr_model.score(X_valid_vec, y_val)
rf_score_val = rf_model.score(X_valid_vec, y_val)
lgbm_score_val = lgbm_model.score(X_valid_vec, y_val)
print('='*150)
print(f'Linear Regression train score : {lr_score_train*100:.2f}%')
print(f'Random Forest train score : {rf_score_train*100:.2f}%')
print(f'LGBM train score : {lgbm_score_train*100:.2f}%')
print('-'*50)
print(f'Linear Regression valid score : {lr_score_val*100:.2f}%')
print(f'Random Forest valid score : {rf_score_val*100:.2f}%')
print(f'LGBM valid score : {lgbm_score_val*100:.2f}%')
print('='*150)
결과
![[Screenshot_433 1.png]]
🔶예측
코드
# 예측
lr_pred = lr_model.predict(X_valid_vec)
rf_pred = rf_model.predict(X_valid_vec)
lgbm_pred = lgbm_model.predict(X_valid_vec)
# 스코어
lr_score = accuracy_score(lr_pred,y_val)
rf_score = accuracy_score(rf_pred,y_val)
lgbm_score = accuracy_score(lgbm_pred,y_val)
# 스코어 출력
print(f'Linear Regression score : {lr_score*100:.2f}%')
print(f'Random Forest score : {rf_score*100:.2f}%')
print(f'LGBM score : {lgbm_score*100:.2f}%')
결과
![[Screenshot_434.png]]
랜덤 포레스트
🔶 주요 하이퍼 파라미터
◻ 트리의개수 : n_estimate
◻ 특징의 최대수 : max_feature
◻ 랜덤값 : randomseed
🔶Tip! :
- 기존 결정트리의 단점은 너무 복잡하다 = 모든 특성을 맞춰야 해서 과대적합발생
- (=만족조건이 너무까다로움)
- ex) 핸드폰의 조건은 ? 사각형이다,카메라가몇개다,액정이있고..등등 자세한조건에 맞추면 형태가 다른 모델은 핸드폰으로 예측할수 없음
- 때문에 일반화가 필요하다.
- 예를들어 여러모델의 앙상블 즉 투표를 통해 평균을 내는 방식으로 진행한다고 보면 이해가 쉬움