23.2 N-gram 만들기
N-gram은 문자열에서 N개의 연속된 요소를 추출하는 방법입니다. 만약 'Hello'라는 문자열을 문자(글자) 단위 2-gram으로 추출하면 다음과 같이 됩니다.
He el ll lo
즉, 문자열의 처음부터 문자열 끝까지 한 글자씩 이동하면서 2글자를 추출합니다. 3-gram은 3글자, 4-gram은 4글자를 추출하겠죠?
이제 파이썬에서 문자 단위 2-gram을 출력해보겠습니다.
2_gram_character.py
text = 'Hello' for i in range(len(text) - 1): # 2-gram이므로 문자열의 끝에서 한 글자 앞까지만 반복함 print(text[i], text[i + 1], sep='') # 현재 문자와 그다음 문자 출력
실행 결과
He el ll lo
생각보다 간단하죠? 2-gram이므로 문자열의 끝에서 한 글자 앞까지만 반복하면서 현재 문자와 그다음 문자 두 글자씩 출력합니다.
만약 3-gram이라면 반복 횟수는 range(len(text) - 2))와 같이 되고, 문자열 끝에서 두 글자 앞까지 반복하면 됩니다. 문자열을 출력할 때는 print(text[i], text[i + 1], text[i + 2], sep='')가 되겠죠? 여기서 문자열의 끝까지 반복하면 text[i + 1], text[i + 2]는 문자열의 범위를 벗어난 접근을 하게 되므로 주의해야 합니다.
글자 단위 N-gram이 있다면 단어 단위 N-gram도 있겠죠? 다음은 문자열을 공백으로 구분하여 단어 단위 2-gram을 출력합니다. 예를 들어 'this is python script'는 'this is', 'is python', 'python script'가 됩니다.
2_gram_word.py
text = 'this is python script' words = text.split() # 공백을 기준으로 문자열을 분리하여 리스트로 만듦 for i in range(len(words) - 1): # 2-gram이므로 리스트의 마지막에서 요소 한 개 앞까지만 반복함 print(words[i], words[i + 1]) # 현재 문자열과 그다음 문자열 출력
실행 결과
this is is python python script
단어 단위 2-gram도 간단합니다. split을 사용하여 공백을 기준으로 문자열을 분리하여 리스트로 만듭니다. 그리고 2-gram이므로 words 리스트의 마지막에서 요소 한 개 앞까지만 반복하면서 현재 문자열과 그다음 문자열을 출력하면 됩니다.
4-gram을 쓰면 picked, picks, picking에서 pick만 추출하여 단어의 빈도를 세는데 이용됩니다. 이런 특성 때문에 검색엔진, 빅데이터, 법언어학 분야에서 주로 활용됩니다.
해리포터의 작가 조앤 롤링은 가명으로 <더 쿠쿠스 콜링>이라는 소설을 출간한 적이 있었습니다. 재미있는 점은 <더 쿠쿠스 콜링>의 작가가 조앤 롤링이라는 것을 밝혀내는데 N-gram을 비롯하여 다양한 기법이 동원되었습니다. 즉, 사람마다 사용하는 문장에 패턴이 있지요. 그래서 같은 의미라 하더라도 사람마다 단어 선택이 다르다는 것을 통계적으로 분석해낸 사례입니다.
조앤 롤링을 고백하게 만든 기술, 법언어학: http://yoonjiman.net/2013/07/23/how-forensic-linguistics-outed-j-k-rowling/
지금까지 회문 판별과 N-gram을 만들어보았습니다. 여기서는 문자열의 인덱스를 다루는 방법만 신경쓰면 됩니다.