텍스트 분석을 할 때 텍스트가 수집된 채널의 종류에 따라 이모티콘이 많거나 특수문자가 많은 경우가 있습니다. 또한 파일로 저장하는 과정에서 문단 바꿈, 탭 등이 자바 언어나 다른 컴퓨터 언어로 표현되기도 합니다. 원하고자 하는 언어로 제대로 텍스트 분석을 하기 위해서는 이런 불순물들을 제거하는 작업이 반드시 필요합니다.
파이썬의 경우 re 모듈을 이용해서 정규표현식으로 문장 부호나 이모티콘 등을 제거할 수 있습니다.
필요한 패키지와 모듈을 임포트합니다.
import pandas as pd
import numpy as np
import emoji # 이모지 제거용
import re
from soynlp.normalizer import * #반복되는 자음 제거
import time
from tqdm.notebook import tqdm
from kiwipiepy import Kiwi #문장 분리
분석에 사용할 파일을 불러옵니다.
df = pd.read_csv("파일저장경로/파일명.txt", encoding='UTF-8')
# print(df.shape, type(df)) # 파일 구조 및 컬럼명 확인용
df['org_idx']= df.index #인덱스 column 생성: 문장 분리할 때 사용함
# print(df.columns) # org_idx 제대로 추가됐나 단순 확인용.
post_list = list(df['내용']) #자연어 전처리를 위해 본문을 리스트 형태로
정규표현식으로 불용어와 필요에 따라 숫자나 영어 등을 제거해줍니다.
저는 한글 텍스트 분석을 할 예정이므로 한글과 숫자만 남기고 모두 제거해줍니다.
# post_list 양이 많을 경우 불용어 제거 중에 오류 나면 다시 리스트로 만드는 데 오래 걸려서 카피하는 것임. 안 하고 post_list로 진행해도 됨.
post_list2 = post_list.copy()
for i in range(len(post_list2)):
post_list2[i] = re.sub('\n', ' ', string=str(post_list2[i])) # 줄바꿈을 띄어쓰기 하나로
post_list2[i] = re.compile('[^|ㄱ-ㅎ|ㅏ-ㅣ|0-9|가-힣]+').sub(' ',post_list2[i])
post_list2[i] = repeat_normalize(post_list2[i], num_repeats=1)
# ↑ ㅋㅋㅋ, ㅎㅎㅎ 등의 의미 없는 자음 삭제. num_repeats가 1이면 반복 글자 중 1개만 남기고 2면 2개만 남김.
post_list2[i] = re.sub(r"^\s+|\s+$", "", post_list2[i]) # 문서 앞뒤 공백 제거
post_list2[i] = post_list2[i].split() # 문서 내 공백(1개 이상) 기준으로 자르기
post_list2[i] = ' '.join(post_list[i]) # 공백 기준으로 나뉜 문서를 다시 1개의 공백을 두고 붙임.
# ↑ 문서 내 다중 공백을 지우기 위함.
df['cleaning'] = pd.DataFrame(post_list2) #불용어 제거된 본문을 데이터 프레임으로
이제 깨끗해진 본문 데이터를 문장으로 나누어 줍니다.
이 과정은 굳이 하지 않아도 됩니다.
하지만 블로그 텍스트의 경우 문장을 나누는 기준이 되는 온점을 잘 쓰지 않는 경우도 많고, 위에서 줄바꿈 부호를 제거하면서 문장이 합쳐진 경우도 있기 때문에 kiwipiepy를 이용해서 문장을 나눠줍니다.
https://github.com/bab2min/kiwipiepy
GitHub - bab2min/kiwipiepy: Python API for Kiwi
Python API for Kiwi. Contribute to bab2min/kiwipiepy development by creating an account on GitHub.
github.com
문장 분리 후 본문 인덱스 칼럼과 함께 새로운 데이터프레임으로 저장합니다.
# 문장 분리를 위해 키위를 선언합니다.
kiwi = Kiwi()
kw_sent_list = [kiwi.split_into_sents(df['cleaning'][i]) for i in tqdm(range(len(df['cleaning'])))]
df['kw_sent_list'] = kw_sent_list
# 용량을 줄이기 위해 새로운 데이터프레임에 담습니다.
df2 = pd.DataFrame()
for i in tqdm(range(len(df['kw_sent_list']))):
for j in range(len(df['kw_sent_list'][i])):
kw_sent_str= {'kw_sent_str': df['kw_sent_list'][i][j][0], 'org_idx': [i]}
kw_sent_df= pd.DataFrame(kw_sent_str)
df2= pd.concat([df2,kw_sent_df])
# 기존 본문의 인덱스를 제거하기 위해 인덱스를 리셋해줍니다.
df2.reset_index(drop=True, inplace=True)
df2
위에서 데이터 프레임이 잘 만들어졌는지 확인하고 파일로 저장하면 끝! 입니다.
# 문장으로 구성된 데이터 프레임 저장
df2.to_excel("파일저장경로.xlsx")
df2.to_csv("파일저장경로.csv", index=False, encoding='UTF-8')
df2.to_csv("파일저장경로.txt", index=False, ,sep='\t', encoding='UTF-8')
다른 기술 블로그들이 그렇듯,
코드를 블로그에 공유하는 것은 기록과 '공유'를 위해서입니다.
만약 제 글의 도움을 받아 본인의 글을 작성하신다면 출처를 남겨주시길 바랍니다.
문의는 댓글로 남겨주시면 확인 후 답변드리겠습니다.
'데이터 분석 > Python' 카테고리의 다른 글
[텍스트 마이닝-분석] 한글 형태소 분석: KoNLPy (0) | 2023.09.17 |
---|---|
[텍스트 마이닝-전처리] 한글 맞춤법 검사: Py-hanspell (0) | 2023.09.17 |
[텍스트 마이닝-수집] 네이버 블로그 크롤러(2) - 본문 수집 (0) | 2023.09.17 |
[텍스트 마이닝-수집] 네이버 블로그 크롤러(1) - 수집할 목록 만들기 (0) | 2023.09.15 |
[텍스트 마이닝-수집] 구글 학술 검색 인용 스크래핑 (0) | 2023.09.12 |
댓글