문서가 가지는 모든 단어를 문맥이나 순서를 무시하고 일괄적으로 단어에 대해 빈도 값을 부여하여 피처를 추출하는 모델
쉽고 빠른 구축
단순 단어의 발생 횟수에 기반하나 문서의 특징을 잘 나타낼 수 있는 모델이어서 전통적으로 여러 분야에서 활용도가 높음
하지만 BOW 기반 NLP 연구는 여러 제약에 부딪힘
ML 알고리즘은 숫자형 피처를 데이터로 입력받아 동작하기에 텍스트는 특정 의미를 갖는 숫자형 벡터 값으로 변환되어야 함
BOW 피처 벡터화 방식
단어 피처에 값을 부여할 때 각 문서에서 해당 단어가 나타나는 횟수(Count)를 부여하는 경우를 카운트 벡터화라고 함
카운트 값이 높을 수록 중요한 단어로 인식됨
문장에서 자주 사용될 수 밖에 없는 단어까지 높은 값을 부여하게 되는 문제
TF-IDF(Term Frequency Inverse Document Frequency) 벡터화는 개별 문서에서 자주 나타나는 단어에 높은 가중치
모든 문서에서 전반적으로 자주 나타나는 단어에 대해서는 패널티
어떤 특정 문서에서 단어가 자주 나타나면 해당 문서를 특정짓는 중요 단어일 수 있음
하지만 다른 문서에서도 자주 나타나는 단어라면 언어 특성상 범용적으로 자주 사용되는 단어일 가능성이 높음
사이킷런의 ConterVectorizer 클래스는 카운트 기반 벡터화를 구현한 클래스
단지 피처 벡터화만 수행하지는 않으며 소문자 일괄 변환, 토큰화, 스톱 워드 필터링 등의 텍스트 전처리 함께 수행
사이킷런의 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 객체를 이용해 테스트 데이터를 변환해야 함
Pipeline 클래스를 이용하면 피처 벡터화와 ML 알고리즘 학습/예측을 위한 코드 작성을 한번에 진행 가능
머신러닝에서 Pipeline이란 데이터의 가공, 변환 등의 전처리와 알고리즘 적용을 마치 수도관에서 물이 흐르듯 한꺼번에 스트림 기반으로 처리한다는 의미
데이터 전처리, 머신러닝 학습 과정을 통일된 API 기반에서 처리할 수 있어 더 직관적인 ML 모델 코드를 생성할 수 있음
대용량 데이터의 피처 벡터화 결과를 별도 데이터로 저장하지 않고 스트림 기반에서 바로 머신러닝 알고리즘의 데이터로 입력할 수 있어 수행 시간을 절약할 수 있음
GridSearchCV에 Estimator가 아닌 Pipline 입력 시 param_grid 입력 값 설정이 기존과 약간 다름
딕셔너리 형태의 Key, Value를 가지며, value를 리스트로 입력하는 것은 동일하지만 하이퍼 파라미터명이 객체 변수명과 결합되어 제공해야함
모두의 파라미터를 최적화하려면 너무 많은 튜닝 시간이 소모됨
피처 벡터화 파라미터와 GridSearchCV 하이퍼 파라미터를 합치면 최적화를 위한 너무 많은 경우의 수가 발생하기 쉬움