2. N-gram 만들기
- N-gram은 문자열에서 N개의 연속된 요소를 추출하는 방법이다.
- 만약 'Hello'라는 문자열을 문자(글자) 단위 2-gram으로 추출하면 다음과 같이 된다.
He el ll lo
- 즉, 문자열의 처음부터 끝까지 한 글자씩 이동하면서 2글자를 추출한다(3-gram은 3글자, 4-gram은 4글자)
2-1. 반복문으로 N-gram 출력하기
- 반복문으로 문자 단위 2-gram을 추출해보면, 문자열의 끝에서 한 글자 앞까지만 반복하며 현재 문자와 그다음 문자 두 글자씩을 출력한다.
text = 'Hello' for i in range(len(text) - 1): # 2-gram이므로 문자열의 끝에서 한 글자 앞까지만 반복함 print(text[i], text[i + 1], sep='') # 현재 문자와 그다음 문자 출력 # 실행 결과 He el ll lo
- 만약 3-gram이면 반복 횟수는 range(len(text)-2) 와 같이 되고, 문자열 끝에서 두 글자 앞까지 반복하면 된다.
- 문자열을 출력할 때는 print(text[i], text[i+1], text[i+2], sep='') 가 되는데, 여기서 문자열을 끝까지 반복하면 text[i+1], text[i+2] 는 문자열의 범위를 벗어난 접근을 하게 되므로 주의해야 한다.
- 다음은 문자열을 공백으로 구분하여 단어 단위 2-gram을 출력한다. 예를 들어 'this is python script' 는 'this is', 'is python', 'python script' 가 된다.
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도 spilt을 사용하여 공백을 기준으로 문자열을 분리하고 리스트로 만든 다음, 2-gram이므로 words 리스트의 마지막에서 요소 한 개 앞까지만 반복하면서 현재 문자열과 그다음 문자열을 출력하면 된다.
2-2. zip으로 2-gram 만들기
- 지금까지 zip 함수는 리스트 두 개를 딕셔너리로 만들 때 사용했는데, zip 함수는 반복 가능한 객체의 각 요소를 튜플로 묶어준다.
text = 'hello' two_gram = zip(text, text[1:]) for i in two_gram: print(i[0], i[1], sep='') # 실행 결과 He el ll lo
- zip(text, text[1:]) 은 문자열 text와 text[1:]의 각 요소를 묶어서 튜플로 만들고, text[1:]은 인덱스 1(두번째 문자)부터 마지막 문자를 가져오므로 text와 text[1:]을 zip으로 묶으면 문자 하나가 밀린 상태로 각 문자를 묶게 된다.
>>> text = 'hello' >>> list(zip(text, text[1:])) [('h', 'e'), ('e', 'l'), ('l', 'l'), ('l', 'o')]
- 이렇게 만들어진 2-gram 리스트를 출력할 때는 for i in two_gram: 과 같이 for로 반복하면서 print(i[0], i[1], sep='')로 튜플의 요소를 출력해주면 된다.
- 단어 단위 2-gram도 문자열을 공백으로 분리하여 리스트로 만드는 것을 제외하고는 같은 방법으로 만들면 된다.
>>> text = 'this is python script' >>> words = text.split() >>> list(zip(words, words[1:])) [('this', 'is'), ('is', 'python'), ('python', 'script')]
- 만약 3-gram을 만들고 싶다면 zip(words, words[1:], words[2:]) 와 같이 word, word[1:], word[2:] 총 3개의 리스트를 넣으면 된다.
2-3. zip과 리스트 표현식으로 N-gram 만들기
- N-gram을 만들 때 zip에 일일이 [1:], [2:] 같은 슬라이스를 넣는데, 만약 N-gram의 숫자가 늘어나면 그만큼 슬라이스도 여러 개 입력해줘야 하는 것이 번거롭기 때문에 이 과정을 코드로 만든 리스트 표현식을 사용하면 된다.
>>> text = 'hello' >>> [text[i:] for i in range(3)] ['hello', 'ello', 'llo']
- [text[i:] for i in range(3)] 처럼 for로 3번 반복하면서 text[i:]로 리스트를 생성했다.
- 이때 for i in range(3)dms 0, 1, 2 까지 반복하므로 text[i:]는 text[0:], text[1:], text[2:] 가 되고, 이것이 3-gram에 필요한 슬라이스이다.(text[0:]은 text와 같아서 지금까지 zip에 넣었던듯)
>>> list(zip(['hello', 'ello', 'llo'])) [('hello',), ('ello',), ('llo',)]
- 리스트 ['hello', 'ello', 'llo'] 를 zip에 넣어보면 결과가 3-gram이 아닌데, 이는 zip에 반복 가능한 객체 여러 개를 콤마로 구분해서 넣어주지 않고 ['hello', 'ello', 'llo'] 처럼 요소가 3개 들어있는 리스트 1개를 넣었기 때문이다.
- zip에 리스트의 각 요소를 콤마로 구분해서 넣어주려면 리스트 앞에 *를 붙여야 한다.
>>> list(zip(*['hello', 'ello', 'llo'])) [('h', 'e', 'l'), ('e', 'l', 'l'), ('l', 'l', 'o')]
- 이제 3-gram 리스트가 만들어졌고, 리스트 표현식을 바로 zip에 넣어주려면 리스트 표현식 앞에 *를 붙이면 된다.
>>> list(zip(*[text[i:] for i in range(3)])) [('h', 'e', 'l'), ('e', 'l', 'l'), ('l', 'l', 'o')]
'Python 코딩도장' 카테고리의 다른 글
파이썬 코딩도장 Unit 28 정리(1) - 회문 판별하기 (0) | 2022.02.17 |
---|---|
파이썬 코딩도장 Unit 27 정리(3) - 파이썬 객체를 파일에 저장하고 가져오기 (0) | 2022.02.16 |
파이썬 코딩도장 Unit 27 정리(2) - 문자열 여러 줄을 파일에 쓰고 읽기 (0) | 2022.02.15 |
파이썬 코딩도장 Unit 27 정리(1) - 파일에 문자열 쓰기, 읽기 (0) | 2022.02.14 |
파이썬 코딩도장 Unit 26 정리(5) - 반복문, 세트 표현식 사용 (0) | 2022.02.11 |