Python으로 단톡방 채팅 내용 키워드 분석하기

2020. 6. 28. 17:09취미로 하는 개발

일정이 붕 떠서 심심하던 차에, 문득 친구들이랑 떠드는 단톡방이나 한 번 까보고 싶어졌다.

 

하려는 일의 순서는 다음과 같다.

 

  1. 단톡방 대화내용 확보
  2. 대화내용을 화자별로 구분하여 저장
  3. 각 문장에서 단어를 추출하여 사용 빈도가 높은 순서대로 정렬

 

PC카톡 기준

 

 

일단 대화 내보내기를 통해 단톡방의 내용을 txt파일로 받아놓는다.

 

데이터가 어떻게 구성되어 있는지를 확인해야 원하는 부분을 추출할 수 있기 때문에 txt파일을 열어서 확인해본다.

 

 

 

 

 

데이터 맨 윗줄은 단톡방 이름, 인원, 저장된 날짜가 노출되어 있었다.

 

마지막 채팅 이후 새 채팅이 시작된 시점에 날짜가 지난 경우 {시간}만 노출된 데이터도 있었고,

 

쭉 흝어보니 대화 데이터는 {시간},{이름} : {내용} 으로 표현되어 있었다.

 

내가 필요로 하는 데이터는 오직 {이름},{내용} 뿐이므로 해당 내용을 추출하는 과정이 필요했다.

 

먼저 친구들 각각의 채팅 내용을 따로 저장하는 과정을 거쳤다.

 

DataExtractor.py

chat = open("C:/Users/rejec/Documents/NLP/KakaoTalkChats.txt", encoding="utf-8")
#추출을 위한 채팅 원본 파일로, 읽기 모드로 가져온다. 'r'값은 기본값이라 생략했다.

mhchat = open("C:/Users/rejec/Documents/NLP/MhChats.txt", 'w', encoding="utf-8")
sikchat = open("C:/Users/rejec/Documents/NLP/SikChats.txt", 'w', encoding="utf-8")
inschat = open("C:/Users/rejec/Documents/NLP/InsChats.txt", 'w', encoding="utf-8")
zingchat = open("C:/Users/rejec/Documents/NLP/ZingChats.txt", 'w', encoding="utf-8")
mechat = open("C:/Users/rejec/Documents/NLP/MeChats.txt", 'w', encoding="utf-8")
#각 사용자별로 새 텍스트 파일을 생성해준다. 'w' 쓰기모드


mh = "명룡 : "
sik = "정시기 : "
ins = "박상용 : "
zing = "징도 : "
me = "회원님 : "
# 친구들 이름 +" : " 
# 해당 문자열이 들어있으면 추출해서 따로 저장할 예정

nonchating = ['사진','샵검색','이모티콘','동영상']
# 일반적인 채팅 내용이 아닌 것들은 예외처리를 해주기 위해 리스트에 넣는다

while True:
    line = chat.readline()
    #채팅 내용에서 한 줄씩 가져와준다
    #print(line)
    if not line:
        break
	#더 가져올 줄이 없으면 break
    
    isOk = True
    #예외처리에 필요한 변수 하나 선언
    for item in nonchating:
    #아이템 안에 들어있는 요소들마다
        if item in line:
        #줄에 그 내용이 있으면
            isOk = False
            #다음 단계로 넘기지 마
            break
	
    if isOk:
    #문제가 없으면 Keep Going~
        if mh in line:
        #mh라는 친구가 한 말이면
            line = line.split(" : ")[1]
            #split으로 대화 내용만 추출한다.
            mhchat.write(line)
            #mhchat파일에 추출한 대화 내용을 써준다.
        elif sik in line:
            line = line.split(" : ")[1]
            sikchat.write(line)
        elif ins in line:
            line = line.split(" : ")[1]
            inschat.write(line)
        elif zing in line:
            line = line.split(" : ")[1]
            zingchat.write(line)
        elif me in line:
            line = line.split(" : ")[1]
            mechat.write(line)
	
    #python에는 스위치문이 없어서 elif나 아니면 딕셔너리를 사용한다고 한다.

chat.close()
mhchat.close()
sikchat.close()
inschat.close()
zingchat.close()
mechat.close()
#file 객체 다 닫아줌

 

