피처 벡터화 : One-hot encoding
Bag of Words
- 문맥이나 순서를 무시하고 일괄적으로 단어에 대한 빈도 값을 부여해 피처 값을 추출하는 모델
- 단점 : 문맥 의미 반영 부족, 희소 행렬 문제
BOW에서 피처 벡터화
- 모든 단어를 컬럼 형태로 나열하고 각 문서에서 해당 단어의 횟수나 정규화된 빈도를 값으로 부여하는 데이터 세트 모델로 변경하는 것
피처 벡터화 방식
- 카운트 기반, TF-IDF(Term Frequency - Inverse Document Frequency) 기반 벡터화
카운트 벡터화
- 카운트 값이 높을수록 중요한 단어로 인식. 특성상 자주 사용되는 보편적인 단어까지 높은 값 부여
TF-IDF
- 모든 문서에서 전반적으로 자주 나타나는 단어에 대해서 패널티 부여. '빈번하게', '당연히', '조직', '업무' 등
파라미터
- max_df : 너무 높은 빈도수를 가지는 단어 피처를 제외
- min_df : 너무 낮은 빈도수를 가지는 단어 피처를 제외
- max_features : 추출하는 피처의 개수를 제한하며 정수로 값을 지정
- stop_words : 'english'로 지정하면 스톱 워드로 지정된 단어는 추출에서 제외
- n_gram_range : 튜플 형태로 (범위 최솟값, 범위 최댓값)을 지정
- analyzer : 피처 추출을 수행하는 단위. 디폴트는 'word'
- token_pattern : 토큰화를 수행하는 정규 표현식 패턴을 지정
- tokenizer : 토큰화를 별도의 커스텀 함수로 이용시 적용
희소 행렬
1. COO 형식
- 0이 아닌 데이터만 별도의 데이터 배열에 저장하고
- 행과 행의 위치를 별도의 배열로 저장
- 희소 행렬 변환을 위해 scipy sparse 패키지를 이용
import numpy as np
from scipy import sparse
data = np.array([3,1,2])
row_pos = np.array([0,0,1])
col_pos = np.array([0,2,1])
sparse_coo = sparse.coo_matrix((data,(row_pos,col_pos)))
print(sparse_coo)
sparse_coo.toarray()
#출력
(0, 0) 3
(0, 2) 1
(1, 1) 2
array([[3, 0, 1],
[0, 2, 0]])
2. CSR 형식
- COO 형식의 반복적인 위치 데이터를 사용하는 문제점을 보완.
- 반복 제거(위치의 위치를 표기), 메모리 적게 들고 빠른 연산 가능
import numpy as np
from scipy import sparse
# dense2 = np.array([[0,0,1,0,0,5],
# [1,4,0,3,2,5],
# [0,6,0,3,0,0],
# [2,0,0,0,0,0],
# [0,0,0,7,0,8],
# [1,0,0,0,0,0]])
data2 = np.array([1, 5, 1, 4, 3, 2, 5, 6, 3, 2, 7, 8, 1])
# row_pos = np.array([0, 0, 1, 1, 1, 1, 1, 2, 2, 3, 4, 4, 5])
col_pos = np.array([2, 5, 0, 1, 3, 4, 5, 1, 3, 0, 3, 5, 0])
# COO 형식으로 변환
# sparse_coo = sparse.coo_matrix((data2,(row_pos,col_pos)))
# 행 위치 배열의 고유한 값들의 시작 위치 인덱스를 배열로 생성
row_pos_ind = np.array([0,2,7,9,10,12,13])
# CSR 형식으로 변환
sparse_csr = sparse.csr_matrix((data2, col_pos,row_pos_ind))
# print(sparse_coo)
print()
print(sparse_csr)
print(sparse_csr.toarray())
#출력
(0, 2) 1
(0, 5) 5
(1, 0) 1
(1, 1) 4
(1, 3) 3
(1, 4) 2
(1, 5) 5
(2, 1) 6
(2, 3) 3
(3, 0) 2
(4, 3) 7
(4, 5) 8
(5, 0) 1
[[0 0 1 0 0 5]
[1 4 0 3 2 5]
[0 6 0 3 0 0]
[2 0 0 0 0 0]
[0 0 0 7 0 8]
[1 0 0 0 0 0]]
3. 밀집 행렬을 생성 파라미터로 입력하면 COO, CSR 희소 행렬로 생성
dense3 = np.array([[0,0,1,0,0,5],
[1,4,0,3,2,5],
[0,6,0,3,0,0],
[2,0,0,0,0,0],
[0,0,0,7,0,8],
[1,0,0,0,0,0]])
coo = sparse.coo_matrix(dense3)
csr = sparse.csr_matrix(dense3)
print(coo)
print()
print(csr)
#출력
(0, 2) 1
(0, 5) 5
(1, 0) 1
(1, 1) 4
(1, 3) 3
(1, 4) 2
(1, 5) 5
(2, 1) 6
(2, 3) 3
(3, 0) 2
(4, 3) 7
(4, 5) 8
(5, 0) 1
(0, 2) 1
(0, 5) 5
(1, 0) 1
(1, 1) 4
(1, 3) 3
(1, 4) 2
(1, 5) 5
(2, 1) 6
(2, 3) 3
(3, 0) 2
(4, 3) 7
(4, 5) 8
(5, 0) 1
DictVectorizer
- 문서에서 단어의 사용 빈도를 나타내는 딕셔너리 정보를 입력받아 BOW 인코딩한 수치 벡터로 변환
from sklearn.feature_extraction import DictVectorizer
v = DictVectorizer(sparse=False)
D = [{'A': 1, 'B': 2}, {'B': 3, 'C': 1}]
X = v.fit_transform(D)
print(v.feature_names_)
print(v.vocabulary_)
print(X)
print()
print(v.transform({'C': 4, 'D': 3}))
#출력
['A', 'B', 'C']
{'A': 0, 'B': 1, 'C': 2}
[[1. 2. 0.]
[0. 3. 1.]]
[[0. 0. 4.]]
CountVectorizer
- 문서를 토큰 리스트로 변환
- 각 문서에서 토큰의 출현 빈도 카운트
- 각 문서를 BOW 인코딩 벡터로 변환
from sklearn.feature_extraction.text import CountVectorizer
corpus = [
'This is the first document.',
'This is the second second document.',
'And the third one.',
'Is this the first document?',
'The last document?',
]
vect = CountVectorizer()
vect.fit(corpus) # fit() 는 데이터를 모델에 학습시킬 때 사용.
print(vect.get_feature_names())
print(vect.vocabulary_)
print()
print(vect.transform(['This is the second document']).toarray())
# transform() 은 데이터를 알맞게 변형해 줌
print()
print(vect.transform(['Something completely new.']).toarray())
print()
print(vect.transform(corpus).toarray())
#출력
['and', 'document', 'first', 'is', 'last', 'one', 'second', 'the', 'third', 'this']
{'this': 9, 'is': 3, 'the': 7, 'first': 2, 'document': 1, 'second': 6, 'and': 0, 'third': 8, 'one': 5, 'last': 4}
[[0 1 0 1 0 0 1 1 0 1]]
[[0 0 0 0 0 0 0 0 0 0]]
[[0 1 1 1 0 0 0 1 0 1]
[0 1 0 1 0 0 2 1 0 1]
[1 0 0 0 0 1 0 1 1 0]
[0 1 1 1 0 0 0 1 0 1]
[0 1 0 0 1 0 0 1 0 0]]
Stop Words
- 문서에서 단어장을 생성할 때 무시할 수 있는 단어. 보통 영어의 관사나 접속사, 한국어의 조사 등
vect = CountVectorizer(stop_words=["and", "is", "the", "this"]).fit(corpus)
vect.vocabulary_
#출력
{'first': 1, 'document': 0, 'second': 4, 'third': 5, 'one': 3, 'last': 2}