큰 의미가 없는 단어 토큰. 자주 등장 하지만, 분석을 하는 것에 있어서는 큰 도움이 되지 않는 단어들.
I,my,me,over,조사(이/가),접미사(-님,-질)
NLTK에서 불용어 확인하기
from nltk.corpus import stopwords
stopwords.words('english')[:10]
#['i', 'me', 'my', 'myself', 'we', 'our', 'ours', 'ourselves', 'you', 'your']
NLTK를 통해 불용어 제거하기
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
example = "Family is not an important thing. It's everything."
stop_words = set(stopwords.words('english'))
word_tokens = word_tokenize(example)
result = []
for w in word_tokens:
if w not in stop_words:
result.append(w)
print(word_tokens)
#['Family', 'is', 'not', 'an', 'important', 'thing', '.', 'It', "'s", 'everything', '.']
print(result)
#['Family', 'important', 'thing', '.', 'It', "'s", 'everything', '.']
한국어에서 불용어 제거하기
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
example = "고기를 아무렇게나 구우려고 하면 안 돼. 고기라고 다 같은 게 아니거든. 예컨대 삼겹살을 구울 때는 중요한 게 있지."
stop_words = "아무거나 아무렇게나 어찌하든지 같다 비슷하다 예컨대 이럴정도로 하면 아니거든"
# 위의 불용어는 명사가 아닌 단어 중에서 저자가 **임의**로 선정한 것으로 실제 의미있는 선정 기준이 아님
stop_words=stop_words.split(' ')
word_tokens = word_tokenize(example)
result = []
for w in word_tokens:
if w not in stop_words:
result.append(w)
# 위의 4줄은 아래의 한 줄로 대체 가능
# result=[word for word in word_tokens if not word in stop_words]
print(word_tokens)
print(result)
아래의 링크는 보편적으로 선택할 수 있는 한국어 불용어 리스트를 보여줍니다. (여전히 절대적인 기준은 아닙니다.)
링크 : https://www.ranks.nl/stopwords/korean
한국어 불용어를 제거하는 더 좋은 방법은 코드 내에서 직접 정의하지 않고 txt 파일이나 csv 파일로 수많은 불용어를 정리해놓고, 이를 불러와서 사용하는 방법입니다.
특정한 규칙을 가진 문자열의 집합을 표현하는 형식
1)정규 표현식 문법
특수문자 | 설명 |
---|---|
. | 한 개의 임의의 문자를 나타냅니다. (줄바꿈 문자인 \n는 제외) |
? | 앞의 문자가 존재할 수도 있고, 존재하지 않을 수도 있습니다. (문자가 0개 또는 1개) |
* | 앞의 문자가 무한개로 존재할 수도 있고, 존재하지 않을 수도 있습니다. (문자가 0개 이상) |
+ | 앞의 문자가 최소 한 개 이상 존재합니다. (문자가 1개 이상) |
^ | 뒤의 문자로 문자열이 시작됩니다. |
$ | 앞의 문자로 문자열이 끝납니다. |
{숫자} | 숫자만큼 반복합니다. |
{숫자1,숫자2} | 숫자1 이상 숫자2 이하만큼 반복합니다. ?, *, +를 이것으로 대체할 수 있습니다. |
{숫자,} | 숫자 이상만큼 반복합니다. |
[] | 대괄호 안의 문자들 중 한 개의 문자와 매치합니다. [amk]라고 한다면 a 또는 m 또는 k 중 하나라도 존재하면 매치를 의미합니다. [a-z]와 같이 범위를 지정할 수도 있습니다. [a-zA-Z]는 알파벳 전체를 의미하는 범위이며, 문자열에 알파벳이 존재하면 매치를 의미합니다. |
[^문자] | 해당 문자를 제외한 문자를 매치합니다. |
| | A|B와같이 쓰이며 A또는 B의 의미를 가집니다. |
문자규칙 | 설명 |
---|---|
\ | 역 슬래쉬 문자 자체를 의미합니다 |
\d | 모든 숫자를 의미합니다. [0-9]와 의미가 동일합니다. |
\D | 숫자를 제외한 모든 문자를 의미합니다. [^0-9]와 의미가 동일합니다. |
\s | 공백을 의미합니다. [ \t\n\r\f\v]와 의미가 동일합니다. |
\S | 공백을 제외한 문자를 의미합니다. [^ \t\n\r\f\v]와 의미가 동일합니다. |
\w | 문자 또는 숫자를 의미합니다. [a-zA-Z0-9]와 의미가 동일합니다. |
\W | 문자 또는 숫자가 아닌 문자를 의미합니다. [^a-zA-Z0-9]와 의미가 동일합니다. |
2)정규표현식 모듈함수
모듈 함수 | 설명 |
---|---|
re.compile() | 정규표현식을 컴파일하는 함수입니다. 다시 말해, 파이썬에게 전해주는 역할을 합니다. 찾고자 하는 패턴이 빈번한 경우에는 미리 컴파일해놓고 사용하면 속도와 편의성면에서 유리합니다. |
re.search() | 문자열 전체에 대해서 정규표현식과 매치되는지를 검색합니다. |
re.match() | 문자열의 처음이 정규표현식과 매치되는지를 검색합니다. |
re.split() | 정규 표현식을 기준으로 문자열을 분리하여 리스트로 리턴합니다. |
re.findall() | 문자열에서 정규 표현식과 매치되는 모든 경우의 문자열을 찾아서 리스트로 리턴합니다. 만약, 매치되는 문자열이 없다면 빈 리스트가 리턴됩니다. |
re.finditer() | 문자열에서 정규 표현식과 매치되는 모든 경우의 문자열에 대한 이터레이터 객체를 리턴합니다. |
re.sub() | 문자열에서 정규 표현식과 일치하는 부분에 대해서 다른 문자열로 대체합니다. |
3)문법 예시
import re
r=re.compile("a.c")
r.search("kkk") # 아무런 결과도 출력되지 않는다.
r.search("abc")
#<_sre.SRE_Match object; span=(0, 3), match='abc'>
#a.c 라는 패턴이 존재하는지 찾는 것. 있다면 span=(시작,끝)으로 표현
import re
r=re.compile("ab?c")
r.search("abbc") # 아무런 결과도 출력되지 않는다.
r.search("abc")
#<_sre.SRE_Match object; span=(0, 3), match='abc'>
r.search("ac")
#<_sre.SRE_Match object; span=(0, 2), match='ac'>
#ab?c는 b가 존재할 수도 있고 안할 수도 있는 패턴, 즉 abc or ac를 의미한다.
import re
r=re.compile("ab*c")
r.search("a") # 아무런 결과도 출력되지 않는다.
#*은 바로앞의 문자가 0개 이상일때를 말한다. 존재하지 않을 수도, 아주많을 수도 있다. ac,abc,abbc,ab....bc의 경우를 말한다.
r.search("abbbbc")
#<_sre.SRE_Match object; span=(0, 6), match='abbbbc'>
import re
r=re.compile("ab+c")
r.search("ac") # 아무런 결과도 출력되지 않는다.
#+는 앞의 문자가 1개 이상을 말한다. *와 동일, 하지만 앞문자가 존재는 해야한다. abc,abbc,ab.....bc의 경우를 말함
r.search("abbbbc")
#<_sre.SRE_Match object; span=(0, 6), match='abbbbc'>
import re
r=re.compile("^a")
r.search("bbc") # 아무런 결과도 출력되지 않는다.
#^는 시작되는 글자를 지정. ^a는 a로 시작하는 글자를 말함.
r.search("ab")
#<_sre.SRE_Match object; span=(0, 1), match='a'>
import re
r=re.compile("ab{2}c")
r.search("ac") # 아무런 결과도 출력되지 않는다.
r.search("abc") # 아무런 결과도 출력되지 않는다.
#숫자 만큼 앞의 문자가 반복된 경우를 말한다.
ab{2}c의 경우 b가 두번 반복되어 abbc의 경우를 말한다.
r.search("abbc")
#<_sre.SRE_Match object; span=(0, 4), match='abbc'>
import re
r=re.compile("ab{2,8}c")
r.search("ac") # 아무런 결과도 출력되지 않는다.
r.search("abc") # 아무런 결과도 출력되지 않는다.r=re
#앞에 문자가 숫자1이상 숫자2이하 개수가 있는 경우를 말함
#+ab{2,8}c는 b가 a와 c 사이에 2개이상, 8개이하 존재하는 경우.
import re
r=re.compile("a{2,}bc")
r.search("bc") # 아무런 결과도 출력되지 않는다.
r.search("aa") # 아무런 결과도 출력되지 않는다.
#앞의 문자가 숫자 이상 반복되는 경우를 말함
#a{2,}bc => aabc, aaabc, a.....abc
r.search("aaaaaaaabc")
<_sre.SRE_Match object; span=(0, 10), match='aaaaaaaabc'>
import re
r=re.compile("[abc]") # [abc]는 [a-c]와 같다.
r.search("zzz") # 아무런 결과도 출력되지 않는다.
#[]안의 문자들중 "한개"의 문자를 가진 경우를 말함.[a-z]소문자[A-Z]대문자[0-9]숫자로 범위 설정가능 처음 만난 한 문자에 대해서만 span 출력.
r.search("a")
<_sre.SRE_Match object; span=(0, 1), match='a'>
r.search("aaaaaaa")
<_sre.SRE_Match object; span=(0, 1), match='a'>
r.search("baac")
<_sre.SRE_Match object; span=(0, 1), match='b'>
^기호 뒤의 문자들을 제외한 모든 문자의 경우를 말함.
[^a-zA-Z] 영어 대소문자 제외
import re
r=re.compile("[^abc]")
r.search("a") # 아무런 결과도 출력되지 않는다.
r.search("ab") # 아무런 결과도 출력되지 않는다.
r.search("b") # 아무런 결과도 출력되지 않는다.
r.search("d")
#<_sre.SRE_Match object; span=(0, 1), match='d'>
3)모듈 함수 예시
re.match는 첫 부분부터 정규 표현식과 확인
re.search는 정규 표현식 전체에 대해서 문자열 매치 확인
import re
r=re.compile("ab.")
r.search("kkkabc")
<_sre.SRE_Match object; span=(3, 6), match='abc'>
r.match("kkkabc") #아무런 결과도 출력되지 않는다.
#ab. 으로 시작하지 않음으로 match결과는 나오지 않는다.
r.match("abckkk")
#<_sre.SRE_Match object; span=(0, 3), match='abc'>
정규 표현식 기준으로 문자열을 분리하여 리스트로 리턴한다.
import re
text="사과 딸기 수박 메론 바나나"
re.split(" ",text)
#['사과', '딸기', '수박', '메론', '바나나']
공백을 기준으로 분리가능.
정규 표현식과 매치되는 모든 문자열들을 리스트로 리턴. 없으면 빈 리스트.
import re
text="""이름 : 김철수
전화번호 : 010 - 1234 - 1234
나이 : 30
성별 : 남"""
re.findall("\d+",text)
#['010', '1234', '1234', '30']
정규 표현식 패턴과 일치하는 문자열을 대체
import re
text="Regular expression : A regular expression, regex or regexp[1] (sometimes called a rational expression)[2][3] is, in theoretical computer science and formal language theory, a sequence of characters that define a search pattern."
re.sub('[^a-zA-Z]',' ',text)
#'Regular expression A regular expression regex or regexp sometimes called a rational expression is in theoretical computer science and formal language theory a sequence of characters that define a search pattern '
import re
text = """100 John PROF
101 James STUD
102 Mac STUD"""
re.split('\s+', text)
#['100', 'John', 'PROF', '101', 'James', 'STUD', '102', 'Mac', 'STUD']
re.findall('\d+',text)
#['100', '101', '102]
re.findall('[A-Z]',text)
#['J', 'P', 'R', 'O', 'F', 'J', 'S', 'T', 'U', 'D', 'M', 'S', 'T', 'U', 'D']
re.findall('[A-Z]{4}',text)
#['PROF', 'STUD', 'STUD']
re.findall('[A-Z][a-z]+',text)
#['John', 'James', 'Mac']
NLTK에서는 Regexp Tokenizer를 사용하여 토큰화 가능.
import nltk
from nltk.tokenize import RegexpTokenizer
tokenizer=RegexpTokenizer("[\w]+")
print(tokenizer.tokenize("Don't be fooled by the dark sounding name, Mr. Jone's Orphanage is as cheery as cheery goes for a pastry shop"))
#['Don', 't', 'be', 'fooled', 'by', 'the', 'dark', 'sounding', 'name', 'Mr', 'Jone', 's', 'Orphanage', 'is', 'as', 'cheery', 'as', 'cheery', 'goes', 'for', 'a', 'pastry', 'shop']
#\w, 즉 문자나 숫자가 1개 이상있는 경우를 사용하여 토큰으로 만듬.
import nltk
from nltk.tokenize import RegexpTokenizer
tokenizer=RegexpTokenizer("[\s]+", gaps=True)
print(tokenizer.tokenize("Don't be fooled by the dark sounding name, Mr. Jone's Orphanage is as cheery as cheery goes for a pastry shop"))
#["Don't", 'be', 'fooled', 'by', 'the', 'dark', 'sounding', 'name,', 'Mr.', "Jone's", 'Orphanage', 'is', 'as', 'cheery', 'as', 'cheery', 'goes', 'for', 'a', 'pastry', 'shop']
#gaps=True로 토큰을 나누는 기준을 [\s], 공백으로 지정 하게 됨.