이렇게 하면 원하는 대로 대화내용만 쏙쏙 빼서 txt파일로 생성이 되는 부분을 확인 할 수 있다.

 

 

 

실제로 파일을 열어보면 대화 내용만 착하게 저장되어 있다.

 

이제 단어의 빈도수만 파악하면 되겠다.

 

띄어쓰기가 되지 않은 문장도 자연어 처리를 통해 단어로 분석할 수 있지만

 

그렇게까지 하긴 싫어서 그냥 공백으로 구분하였다.

 

import operator

mhchat = open("C:/Users/rejec/Documents/NLP/MhChats.txt", 'r', encoding="utf-8")
mhchatfreq = open("C:/Users/rejec/Documents/NLP/MhChatsFreq.txt", 'w', encoding="utf-8")
sikchat = open("C:/Users/rejec/Documents/NLP/SikChats.txt", 'r', encoding="utf-8")
sikchatfreq = open("C:/Users/rejec/Documents/NLP/SikChatsFreq.txt", 'w', encoding="utf-8")
inschat = open("C:/Users/rejec/Documents/NLP/InsChats.txt", 'r', encoding="utf-8")
inschatfreq = open("C:/Users/rejec/Documents/NLP/InsChatsFreq.txt", 'w', encoding="utf-8")
zingchat = open("C:/Users/rejec/Documents/NLP/ZingChats.txt", 'r', encoding="utf-8")
zingchatfreq = open("C:/Users/rejec/Documents/NLP/ZingChatsFreq.txt", 'w', encoding="utf-8")
mechat = open("C:/Users/rejec/Documents/NLP/MeChats.txt", 'r', encoding="utf-8")
mechatfreq = open("C:/Users/rejec/Documents/NLP/MeChatsFreq.txt", 'w', encoding="utf-8")
#기존에 저장한 각 화자별 대화 내용을 가져오고,
#단어와 빈도수를 저장할 freq파일을 생성한다.

#function을 하나 만들어서 간단히 처리해보자
def get_freq(chat_file, out_file):
	#chat_file은 대화 내용이 담긴 텍스트 파일, out_file은 빈도를 저장할 file이다.
    # 생각해보니 그냥 chat_flie만 받아서 해도 되었을텐데... 또 바보같이 했다.
    
    freq = {}
    # 단어와 빈도를 저장할 딕셔너리 생성

    while True:
        line = chat_file.readline()
        if not line:
            break
		#읽어오는 부분은 동일하다
        lines = line.split(" ")
		#공백으로 단어를 구분한다
        for i in lines:
        	#구분한 단어들을, 
            i = i.replace('\n', '')
            #개행문자를 제거한 후
            count = freq.get(i, 0)
            #기존에 저장된 빈도 딕셔너리에서 가져온다
            #없는 값이라면(처음 보는 값이라면) 0과 함께 저장
            freq[i] = count + 1
            #이렇게 하면 i라는 단어의 value는 기존에 존재했다면 +1, 처음이라면 1이 저장된다

    frequency_list = sorted(freq.items(), key=operator.itemgetter(1), reverse=True)
    #저장된 딕셔너리의 값을 빈도수가 높은 순서대로 재정렬 해준다. 낮은 순서대로 하려면 reverse=False
    '''
    # sorted(dict.items(), key=operator.itemgetter(0))
    # key=operator.itemgetter(0)는 정렬하고자 하는 키 값을 0번째 인덱스로 한다.
    # 딕셔너리 자료형에서 0번째 인덱스는 Key.
    # 1번째 인자는 Value니까 1로 해야한다.
    
    '''
    for words in frequency_list:
        out_file.write(words[0] + " : " + str(words[1]) + "\n")
        #정렬된 딕셔너리 자료형을 보기 좋게 {단어} : {빈도} \n 로 저장한다.

    chat_file.close()
    out_file.close()


get_freq(mhchat, mhchatfreq)
get_freq(sikchat, sikchatfreq)
get_freq(inschat, inschatfreq)
get_freq(zingchat, zingchatfreq)
get_freq(mechat, mechatfreq)
#5명 반복

 

실행 후 결과를 까보도록 하자.

 

 

 

빈도가 높은 단어 순서대로 {단어} : {빈도수} 확인이 가능하다.

 

저 공백 부분은 예외처리를 해줘야겠다.

 

아무튼 끝~