221005

AIVILLAIN·2022년 10월 5일
0

오공완

목록 보기
17/25

BOW

실습 코드

문서가 가지는 모든 단어를 문맥이나 순서를 무시하고 일괄적으로 단어에 대해 빈도 값을 부여하여 피처를 추출하는 모델
쉽고 빠른 구축
단순 단어의 발생 횟수에 기반하나 문서의 특징을 잘 나타낼 수 있는 모델이어서 전통적으로 여러 분야에서 활용도가 높음
하지만 BOW 기반 NLP 연구는 여러 제약에 부딪힘

  • 문맥 의미 반영 부족
    단어의 순서를 고려하지 않기에 문맥적인 의미가 무시됨
    이를 보완하기 위해 n_gram 기법 활용 가능하나 제한적인 부분에 그침
  • 희소 행렬 문제
    많은 문서에서 단어를 추출하면 매우 많은 단어가 칼럼으로 만들어짐
    문서마다 서로 다른 단어로 구성되기에 단어가 문서마다 나타나지 않는 경우가 훨씬 많음
    희소 행렬은 일반적으로 ML 알고리즘의 수행 시간과 예측 성능을 떨어트리기 때문에 이를 위한 기법이 마련되어 있음

BOW 피처 벡터화

ML 알고리즘은 숫자형 피처를 데이터로 입력받아 동작하기에 텍스트는 특정 의미를 갖는 숫자형 벡터 값으로 변환되어야 함

BOW 피처 벡터화 방식

  • 카운트 기반 벡터화
  • TF-IDF 벡터화

단어 피처에 값을 부여할 때 각 문서에서 해당 단어가 나타나는 횟수(Count)를 부여하는 경우를 카운트 벡터화라고 함
카운트 값이 높을 수록 중요한 단어로 인식됨
문장에서 자주 사용될 수 밖에 없는 단어까지 높은 값을 부여하게 되는 문제

TF-IDF(Term Frequency Inverse Document Frequency) 벡터화는 개별 문서에서 자주 나타나는 단어에 높은 가중치
모든 문서에서 전반적으로 자주 나타나는 단어에 대해서는 패널티
어떤 특정 문서에서 단어가 자주 나타나면 해당 문서를 특정짓는 중요 단어일 수 있음
하지만 다른 문서에서도 자주 나타나는 단어라면 언어 특성상 범용적으로 자주 사용되는 단어일 가능성이 높음

사이킷런의 ConterVectorizer 클래스는 카운트 기반 벡터화를 구현한 클래스
단지 피처 벡터화만 수행하지는 않으며 소문자 일괄 변환, 토큰화, 스톱 워드 필터링 등의 텍스트 전처리 함께 수행

  • max_df
    전체 문서에 걸쳐 너무 높은 빈도수의 단어 피처 제외를 위한 파라미터
    max_df = 100과 같이 정수 값을 가지면 해당 개수 이하로 나타나는 단어만 추출
    max_df = 0.95 같이 부동소수점 값을 가지면 전체 문서에 걸쳐 빈도수 백분율 까지의 단어만 피처로 추출, 나머지 상위 5%는 피처로 추출하지 않음
  • min_df
    낮은 빈도수 피처 제외를 위한 파라미터
  • max_features
    추출하는 피처의 개수를 제한
    가장 높은 빈도를 가지는 단어 순으로 정렬하여 개수 지정
  • stop_words
    english로 지정하면 영어 스톱 워드 지정 단어는 추출에서 제외
  • n_gram_range
    BOW 모델의 단어 순서를 어느 정도 보강하기 위한 n_gram 범위 설정
    튜플 형태로 (범위 최소값, 범위 최대값) 지정
  • analyzer
    피처 추출 수행 단위 지정
    default = ‘word’
    character의 특정 범위를 피처로 만드는 특정한 경우 등을 적용할 때 사용
  • token_pattern
    토큰화를 수행하는 정규 표현식 패턴 지정
    default = ‘\b\w\w+\b’
    공백 또는 개행 문자 등으로 구분된 단어 분리자 사이의 2개의 문자(문자 혹은 숫자) 이상의 단어를 토큰으로 분리
    analyzer = ‘word’로 설정했을 때만 변경 가능하나 디폴트를 변경할 경우는 거의 없음
  • tokenizer
    토큰화를 별도의 커스텀 함수로 이용시 적용
    CountTokenizer 클래스에서 어근 변환 시 이를 수행하는 별도의 함수를 tokenizer 파라미터에 적용
  1. 영어의 경우 모든 문자를 소문자로 변경하는 등 전처리 작업 수행
  2. 디폴트로 단어 기준 n_gram_range를 반영하여 각 단어 토큰화
  3. 텍스트 정규화 수행
    (stop_words 파라미터가 주어진 경우 스톱 워드만 필터링 가능)
    Stemming, Lemmatization 같은 어근 변환은 직접 지원하진 않으나 tokenizer 파라미터에 커스텀 어근 변환 함수를 적용하여 수행 가능
  4. max_df, min_df, max_features 등 파라미터를 이용해 토큰화된 단어를 피처로 추출하고 단어 빈도수 벡터 값 적용

