khann's IT와 경제 블로그

반응형

1편에 이어 이번에는 Doc2Vec을 활용하여 서울시 장애인 콜택시 이용자들의 소리에는 어떤 키워드가 연관되어 있는지 확인해보고 이용자들의 불만은 무엇이고 서울시 장애인 콜택시의 문제점 및 개선사항은 어떤 것인지 확인해 보자.

 

활용 라이브러리 : Gensim, Scikit-learn, Konlpy-Okt 

 

1편

https://khann.tistory.com/10

 

실전 데이터 분석#1 - 서울시 장애인 콜택시 이용 만족도 분석(1/2)

개요 우리나라에는 이동이 불편한 장애인들을 위해 이동편의를 제공해 사회참여의 확대를 늘리고자, 2002년부터 전국적으로 '장애인 콜택시'라는 서비스를 운영하고 있다. 그중, 서울시의 장애인 콜택시는 서울시..

khann.tistory.com

 

토크나이징

 

저번에는 워드 클라우드를 뽑기 위해서 품사 중 명사만 추출하였는데, 이번에는 형태소 분석기인 Konlpy의 Okt를 이용하여 형태소 별로 품사태깅(POS)하여 변수에 저장했다.

 

※ 게시글의 제목, 문의 내용, 답변 내용을 따로 분리하여 따로 진행했다.

 

Doc2Vec

Doc2Vec은 Word2Vec과 이론은 똑같고 Word대신에 Doc을 Vector화 한다는 차이가 있다. 

(아래는 Word2Vec을 포함한 자연어를 Vector화 하는 여러 방법을 정리해 놓은 포스트이다.)

https://khann.tistory.com/28

 

자연어처리(NLP) - 컴퓨터가 자연어를 이해하는 방법(벡터화)

자연어처리(NLP) - 컴퓨터가 자연어를 이해하는방법(벡터화) 사람은 문장에서 단어가 어떤 의미로 사용되었는지 문맥을 통해 바로 구분할 수 있지만 기계는 그렇게 할 수 없다. 그렇기 때문에 단어를 수치로 표현..

khann.tistory.com

 

다시 분석과정으로 돌아와서, 이번 분석에는 gensim의 Doc2Vec라이브러리를 이용하여 진행했다.

 

먼저 앞서 품사태깅된 자연어 리스트의 리스트들을 indexing(?) 하는 과정이 필요하다. 여기서는 doc에 tag 한다는 말로 Docs를 TaggedDocs로 바꿔주는 작업이다. 하는 방법은 'from gensim.models.doc2vec import TaggedDocument'를 이용해도 되고 직접 'from collections import namedtuple'로 직접 tuple을 만들어 태그 해줘도 된다.

 

 

아래 사진은 TaggedDocs가 완료된 모습이다. TaggedDocument 안에 words, tags 2개의 변수가 들어가는데, words에는 품사태깅된 자연어 리스트(하나의 doc)이, tags에는 이 doc에 대한 tag값이 저장된다.

 

 

이제 tag가 끝났으니 doc2vec을 돌려 사전을 구축해보겠다.

1
2
3
4
5
6
7
8
9
10
11
12
from gensim.models import doc2vec
 
# 사전 구축
doc_vectorizer = doc2vec.Doc2Vec(vector_size=400, alpha=0.0025, min_alpha=0.0025, seed=1234, epochs=50)
doc_vectorizer.build_vocab(tagged_ask_train_docs)
 
# Train document vectors!
doc_vectorizer.train(tagged_ask_train_docs, epochs=doc_vectorizer.epochs, total_examples=doc_vectorizer.corpus_count)
 
# To save
doc_vectorizer.save('doc2vec.model')
cs

 

 

 

서울시 장애인 콜택시의 문제점 찾기

이제 모든 자연어들이 각자의 벡터 값을 가지고 서로 벡터의 어느 한 지점씩 위치해 있을 것이다. 여기서 저번 시간에 워드 클라우드를 하면서 가장 빈도수 높은 키워드를 활용해서 벡터화가 잘 되었는지 잘 학습되었는지 확인해 보자.

