Ethan's Values
파이썬 데이터 주무르기 8장 자연어 처리(5~7/8절) 본문
https://hykethan.tistory.com/24
파이썬 데이터 주무르기 8장 자연어 처리 시작하기(~4/8절)
1. 한글 자연어 처리 기초 - KoNLPy 및 필요 모듈의 설치 먼저 설치와 주의해야 되는 것들이 있습니다. **먼저 파이썬 버젼을 확인해야 합니다. 2023년 11월 2일 기준으로 3.12버전 까지 나왔습니다. 하
hykethan.tistory.com
8장의 4절에 이어서 진행하겠습니다.
5. Naive Bayes Classifier의 이해 - 영문
유명한 Bayes법치에 기반한 분류기이다.
그 특징은 서로 확률적으로 독립이라는 가정이 있다.
특정 경찰서에 있는 경찰관의 이름이 나열되어 있을때 drew라는 이름의 경찰관은 남자일까/여자일까
P(male | drew) = 1/3 * 3/8 = 0.125
P(female | drew) = 2/5 * 5/8 = 0.25
=> 여성 쪽이 높은 값이 나오기 때문에 여자라고 분류된다.
일단 필요한 모듈을 import 합니다.
그리고 나서, 연습용 데이터를 만듭니다.
train 문장에서 사용된 전체 단어를 찾습니다.
코드해석은 아래 링크로 들어가서 보시면 됩니다. 내포함수들이 나오기 때문에 내용을 정리했습니다.
https://hykethan.tistory.com/23
Python 리스트, 집합, 딕셔너리 내포 정리
내포란? 내포는 간결하고 효율적인 방식으로 리스트, 집합, 딕셔너리를 생성할 수 있는 기능입니다. for문과 조건문 if문을 사용한 코드를 더 간결하게 쓸 수 있습니다. 하지만, 내포 코드가 너무
hykethan.tistory.com
{'hate', 'her', 'i', 'like', 'me', 'you'}
위와 같이 집합(set) 안에 있기 때문에 {}인 집합으로 도출되며 unique한 값만 도출되게 됩니다.
우리는 이것을 '말뭉치'라고 해두겠습니다.
그리고 말뭉치 기준으로 train문장에 속한 단어인지 아닌지를 기록합니다.
=> 첫번째 문장은 말뭉치에서 you, like, i가 들어있습니다.
이제 이를 이용해서 Naive Bayes 분류기를 동작시키도록 합니다.
=> train 문장에 붙은 pos/neg (긍정/부정) 태그를 이용해서 분류한 결과 hate라는 단어가 Fasle 일때 즉, hate가 없을때 긍정일 비율이 1.7:1.0이라는 의미입니다.
이제, 분류하는 분류기를 만들었습니다. 이걸 가지고 테스트 문장을 통과시켜 보겠습니다.
=> i와 like만 일치하네요.
이에 따라서 긍정일지 부정일지 확인해보니 긍정이라고 나왔습니다.
'pos'
6. Naive Bayes Classifier의 이해 - 한글
한글에서는 형태소 분석을 이용해야 합니다. 형태소 분석을 하지 않으면 분류기의 동작을 장담하기 어렵고, 신뢰도가 매우 낮기 때문에 꼭 형태소 분석을 거쳐 신뢰도 높은 분류기를 만들어 사용해야 합니다. 우리는 Okt 형태소 분석기를 사용하겠습니다.
학습할 데이터를 정의해줍니다.
형태소 분석이 필요하기 때문에 형태소에 태그를 붙여주는 tokenize 함수를 정의합니다.
정의한 함수를 train에 적용시키면 아래와 같이 도출됩니다.
이제 문장만 들어있는 항목을 tokens에 넣어주어 전체 말뭉치를 만들어 줍니다.
=>
말뭉치에 들어있는 단어가 있는지 아닌지를 구분하는 함수를 만들어서 train 문장에 적용합니다.
=>
이제 분류기에 학습을 시켜줍니다. 그리고 이 학습된 분류기에 적용할 테스트할 문장은 아래와 같습니다.
테스트 문장을 형태소 분석해줍니다.
=>
있는지 없는지 확인합니다.
=>
마지막으로 분류기를 거친 테스트 문장에 대한 결과를 보니 pos(긍정)이 도출되었습니다. 의미가 잘 드러난 것 같습니다.
7. 문장의 유사도 측정하기
유사한 문장을 찾아내는 방법에 대해 설명하겠습니다.
먼저 문장을 컴퓨터가 인식하기 쉽게 벡터화를 하고 벡터 간 거리를 구하는 방법으로 유사도를 측정해보겠습니다.
먼저 scikit-learn에서 텍스트의 특징(feature)을 추출하는 모듈에서 CountVectorizer라는 함수를 import 합니다.
연습 문장을 정의해줍니다.
문장에서 특징(feature)을 추출해 X에 저장합니다.
특징(feature)을 기반으로 벡터화된 결과를 확인해봅시다.
=> 문장이 4개이기 때문에, 4개 열로 나오고, 각 단어의 위치가 1의 값을 가집니다.
'놀러가고'는 위 추출 결과에서 8번째에, 메리랑은 11번째에 있으므로, 아래 결과에서 1열에 8번째, 11번쨰 숫자 1
문제는 메리랑과 메리는을 분리해서 같은 단어로 봐야함.
한글 문장에 대한 벡터화를 형태소 분석 사용해서 합리적으로 진행해보겠습니다.
Twitter를 사용해서 형태소 분석한 결과를 token으로 두겠습니다.
그리고 형태소 분석을 한 후 띄어쓰기로 구분하고 그것 자체를 하나의 문장(sentence)으로 만들어서 scikit learn의 vectorizer 함수에서 사용하기 편하게 편집합니다.
[' 메리 랑 놀러 가고 싶지만 바쁜데 어떻하죠 ?',
' 메리 는 공원 에서 산책 하고 노 는 것 을 싫어해요',
' 메리 는 공원 에서 노 는 것 도 싫어해요 . 이상해요 .',
' 먼 곳 으로 여행 을 떠나고 싶은데 너무 바빠서 그러질 못 하고 있어요']
그리고 feature를 찾도록 합니다.
feature를 확인해보겠습니다.
array(['가고', '공원', '그러질', '너무', '놀러', '떠나고', '메리', '바빠서', '바쁜데', '산책',
'싫어해요', '싶은데', '싶지만', '어떻하죠', '에서', '여행', '으로', '이상해요', '있어요',
'하고'], dtype=object)
이제 새로운 문장을 동일한 과정으로 벡터화해서 각 벡터들 사이의 거리를 구해봅시다.
위 과정을 거쳐 벡터화를 시키고 새로운 문장(new_post_vec)과 비교해야 할 문장(contents)들 각각에 대해 거리를 구해봅시다. 먼저 거리를 구하기 위해 sp 모듈을 호출하고 벡터의 거리를 계산해서 정규화시켜주는 함수를 정의합니다.
이제 각 문장과 새로운 문장의 거리를 구해봅시다.
== Post 0 with dist=3.00 : 메리랑 놀러가고 싶지만 바쁜데 어떻하죠?
== Post 1 with dist=1.00 : 메리는 공원에서 산책하고 노는 것을 싫어해요
== Post 2 with dist=2.00 : 메리는 공원에서 노는 것도 싫어해요. 이상해요.
== Post 3 with dist=3.46 : 먼 곳으로 여행을 떠나고 싶은데 너무 바빠서 그러질 못하고 있어요
가장 유사한 문장을 추출해보겠습니다.
Best post is 1, dist = 1.00
--> ['메리랑 공원에서 산책하고 놀고 싶어요']
----> 메리는 공원에서 산책하고 노는 것을 싫어해요
거리가 1일 때가 가장 가까운 거리였고, 그 문장은 '메리랑 공원에서 산책하고 놀고 싶어요' 입니다. 문장의 의미는 반대지만 단어들의 조합을 보면 비슷해보입니다.
벡터화된 결과를 보겠습니다.
0 번째 문장의 벡터결과 -> [[1 0 0 0 1 0 1 0 1 0 0 0 1 1 0 0 0 0 0 0]]
1 번째 문장의 벡터결과 -> [[0 1 0 0 0 0 1 0 0 1 1 0 0 0 1 0 0 0 0 1]]
2 번째 문장의 벡터결과 -> [[0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 0]]
3 번째 문장의 벡터결과 -> [[0 0 1 1 0 1 0 1 0 0 0 1 0 0 0 1 1 0 1 1]]
-----------------------------------------------------------------
새로운 문장의 벡터결과 -> [[0 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1]]
7.1. 문장의 유사도 측정하기(TF - IDF)
TF-IDF 개념 적용
tf(term frequency) 와 idf(inverse document frequency) 는 일종의 단어별로 부과하는 가중치.
-> tf는 어떤 단어가 문서 내에서 자주 등장할수록 중요도가 높을 것으로 보는것.
-> idf는 비교하는 모든 문서에 만약 같은 단어가 있다면 이 단어는 핵심 어휘일지는 모르지만 문서 간의 비교에서는 중요한 단어가 아니라는 뜻으로 보는 것
-> TF_IDF는 TF와 IDF를 곱한 값을 의미함. 특정 문서에서만 자주 등장하는 단어는 중요도가 높다고 판단.
-> TF_IDF 값이 낮으면 중요도가 낮은것, 크면 중요도 큰 것.
먼저 직접 TF-IDF 함수를 생성해보겠습니다.
테스트를 해보겠습니다.
이후 tf*idf 값을 취하면 되지만, scikit-learn의 TfidfVectorizer를 import 하겠습니다. 벡터화하는 모듈을 CounterVectorizer 대신 TfidVectorizer를 사용하는 것입니다.
이후 동일하게 contents 문장들을 다듬는 작업을 진행합니다.
(4, 20)
추출된 특징(feature)를 확인해보겠습니다.
array(['가고', '공원', '그러질', '너무', '놀러', '떠나고', '메리', '바빠서', '바쁜데', '산책',
'싫어해요', '싶은데', '싶지만', '어떻하죠', '에서', '여행', '으로', '이상해요', '있어요',
'하고'], dtype=object)
이제, 테스트 문장을 벡터화 하는 작업을 하겠습니다.
이제, 결과값을 한번 확인해보도록 하겠습니다.
== Post 0 with dist=0.90 : 메리랑 놀러가고 싶지만 바쁜데 어떻하죠?
== Post 1 with dist=1.18 : 메리는 공원에서 산책하고 노는 것을 싫어해요
== Post 2 with dist=1.16 : 메리는 공원에서 노는 것도 싫어해요. 이상해요.
== Post 3 with dist=1.41 : 먼 곳으로 여행을 떠나고 싶은데 너무 바빠서 그러질 못하고 있어요
Best post is 0, dist = 0.90
--> ['근처 공원에 메리랑 놀러가고 싶네요.']
----> 메리랑 놀러가고 싶지만 바쁜데 어떻하죠?
이렇게 재미있는 결과를 얻을 수 있습니다.
본 내용은 파이썬으로 데이터 주무르기-민형기 책에서 공부한 내용을 바탕으로 작성한 글입니다.
'Python' 카테고리의 다른 글
파이썬 비즈니스 통계분석 - 상관관계 분석 (4) | 2023.11.28 |
---|---|
파이썬 비즈니스 통계분석 - T-검정(T-Test) (0) | 2023.11.13 |
Python 특정 날짜의 요일 계산방법 (0) | 2023.11.03 |
파이썬 데이터 주무르기 8장 자연어 처리 시작하기(~4/8절) (0) | 2023.11.03 |
Python 리스트, 집합, 딕셔너리 내포 정리 (2) | 2023.11.03 |