본문 바로가기

데이터/Machine Learning

[머신러닝] MultiLabel Classification을 이용한 속성 분류 모델

속성분류 모델

개요

  • 인풋 값으로 텍스트를 받아, 총 6개의 속성(’가격’, ‘제형’, ‘색상’, ‘향’, ‘디자인’, ‘사용감’) 중 어떤 속성들에 해당하는 지를 예측하는 모델을 생성하고자 함
  • Multiclass classification이면서 동시에, y값으로 1개~6개를 반환하기에 Multilabel classification 문제임
  • X, Y 형태는 다음과 같음

데이터 전처리

X, feature

  • feature EDA
print('feature 평균 길이 :', np.mean(df['feature'].str.len()))
print('feature 최대 길이 :', max(df['feature'].str.len()))
print('feature 최소 길이 :', min(df['feature'].str.len()))

  • 길이 7이하는 전혀 의미가 없는 feature들이므로 삭제
  • short_len_idx = df[df['feature'].str.len() < 7].index # 길이 7 이하는 불필요한 내용만 담고 있음 -> 삭제 df.drop(short_len_idx, axis=0, inplace=True) df.reset_index(inplace=True) df.info()
# 불필요한 괄호 등 제외하고 한글만 뽑아내기
def get_morph(text):
    text = re.findall('[ㄱ-힣]+', text)
    text = ' '.join(text)
    return text

feature = df['NlpMorpheme'].apply(get_morph)

Y, target

  • Y 값 살펴보기
df['Property'].value_counts()

 

  • MultiLabelBinarizer()로 원핫 인코딩
    • MultiLabelBinarizer
    • 여러개의 속성값들을, 각 속성값의 벡터로 표현하여 속성에 해당하면 1, 해당하지 않으면 0으로 표현하여 여러개의 이진분류 문제로 바꿔줌
    from sklearn.preprocessing import MultiLabelBinarizer
    mlb = MultiLabelBinarizer()
    mlb.fit([’가격’, ‘디자인’, ‘사용감’, ‘색상’, ‘제형’, ‘향’])
    
    import re
    df['target'] = df['Property'].apply(lambda x : ' '.join(re.findall(r'\\w{1,}', x)))
    y_data = df['target'].apply(lambda y_list : [y for y in y_list.split(' ')])
    
    target = mlb.transform(y_data)
    
    pd.DataFrame(target, columns = mlb.classes_)
    

모델 학습

Stopwords 만들기

Train, Test 분할하기

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split

X = feature
y = target

# 이미 학습된 tfidf vectorizer 로드

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# tfidf vectorizing
tfidf = TfidfVectorizer(min_df=2, token_pattern='\\w{1,}', ngram_range=(1,2), stop_words=stop_words, norm='l2')
X_train = tfidf.fit_transform(X_train)
X_test = tfidf.transform(X_test)

# le = LabelEncoder()
# y_train = le.fit_transform(y_train)
# y_test = le.transform(y_test)

print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)

학습

  • Multilabel classification에 사용 가능한 모델은 아래와 같음
    • tree.DecisionTreeClassifier
    • tree.ExtraTreeClassifier
    • ensemble.ExtraTreesClassifier
    • neighbors.KNeighborsClassifier
    • neural_network.MLPClassifier
    • neighbors.RadiusNeighborsClassifier
    • ensemble.RandomForestClassifier
    • linear_model.RidgeClassifier
    • linear_model.RidgeClassifierCV
  • 속도가 빠른 DecisionTreeClassifier 사용
    • 희소 행렬 형태로, 무수히 많은 column들이 있는 행렬이 feature로 입력되기에 Max Depth가 51로 매우 크다. → Pruning이 필요함
from sklearn.tree import DecisionTreeClassifier

dt = DecisionTreeClassifier()

dt.fit(X_train, y_train)

평가

from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
pred = dt.predict(X_test)

accuracy_score(y_test, pred)
print(classification_report(y_test, pred))

 

  • MultiLabelBinarizer는 0~5 사이의 정수로 레이블을 나타내기에 보기가 불편하다
  • 불린 인덱싱으로 통과시켜 값을 한글로 볼 수 있다.
# astype('bool') 메서드를 사용해서 해당 요소만 뽑아올 수 있다.
mlb.classes_[pred[0].astype('bool'

 


참고

  1. https://scikit-learn.org/stable/modules/preprocessing_targets.html#multilabelbinarizer
  2. https://scikit-learn.org/stable/modules/multiclass.html
  3. https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MultiLabelBinarizer.html#sklearn.preprocessing.MultiLabelBinarizer
  4. https://towardsdatascience.com/evaluating-multi-label-classifiers-a31be83da6ea