BOW 벡터화를 위한 희소 행렬

사이킷런의 CounterVectorizer/TfidfVectorizer를 이용해 텍스트를 피처 단위로 벡터화해 변환하고 CSR 형태의 희소 행렬 반환
피처 벡터화된 희소 행렬이 어떤 형태인지 중요하지 않을 수 있으나 좀 더 난이도가 있는 ML 모델 수립을 위해서는 희소 행렬이 어떤 형태로 구성되어 있는 지 알아야 함

모든 문서에 있는 단어를 추출하여 이를 피처로 벡터화하는 방법은 필연적으로 많은 피처 칼럼을 만들 수 밖에 없음
대규모 행렬이 생성되더라도 레코드의 각 문서가 가지는 단어의 수는 제한적이기 때문에 이 행렬의 값은 대부분 0이 차지할 수 밖에 없음
대규모 행렬의 대부분의 값을 0이 차지하는 행렬을 가리켜 희소 행렬이라고 함
BOW 형태를 가진 언어 모델의 피처 벡터화는 대부분 희소 행렬

희소 행렬은 너무 많은 불필요한 0 값이 메모리 공간에 할당되며 행렬의 크기가 커서 연산 시에도 데이터 액세스를 위한 시간이 많이 소모됨
따라서 물리적으로 적은 메모리 공간을 차지할 수 있도록 변환해 줄 필요가 있는데 대표적인 방법으로 COO, CSR 형식이 있음

COO(Coordinate) 방식
0이 아닌 데이터만 별도의 데이터 배열에 저장하고 그 데이터가 가리키는 행과 열의 위치를 별도의 배열로 저장하는 방식
파이썬에서는 희소 행렬 변환을 위해 주로 Scipy 사용
scipy의 sparse 패키지는 희소 행렬 변환을 위한 다양한 모듈 제공

CSR(Compressed Sparse Row) 방식
COO 형식이 행과 열의 위치를 나타내기 위해 반복적인 위치 데이터를 사용해야 하는 문제점 보완
행 위치 배열 내에 있는 고유한 값의 시작 위치만 다시 별도의 위치 배열로 가지는 변환 방식

텍스트 분류

실습 코드

사이킷런의 fetch_20newsgroups() API를 이용하여 뉴스그룹 분류 수행
텍스트를 피처 벡터화로 변환하면 희소 행렬 형태
이러한 희소 행렬에 분류를 효과적으로 잘 처리할 수 있는 알고리즘은 로지스틱 회귀, 선형 서포트 벡터 머신, 나이브 베이즈 등
텍스트 기반으로 분류를 수행할 때는 텍스트를 정규화한 뒤 피처 벡터화 적용

텍스트 정규화

fetch_20newsgroups의 텍스트 데이터는 뉴스그룹 기사 내용 뿐만 아니라 제목, 작성자, 소속, 이메일 등 다양한 정보가 있음
기사 내용을 제외한 다른 정보 제거 제공

피처 벡터화, 머신러닝 모델 학습/예측/평가

CountVectorizer를 이용하여 학습 데이터 텍스트를 피처 벡터화
테스트 데이터 역시 피처 벡터화 수행
테스트 데이터에서 ConterVectorizer 적용 시 학습 데이터를 이용해 fit()이 수행된 CounterVectorizer 객체를 이용해 테스트 데이터를 변환해야 함

사이킷런 파이프라인 사용 및 GridSearchCV 결합

Pipeline 클래스를 이용하면 피처 벡터화와 ML 알고리즘 학습/예측을 위한 코드 작성을 한번에 진행 가능
머신러닝에서 Pipeline이란 데이터의 가공, 변환 등의 전처리와 알고리즘 적용을 마치 수도관에서 물이 흐르듯 한꺼번에 스트림 기반으로 처리한다는 의미
데이터 전처리, 머신러닝 학습 과정을 통일된 API 기반에서 처리할 수 있어 더 직관적인 ML 모델 코드를 생성할 수 있음
대용량 데이터의 피처 벡터화 결과를 별도 데이터로 저장하지 않고 스트림 기반에서 바로 머신러닝 알고리즘의 데이터로 입력할 수 있어 수행 시간을 절약할 수 있음

GridSearchCV에 Estimator가 아닌 Pipline 입력 시 param_grid 입력 값 설정이 기존과 약간 다름
딕셔너리 형태의 Key, Value를 가지며, value를 리스트로 입력하는 것은 동일하지만 하이퍼 파라미터명이 객체 변수명과 결합되어 제공해야함

모두의 파라미터를 최적화하려면 너무 많은 튜닝 시간이 소모됨
피처 벡터화 파라미터와 GridSearchCV 하이퍼 파라미터를 합치면 최적화를 위한 너무 많은 경우의 수가 발생하기 쉬움

profile
소신있는 오픈마인드

0개의 댓글