프로그래밍/NLP

[ NLP ] 사이킷런을 사용해서 데이터를 수치화 하는 방법

Yanoo 2020. 9. 18. 00:49
728x90
반응형

사이킷런을 사용해서 데이터를 수치화 하는 방법

이 세 가지 방법은 모두 텍스트를 벡터로 만든다

 

  • CountVectorizer : 단순히 각 텍스트에서 횟수 기준으로 특징 추출하는 방법
  • TfidfVectorizer : TF-IDE라는 값을 사용해서 텍스트 특징 추출
  • HashingVectorizer : CountVectorizer과 동일한 방법이지만 텍스트를 처리할 때 해시를 이용하여 실행시간을 줄임

- CountVectorizer

 예를 들어 "나는 매일 공부를 한다" 문장을 횟수값으로 이뤄진 벡터로 만든다면 먼저 단어 사전을 정의한다

단어 사전에 "나는","너가","매일","공부를","한다","좋아한다" 6개 단어로 되어 있다고 하면 "나는 매일 공부를 한다" 문장의 경우  [1,0,1,1,1,0] 이라는 벡터로 바뀔 것이다. 이런 식으로 "나는 매일 매일 공부를 한다." 라는 문장은 [1,0,2,1,1,0]이 된다.

 

사이킷런 모듈을 사용해 구현해보면

from sklearn.feature_extraction.text import CountVectorizer

text_data=['나는 내일 공부 해야지','내일 날씨는 좋을까','내일 어디를 가지','공부 집에서 해야지']

count_vectorizer=CountVectorizer()

count_vectorizer.fit(text_data)
print(count_vectorizer.vocabulary_)

>> {'나는': 2, '내일': 4, '공부': 1, '해야지': 8, '날씨는': 3, '좋을까': 6, '어디를': 5, '가지': 0, '집에서': 7}

생성한 객체에 fit 함수를 사용해 데이터를 적용하면 자동으로 단어 사전을 생성한다.

>> {'나는': 2, '내일': 4, '공부': 1, '해야지': 8, '날씨는': 3, '좋을까': 6, '어디를': 5, '가지': 0, '집에서': 7}

결과를 보면 이렇게 사전 형태로 구성 되어 있음

 

입력한 텍스트 데이터를 실제 벡터로 확인해보면

sentence=[text_data[0]] # 나는 내일 공부 해야지
print(count_vectorizer.transform(sentence).toarray())
>>[[0 1 1 0 1 0 0 0 1]]

하지만 이런 방식은 조사나 지시대명사 때문에 큰 의미를 갖기는 어려울 수 있다. 이러한 문제점을 해결할 수 있는

TF-IDE 방식의 특징 추출 방법을 알아보자

 

- TfidVectorizer

TF-IDE라는 값을 사용해서 특징을 추출하는 방법.

TF : 특정 단어가 하나의 데이터 안에서 등장하는 횟수

DF : 문제 빈도 값으로, 특정 단어가 여러 데이터에 자주 등장하는지 알려주는 지표

IDF(Inverse) DF의 역수를 취해서 구하며, 특정 단어가 다른 데이터에 등장하지 않을 경우 값 커짐

TF-IDF란 이 두 값을 곱해서 사용하므로 어떤 단어가 해당 문서에 자주 등장하지만 다른 문서에는 많이 없는 단어일수록 높은 값을 가진다. 따라서 조사나 지시대명사처럼 자주 등장하는 단어는 TF 값은 크지만 IDF 값은 작아지므로 CountVectorizer가 가진 문제점 해결 가능

 

from sklearn.feature_extraction.text import TfidfVectorizer

text_data=['나는 내일 공부 해야지','내일 날씨는 좋을까','내일 어디를 가지','공부 집에서 해야지']

tfidf_vectorizer=TfidfVectorizer()

tfidf_vectorizer.fit(text_data)
print(tfidf_vectorizer.vocabulary_)
>>{'나는': 2, '내일': 4, '공부': 1, '해야지': 8, '날씨는': 3, '좋을까': 6, '어디를': 5, '가지': 0, '집에서': 7}

같은 방식으로 단어사전 만들기를 진행한 후 벡터로 바뀐 값도 출력해보면

 

sentence=[text_data[0]] # '나는 내일 공부 해야지'
print(tfidf_vectorizer.transform(sentence).toarray())
>>[[0.         0.4842629  0.61422608 0.         0.39205255 0.
  0.         0.         0.4842629 ]]

먼저 헷갈릴 거같아 단어 사전을 정리해 보면

[

0 : '가지',

1 : '공부',

2 : '나는',

3 : '날씨는',

4 : '내일',

5 : '어디를',

6 : '좋을까',

7 : '집에서',

8 : '해야지'

]

와 벡터로 바뀐 값을 비교해보자. 예시 문장은 '나는 내일 공부 해야지' 이므로 1,2,4,8 이외의 값은 0이 나왔다.

TF-IDF값을 확인해보면 우선 해당 문장 안에서 단어의 출현 빈도를 측정하고 해당 단어가 다른 데이터에서는 잘 나오지 않은 값일수록 높은 값을 가진다고 했으므로 '나는'이라는 단어는 text_data[0]에서 밖에 가지지 않아 다른 단어보다 값이 높게 나왔다. 그리고 '공부'와 '해야지'는 text_data[0]이외에도 text_data[3]에서 한번씩만 더 사용되어 있으므로 값이 같은 것을 확인할 수 있다.

 

이렇게 TF-IDF 값을 사용할 경우 단순 횟수 이용보다는 각 단어 특성을 반영할 수 있다.

 

 

 

[ 출처 : 책 ( 텐서플로와 머신러닝으로 시작하는 자연어 처리) ]

728x90
반응형