준지도 텍스트 분류

Beginner

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

소개

이 실습에서는 scikit-learn 을 사용하여 텍스트 데이터 세트에 대한 반지도 분류를 수행하는 방법을 배웁니다. 반지도 학습은 레이블이 지정된 데이터와 레이블이 지정되지 않은 데이터 모두를 사용하여 모델을 학습시키는 기계 학습 유형입니다. 이 실습에서는 반지도 텍스트 분류를 위해 Self-Training 및 LabelSpreading 알고리즘을 사용하는 방법을 다룰 것입니다. 20 뉴스그룹 데이터 세트를 사용하여 모델을 학습 및 테스트할 것입니다.

VM 팁

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

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

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

데이터셋 로드

20 개의 주제에 대한 약 18,000 개의 뉴스그룹 게시물을 포함하는 20 뉴스그룹 데이터셋을 사용할 것입니다. 이 단계에서는 데이터셋을 로드하고 데이터셋에 대한 기본 정보를 출력합니다.

import numpy as np
from sklearn.datasets import fetch_20newsgroups

## 처음 5 개 카테고리로 데이터셋 로드
data = fetch_20newsgroups(
    subset="train",
    categories=[
        "alt.atheism",
        "comp.graphics",
        "comp.os.ms-windows.misc",
        "comp.sys.ibm.pc.hardware",
        "comp.sys.mac.hardware",
    ],
)

## 데이터셋 정보 출력
print("%d documents" % len(data.filenames))
print("%d categories" % len(data.target_names))

지도 학습 파이프라인 생성

이 단계에서는 지도 학습을 위한 파이프라인을 생성합니다. 파이프라인은 텍스트 데이터를 토큰 빈도 행렬로 변환하는 CountVectorizer, 카운트 행렬에 역문서 빈도 정규화 (TF-IDF) 를 적용하는 TfidfTransformer, 그리고 모델을 학습하는 SGDClassifier 로 구성됩니다.

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.linear_model import SGDClassifier
from sklearn.pipeline import Pipeline

## SGDClassifier 의 매개변수
sdg_params = dict(alpha=1e-5, penalty="l2", loss="log_loss")

## CountVectorizer 의 매개변수
vectorizer_params = dict(ngram_range=(1, 2), min_df=5, max_df=0.8)

## 파이프라인 생성
pipeline = Pipeline(
    [
        ("vect", CountVectorizer(**vectorizer_params)),
        ("tfidf", TfidfTransformer()),
        ("clf", SGDClassifier(**sdg_params)),
    ]
)

지도 학습 모델 학습 및 평가

이 단계에서는 데이터셋을 학습용과 테스트용으로 분할하고, 2 단계에서 생성한 지도 학습 모델 파이프라인을 학습 및 평가합니다.

from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score

## 데이터셋을 학습용과 테스트용으로 분할
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(X, y)

## 지도 학습 모델 파이프라인 학습 및 평가
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)
print(
    "테스트 세트에서의 마이크로 평균 F1 점수: %0.3f"
    % f1_score(y_test, y_pred, average="micro")
)

자기지도 학습 파이프라인 생성

이 단계에서는 자기지도 학습을 위한 파이프라인을 생성합니다. 이 파이프라인은 지도 학습 파이프라인과 유사하지만, SGDClassifier 대신 SelfTrainingClassifier 를 사용합니다.

from sklearn.semi_supervised import SelfTrainingClassifier

## 자기지도 학습 파이프라인 생성
st_pipeline = Pipeline(
    [
        ("vect", CountVectorizer(**vectorizer_params)),
        ("tfidf", TfidfTransformer()),
        ("clf", SelfTrainingClassifier(SGDClassifier(**sdg_params), verbose=True)),
    ]
)

자기지도 학습 모델 학습 및 평가

이 단계에서는 레이블이 지정된 데이터의 20% 에 대해 자기지도 학습을 수행합니다. 레이블이 지정된 데이터의 20% 를 무작위로 선택하고, 해당 데이터로 모델을 학습한 다음, 나머지 레이블이 지정되지 않은 데이터에 대한 레이블을 예측하는 데 모델을 사용합니다.

import numpy as np

## 학습 데이터의 20% 선택
y_mask = np.random.rand(len(y_train)) < 0.2
X_20, y_20 = map(
    list, zip(*((x, y) for x, y, m in zip(X_train, y_train, y_mask) if m))
)

## 마스크가 지정되지 않은 부분을 레이블이 지정되지 않은 데이터로 설정
y_train[~y_mask] = -1

## 자기지도 학습 파이프라인 학습 및 평가
st_pipeline.fit(X_train, y_train)
y_pred = st_pipeline.predict(X_test)
print(
    "테스트 세트에서의 마이크로 평균 F1 점수: %0.3f"
    % f1_score(y_test, y_pred, average="micro")
)

LabelSpreading 파이프라인 생성

이 단계에서는 LabelSpreading 을 사용한 준지도 학습을 위한 파이프라인을 생성합니다. 이 파이프라인은 지도 학습 파이프라인과 유사하지만, SGDClassifier 대신 LabelSpreading 알고리즘을 사용합니다.

from sklearn.semi_supervised import LabelSpreading
from sklearn.preprocessing import FunctionTransformer

## LabelSpreading 파이프라인 생성
ls_pipeline = Pipeline(
    [
        ("vect", CountVectorizer(**vectorizer_params)),
        ("tfidf", TfidfTransformer()),
        ("toarray", FunctionTransformer(lambda x: x.toarray())),
        ("clf", LabelSpreading()),
    ]
)

LabelSpreading 모델 학습 및 평가

이 단계에서는 레이블이 지정된 데이터의 20% 에 대해 LabelSpreading 을 사용합니다. 레이블이 지정된 데이터의 20% 를 무작위로 선택하고, 해당 데이터로 모델을 학습한 다음, 나머지 레이블이 지정되지 않은 데이터에 대한 레이블을 예측하는 데 모델을 사용합니다.

## LabelSpreading 파이프라인 학습 및 평가
ls_pipeline.fit(X_train, y_train)
y_pred = ls_pipeline.predict(X_test)
print(
    "테스트 세트에서의 마이크로 평균 F1 점수: %0.3f"
    % f1_score(y_test, y_pred, average="micro")
)

요약

이 실습에서는 scikit-learn 을 사용하여 텍스트 데이터 세트에 대한 준지도 분류를 수행하는 방법을 배웠습니다. 자체 학습 (Self-Training) 및 LabelSpreading 알고리즘을 사용하여 모델을 학습하고 테스트했습니다. 준지도 학습은 레이블이 지정된 데이터가 제한적인 경우 유용하며, 레이블이 지정되지 않은 데이터를 통합하여 모델의 성능을 향상시키는 데 도움이 될 수 있습니다.