day 5 회문 판별하기
회문 판별과 N-gram
회문
회문(palindrome)은 순서를 거꾸로 읽어도 제대로 읽은 것과 같은 단어와 문장을 말합니다. 예를 들면 “level”, “SOS”, “rotator”, “nurses run”과 같은 단어와 문장이 있지요.
회문은 유전자 염기서열 분석에서 많이 쓰고, N-gram은 빅 데이터 분석, 검색 엔진에서 많이 쓰입니다. 특히 구글은 책들을 스캔해서 N-gram viewer를 만들었는데 사람들의 언어 패턴을 시대별로 분석하기도 했습니다.
반복문으로 문자 검사하기
반복문으로 문자열의 각 문자를 검사 하기
word = input('단어를 입력하세요: ')
is_palindrome = True # 회문 판별값을 저장할 변수, 초깃값은 True
for i in range(len(word) // 2): # 0부터 문자열 길이의 절반만큼 반복
if word[i] != word[-1 - i]: # 왼쪽 문자와 오른쪽 문자를 비교하여 문자가 다르면
is_palindrome = False # 회문이 아님
break
print(is_palindrome) # 회문 판별값 출력
실행 결과
단어를 입력하세요: level (입력)
True
단어를 입력하세요: hello (입력)
False
시퀀스 뒤집기로 문자 검사하기
word = input('단어를 입력하세요: ')
print(word == word[::-1]) # 원래 문자열과 반대로 뒤집은 문자열을 비교
실행 결과
단어를 입력하세요: level (입력)
True
단어를 입력하세요: hello (입력)
False
리스트와 reversed 사용하기
>>> word = 'level'
>>> list(word) == list(reversed(word))
True
>>> list(word)
['l', 'e', 'v', 'e', 'l']
>>> list(reversed(word))
['l', 'e', 'v', 'e', 'l']
문자열의 join 메서드와 reversed 사용하기
>>> word = 'level'
>>> word == ''.join(reversed(word))
True
>>> word
'level'
>>> ''.join(reversed(word))
'level'
N-gram
N-gram은 문자열에서 N개의 연속된 요소를 추출하는 방법입니다. 만약 ‘Hello’라는 문자열을 문자(글자) 단위 2-gram으로 추출하면 다음과 같이 됩니다.
He
el
ll
lo
반복문으로 N-gram 출력
text = 'Hello'
for i in range(len(text) - 1): # 2-gram이므로 문자열의 끝에서 한 글자 앞까지만 반복함
print(text[i], text[i + 1], sep='') # 현재 문자와 그다음 문자 출력
..
..
He
el
ll
lo
단어 n-gram
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
zip을 2-gram 만들기
text = 'hello'
two_gram = zip(text, text[1:])
for i in two_gram:
print(i[0], i[1], sep='')
..
..
He
el
ll
lo
>>> text = 'hello'
>>> list(zip(text, text[1:]))
[('h', 'e'), ('e', 'l'), ('l', 'l'), ('l', 'o')]
단어 2-gram
>>> text = 'this is python script'
>>> words = text.split()
>>> list(zip(words, words[1:]))
[('this', 'is'), ('is', 'python'), ('python', 'script')]
zip과 리스트 표현식으로 N-gram
>>> list(zip(['hello', 'ello', 'llo']))
[('hello',), ('ello',), ('llo',)]
결과를 보면 원하는 3-gram이 아닙니다. 왜 그럴까요? zip은 반복 가능한 객체 여러 개를 콤마로 구분해서 넣어줘야 합니다. 하지만 [‘hello’, ‘ello’, ‘llo’]은 요소가 3개 들어있는 리스트 1개이기 때문입니다.
zip에 리스트의 각 요소를 콤마로 구분해서 넣어주려면 리스트 앞에 *를 붙여야 합니다.
>>> list(zip(*[text[i:] for i in range(3)]))
[('h', 'e', 'l'), ('e', 'l', 'l'), ('l', 'l', 'o')]
리스트에 *를 붙이는 방법은 리스트 언패킹(list unpacking)이라고 합니다.
읽을거리 | N-gram의 활용
4-gram을 쓰면 picked, picks, picking에서 pick만 추출하여 단어의 빈도를 세는데 이용됩니다. 이런 특성 때문에 검색엔진, 빅데이터, 법언어학 분야에서 주로 활용됩니다.
Leave a comment