텍스트 특징 추출 및 평가

Beginner

This tutorial is from open-source community. Access the source code

소개

scikit-learn 라이브러리는 텍스트 특징 추출 및 평가를 위한 도구를 제공합니다. 이 실습에서는 20newsgroups 데이터셋을 사용하여 텍스트 데이터에서 특징을 추출하고, 파이프라인을 구축하며, 하이퍼파라미터 튜닝을 통해 모델의 성능을 평가하는 방법을 보여줍니다.

VM 팁

VM 시작이 완료되면 왼쪽 상단 모서리를 클릭하여 Notebook 탭으로 전환하여 연습용 Jupyter Notebook에 접근합니다.

때때로 Jupyter Notebook 이 완전히 로드되기까지 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한으로 인해 작업의 유효성 검사를 자동화할 수 없습니다.

학습 중 문제가 발생하면 Labby 에게 문의하십시오. 세션 후 피드백을 제공하면 문제를 신속하게 해결해 드리겠습니다.

데이터 로드

20 개의 서로 다른 카테고리에 걸쳐 약 20,000 개의 뉴스그룹 문서가 모인 20newsgroups 데이터셋을 로드합니다. 이 실습에서는 alt.atheism 및 talk.religion.misc 두 가지 카테고리에 집중합니다.

from sklearn.datasets import fetch_20newsgroups

categories = [
    "alt.atheism",
    "talk.religion.misc",
]

data_train = fetch_20newsgroups(
    subset="train",
    categories=categories,
    shuffle=True,
    random_state=42,
    remove=("headers", "footers", "quotes"),
)

data_test = fetch_20newsgroups(
    subset="test",
    categories=categories,
    shuffle=True,
    random_state=42,
    remove=("headers", "footers", "quotes"),
)

print(f"Loading 20 newsgroups dataset for {len(data_train.target_names)} categories:")
print(data_train.target_names)
print(f"{len(data_train.data)} documents")

하이퍼파라미터 튜닝을 사용한 파이프라인 정의

텍스트 분류를 위해 텍스트 특징 벡터화기와 간단한 분류기를 결합한 파이프라인을 정의합니다. Complement Naive Bayes 를 분류기로, TfidfVectorizer 를 특징 추출기로 사용합니다.

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import ComplementNB
from sklearn.pipeline import Pipeline
import numpy as np

pipeline = Pipeline(
    [
        ("vect", TfidfVectorizer()),
        ("clf", ComplementNB()),
    ]
)

parameter_grid = {
    "vect__max_df": (0.2, 0.4, 0.6, 0.8, 1.0),
    "vect__min_df": (1, 3, 5, 10),
    "vect__ngram_range": ((1, 1), (1, 2)),  ## unigrams or bigrams
    "vect__norm": ("l1", "l2"),
    "clf__alpha": np.logspace(-6, 6, 13),
}

하이퍼파라미터 튜닝

랜덤 검색 (RandomizedSearchCV) 을 사용하여 하이퍼파라미터 그리드를 탐색하고 파이프라인에 대한 최상의 하이퍼파라미터 조합을 찾습니다. 이 경우 n_iter=40으로 검색 공간을 제한합니다. 더욱 정보적인 분석을 위해 n_iter 값을 늘릴 수 있지만, 계산 시간이 증가합니다.

from pprint import pprint
from sklearn.model_selection import RandomizedSearchCV

random_search = RandomizedSearchCV(
    estimator=pipeline,
    param_distributions=parameter_grid,
    n_iter=40,
    random_state=0,
    n_jobs=2,
    verbose=1,
)

print("Performing grid search...")
print("Hyperparameters to be evaluated:")
pprint(parameter_grid)

random_search.fit(data_train.data, data_train.target)

test_accuracy = random_search.score(data_test.data, data_test.target)

결과 시각화

Plotly.express 를 사용하여 하이퍼파라미터 튜닝 결과를 시각화할 수 있습니다. 점 산점도를 사용하여 평균 테스트 점수와 스코어링 시간 간의 트레이드오프를 시각화합니다. 또한 평행 좌표를 사용하여 조정된 하이퍼파라미터의 함수로서 평균 테스트 점수를 추가적으로 시각화할 수 있습니다.

import pandas as pd
import plotly.express as px
import math

def shorten_param(param_name):
    """Remove components' prefixes in param_name."""
    if "__" in param_name:
        return param_name.rsplit("__", 1)[1]
    return param_name

cv_results = pd.DataFrame(random_search.cv_results_)
cv_results = cv_results.rename(shorten_param, axis=1)

param_names = [shorten_param(name) for name in parameter_grid.keys()]
labels = {
    "mean_score_time": "CV 스코어 시간 (초)",
    "mean_test_score": "CV 스코어 (정확도)",
}
fig = px.scatter(
    cv_results,
    x="mean_score_time",
    y="mean_test_score",
    error_x="std_score_time",
    error_y="std_test_score",
    hover_data=param_names,
    labels=labels,
)

fig.update_layout(
    title={
        "text": "스코어링 시간과 평균 테스트 점수 간의 트레이드오프",
        "y": 0.95,
        "x": 0.5,
        "xanchor": "center",
        "yanchor": "top",
    }
)

column_results = param_names + ["mean_test_score", "mean_score_time"]

transform_funcs = dict.fromkeys(column_results, lambda x: x)
## alpha 에 대한 로그 스케일 사용
transform_funcs["alpha"] = math.log10
## L1 정규화는 인덱스 1, L2 정규화는 인덱스 2 에 매핑
transform_funcs["norm"] = lambda x: 2 if x == "l2" else 1
## unigram 은 인덱스 1, bigram 은 인덱스 2 에 매핑
transform_funcs["ngram_range"] = lambda x: x[1]

fig = px.parallel_coordinates(
    cv_results[column_results].apply(transform_funcs),
    color="mean_test_score",
    color_continuous_scale=px.colors.sequential.Viridis_r,
    labels=labels,
)
fig.update_layout(
    title={
        "text": "텍스트 분류기 파이프라인의 평행 좌표 플롯",
        "y": 0.99,
        "x": 0.5,
        "xanchor": "center",
        "yanchor": "top",
    }
)

요약

이 실험에서는 텍스트 데이터에서 특징을 추출하고, 파이프라인을 구축하며, 하이퍼파라미터 튜닝을 통해 모델의 성능을 평가하는 방법을 보여주었습니다. 20newsgroups 데이터셋을 사용하여 RandomizedSearchCV 를 활용하여 파이프라인에 대한 최적의 하이퍼파라미터 조합을 찾고, Plotly.express 를 이용하여 결과를 시각화하는 방법을 보여주었습니다.