Chelsey 2022. 12. 11. 20:23
728x90

토큰화

토큰 token 이란 고유한 의미를 말한다. 더 이상 나눌수 없는 하나의 단위를 의미한다.

  1. 축약 contraction 된 표현 : 여러 단어가 공백없이 하나의 묶음으로 묶여있는 경우
  2. n-gram : 여러 단어 사이에 공백이 있지만 의미상 하나의 묶음으로 보는 것이 타당한 경우. 숙어, 관용어구

토큰화 : 각 특징에 따라 의미 단위로 - 토큰 단위로 나누는 것.
축약된 것은 두 개의 토큰으로 나누고 n-gram 같은 것은 하나의 토큰으로 인식하는 과정

# 첫 번째인 - 하나만 변환
sub(pattern='변환할 원래 문자열', replacement='변환 후 입력될 문자열', x='데이터값인 벡터', ignore.case=FALSE)
# ignore.case : 대소문자를 별개의 문자로 구분할 것인가?

# 모든 값을 변환
gsub(...)

 

축약됐을 때 토큰화하는 방법 - 사전을 이용한다. 데이터 정제후 split하여 토큰화한다.

#축약된 형태의 사전 예시 - 실전에서는 직접 만들 필요없이 만들어진 사전을 찾아서 쓰면된다.
contraction_dict <- list( c("don't", "it's", "you're"), 
						  c("do not", "it is", "you are"))
dictlen <- length(contraction_dict[[1]]) # 축약된 표현의 수

datstr <- "I don't think you're ready."
for (stri in 1:dictlen) {
	datstr <- gsub(pattern=contraction_dict[[1]][stri],
    				replacement=contraction_dict[[2]][stri],
                    x=datstr)}

strsplit(datstr, " ") # 단어들을 원래 형태로 토큰화

숙어나 관용어를 위한 토큰화하는 방법 - 사전을 이용한다. 데이터 정제 후 split하여 토큰화한다.

# 관용어들
ngram_dict <- list( c("bed" and breakfast", "grab and go", "New York"),
					c("bed_and_breakfast", "grab_and_go", "New_York"))
ndictlen <- length(ngram_dict[[1]])
datstr <- "It's one of the best bed and breakfast in New York."
for (stri in 1:ndictlen) {
	datstr <- gsub(x=datstr, pattern=ngram_dict[[1]][stri],
    				replacement=ngram_dict[[2]][stri])
                    
strsplit(datstr, " ") # 토큰화 완성

 

대소문자 변환과 문장부호 삭제

대소문자 변환 

  • 고유명사의 일부로 사용된 경우 대문자, 보통명사인 경우에는 소문자로 쓰이는 규칙 유의
  • ex) "NewYork University" vs "universities in nyc")
  • 문자를 소문자로 : tolower()
  • 문자를 대문자로 : toupper()
  • 자주쓰는 고유명사의 경우 n-gram 사전으로 작성해 둘수도 있음

문장부호의 삭제

  • 문장부호가 보통 특별한 의미를 안가지므로 전처리 과정에서 삭제하게 된다.
  • 하지만 무조건적인 삭제는 좋지 않다.
    Wash. == Washington 이나 's 같은, 줄임말을 쓰기위해 문장부호를 사용한 경우가 있다.
  • 정규표현식을 이용해 문장부호 삭제 - 수정이 가능하다.
문자클래스 의미
[:alpha:] 알파벳
[:lower:] 소문자
[:upper:] 대문자
[:blank:] 공백, 탭 등
[:digit:] 숫자
[:alnum:] 영문자와 숫자
[:punct:] 문장부호
[:space:] 공백, 탭, 줄바꾸기 등

 

정규식을 이용해 첫 글자로 사용된 대문자를 소문자로 변환

  • \\L : 소문자 , \\1 : 첫 문자 하나
  • perl을 True로 지정해줘야한다.
# 첫 글자가 대문자인 것 소문자로 바꾼다.
x <- gsub(x, pattern="[[:upper:]]", replacement="\\L\\1", perl=T)

# alphabet과 빈 칸 제외하고
x <- gsub(x, pattern="([^[:alnum:][:blank:]'-])", replacement="")

어간추출 stemming 과 원형복원 lemmatization

어간추출 stemming

  • 여러 단어의 공통된 문자열을 추출하는 것. 
  • 단수형과 복수형, 현재형과 과거형, 과거분사 등에서 불규칙 변화인 경우 - 어간 추출이 어려움 - 사전을 사용

 

어간추출 시 고려해야할 점들

  • 토큰 길이가 3글자 이하면 그대로 반환
  • 숫자로 표현된 토큰은 그대로 반환
  • 토큰이 s/es/ed로 끝나면 s/es/ed를 삭제한 단어가 사전에 있는지 확인 - 있으면 - s/es/ed를 삭제한 토큰 반환
  • 토큰 길이가 6 이상이고 ing로 끝나면 ing를 삭제한 토큰 반환
  • 토큰 길이가 5이하고 ing로 끝나면 토큰 그대로 반환

영어문장 어간추출기

  • 포터의 어간추출기 Porter stemmer & 랭커스터 대학 어간추출기 Lancaster stemmer
  • Porter는 대체로 원 단어를 보존하는 방식
  • Lancaster는 더 많은 문자를 삭제
  • textstem package - stem_strings() 함수 이용 (-> snowballC pacakge - wordStem() 호출함, wordStem() - Porter 어간추출기를 디폴트로 사용한다)
install.packages("textstem")
library(textstem)

stem_string(data, language="porter")

 

원형복원 lemmatization

  • 불규칙 과거형, 비교급 단어가 불규칙하면 어간 추출이 어려우므로 -> 원형으로 표현해 의미상 공통성을 표현한다.
  • R - textstem package - lemmatize_strings()
lemmatize_strings(data)

 

불용어 stopwords 삭제

  • 문장에서 관사(the)와 전치사(in, of, for), 접속사(and) - 문법적인 기능과 의미인 것 = 기능어 function word
  • 기능어를 삭제하겠다
  • 지프의 법칙 Zipf's law 
    • 경험적 법칙으로 단어의 출현빈도를 설명하는데 유용하게 사용할 수 있다.
    • 각 단어의 출현빈도와 출현빈도순위 사이에 반비례 관계
  • 단어주머니 가설에서는 단어의 출현빈도가 중요한 변수임
  • R의 stopword package에 자주 등장하는 불용어가 저장되어 있어서 사용할 수 있다.
install.packages("stopwords")
library(stopwords)

txt
txt <- tolower(txt)
txt <- gsub(...)
txt <- strsplit(txt, " ")
lapply(txt, setdiff, y=stopwords())
  • 불용어 목록이 완벽하진 않다. - 아래처럼 일부 수정해서 사용하면 됨
newstop <- c(stopwords(), "can") # 불용어사전에 "can"cnrk
newstop <- setdiff(newstop, c("no", "not")
lapply(txt, setdiff, y=newstop)

 

 

728x90