키워드는 '시간', 차량', '전화', '병원'등이다.

1
2
3
4
5
6
7
8
print('---시간---')
pprint(doc_vectorizer.wv.most_similar('시간/Noun'))
print('---차량---')
pprint(doc_vectorizer.wv.most_similar('차량/Noun'))
print('---전화---')
pprint(doc_vectorizer.wv.most_similar('전화/Noun'))
print('---병원---')
pprint(doc_vectorizer.wv.most_similar('병원/Noun'))
cs

 

 

output:

 

 

결과가 재밌게도 예상대로 워드 클라우드를 만들면서 예측했던 문제들이 비슷하게 일치하고 있다. 시간이라는 키워드에는 '지연', '기다리다', '후'가 연관 있게 나왔고, 심지어 차량이라는 키워드에도 '10분', '30분'등 시간 키워드가 연관 있게 나왔다. 병원에서는 '치료'와, '재활'을 받으러 택시를 타는것 같다.

그렇다면 왜 차량에도 시간 키워드가 연관있게 나왔을까? 차량을 운전하는 '기사'키워드로도 연관성을 확인해 봤다.

 

output:

신기하게도 기사에는 '친절하다', '감사하다', '따뜻하다' 등 긍정적인 키워드가 많이 연관되어있다. 확실히 기사가 불친절하다거나 서비스의 문제로 지연이 되는 게 지금의 서울시 장애인 콜택시의 문제는 아닌 것 같다.

그렇다면 이용자들은 어떤 문제로 전화하고 1시간, 2시간 지연되고 기다리는 걸까? 혹시 배차랑 연관되어있는 것은 아닐까?

 

'배차'의 연관성을 확인해 보니.

output:

여기에서 문제를 찾은 것 같다. '오기', '하', '무슨', '지치다', '4시간'등의 키워드를 보았을 때, 지금의 서울시 장애인 콜택시는 배차 시스템에 문제가 있는 것 같다.

 

 

 

한번 더 확인해보자, 배차 시스템의 문제로 시간이 지연이 되어 이용자의 불만이 생기는 게 맞다면, '시간'이라는 키워드에 '배차'의 키워드를 빼보면 어떻게 나올까?

1
2
print('\n---(시간-배차)-----')
pprint(doc_vectorizer.wv.most_similar(positive=['시간/Noun'], negative=['배차/Noun']))
cs

output:

시간, 배차, 시간-배차

정말 신기하다, 시간의 키워드에 '지연', 기다리다', '후'의 키워드가 연관이 되게 결과가 나왔고, 

배차 키워드에는 '하', '무슨', '지치다', '4시간' 등 키워드가 나왔는데 

시간-배차로 입력을 넣어서 결과를 보니 놀랍게도 불만의 키워드가 전부 사라졌다.

 

이로써 서울시 장애인 콜택시의 문제점은 '배차'이다. 

 

 

 

마치며...

이번 분석은 데이터가 너무 적어서 분석에 의미가 없거나 잘 안 나올 거라고 생각했다. 그렇지만 나름대로 만족할만한 결과는 나와서 그나마 다행이다. 그러다 보니 한 구절이 떠올랐다.

최근에 읽었던 모두 거짓말을 한다(Everybody LIes)에서 '구글은 모든 데이터 중에서 작은 샘플링을 바탕으로 중요한 결정을 내린다. 데이터가 엄청나게 많아야 중요한 식견을 발견할 수 있는 것은 아니다. 필요한 것은 적절한 데이터다.'라고 설명한다. 책에서 처럼 이 서울시 장애인 콜택시의 시민의 소리는 진짜 불편을 겪거나 고마워서 생긴 '솔직한 데이터'임을 다시 생각하게 된다.  

반응형

이 글을 공유합시다

facebook twitter googleplus kakaostory naver