본문 바로가기
bootcamp

[데이터 전처리] 전처리란?

by AI미남홀란드 2022. 11. 1.
728x90

데이터를 분석하기에 앞서 분석에 용이하도록 데이터를 정제/ 가공하는 작업

-> 영어는 NLTK 패키지를 , 한글은  KoNLPy 패키지를 사용한다.

 

 

텍스트 데이터 전처리로는 토큰화, 노이즈/불용어제거, 정규화, 품사태깅, 벡터화 등이 있다.

 

1️⃣  토큰화 : 텍스트를 원하는 단위로 분절하는 작업이다. 문장 토큰화 단어토큰화 등이 있다. 여기서 말하는 '토큰'은

                   분절하는 기준이 되는 '문장'이나 '단어'라고 생각하면 된다. ✂️

                   * 의미를 가진 가장작은 단위인 '형태소' 단위로 토큰화(의미파괴되는 토큰화는 절대 안됨)

Hannanum , Kkma, KOmoran, Okt(Twitter), Mecab(제일 빠름)

정규표현식(Regular Expression) : findall(), sub() 찾아주는 명령어

 

⭐️정규표현식 규칙(10개)⭐️

 

1.   .    모든 문자 1개

문서=12345 -> 한자리 숫자자로 다 찾고 싶다면 -> target = re.findall('.', 문서)
문서= 갤럭시s3...갤럭시s4...갤럭시s5 -> 갤럭시 모든 시리즈 -> target = re.findall('갤럭시s.', 문서)
문서= '알파코는 알차코를 사랑했다. -> 알파코 알차코를 찾고 싶다면 -> target = re.findall('알.코', 문서)

2.   a?   a가 0회 또는 1회 (앞에꺼 0회 또는 1회) -> 있든지 없든지

문서 = 알코는 알파코를 사랑해서 알파파코를 낳았다 -> 알코, 알파코를 찾고 알파파코X -> target = re.findall('알파?코', 문서)
: 알파?코 == 알 + 파 0회 또는 1회 + 코 = 알코 or 알파코
문서 = '/news?no=1&page...' or '/news>no=2&page...' -> no=값이 있든지 없든지 -> re.findall('no=숫자?', 문서)

3.   a*. a가 0회 이상 -> 없거나 있거나 여러개 있거나 ( 별은 둥글다 0회 이상)

문서 = 알코는 알파코를 사랑해서 알파파코를 낳았다 -> 알코, 알파코를 찾고 알파파코X -> target = re.findall('알파*코', 문서)
: 알파*코 == 알 + 파 0회 1회 2회 3회 + 코 = 알코 or 알파코or 알파파코
문서 = '/news?no=1&page...' or '/news>no=2&page...' -> no=값이 있든지 없든지 -> re.findall('no=숫자*', 문서)

4.   a+ a가 1회 이상 -> 하나 있거나, 여러개 있거나 ( 1회이상)

문서 = 알코는 알파코를 사랑해서 알파파코를 낳았다 -> 알코, 알파코를 찾고 알파파코X -> target = re.findall('알파+코', 문서)
: 알파+코 == 알 + 파  1회 2회 3회 + 코 = 알코 or 알파코or 알파파코
문서 = '/news?no=1&page...' or '/news>no=2&page...' -> no=값이 있든지 없든지 -> re.findall('no=숫자+', 문서)

5.   abc a뒤, c앞에 있는 b / abc에서 b만

문서 = 알파알파코 -> 알파를 한 묶음으로 지정하고 싶다면 -> (알파)
문서 = <a>text</a> -> <a>와 </a> 사이에 있는 text만 저장하고 싶다면 (양쪽 태그는 배제) -> <a> (text)</a>
(abc)를 하면 -> abc가 들어가 있는걸 찾지만
abc 그냥 하면 -> a,b,c 셋중 들어 있는 것을 찾아온다

6,7. [a-z], a부터 z까지 중 하나,

 ['^가~힣'], 가부터 힣까지 제외한 것들 중 하나

문서 = abdcdefedcba -> a, b, c만  지정하고 싶다면 -> re.findall('[abc]',문서)
:[abc] == a랑 b랑 c중에 해당하는게 있다면 다 찾고 싶어 ! (*구분자는 없다)
문서 = alb2c34e5*** -> 소문자알파벳만 찾고 싶다면 -> re.findall('[a-z',문서)
                                          숫자만 찾고 싶다면 -> re.findall([0-9], 문서)
꺽새가 없다면 a-z 까지 찾고 ^가~힣 이라면 얘네를 제외하고 찾아라( 눈웃음 부정적의미)

8. \+ 회피용법 , 특수기호로써의 + 말고 진짜 + ( 지금까지 배운 특수기호 그 자체를 정규표현식으로 표현하고 싶다면 앞에 역슬래시\ )

응용: 숫자열, 한글열 표현하기 

문서 = alpaco123@gmail.com ->123 (숫자열을) 찾고 싶다면 -> re.findall('[0-9]', 문서) -> 1,2,3 따로 따로 찾아야됨
문서 = alpaco123@gmail.com ->123 (숫자열을) 찾고 싶다면 -> re.findall('[0-9]+', 문서) -> 123열로 찾아야됨
[0-9]+= 숫자 1회 이상 = 숫자열
[가-힣]+ =문자열(한글)1회 이상 = 한글열
문서 = 2023 한국경제 5% 이상 성장 -> re.sub([^가-힣], 문서() -> '한국경제' 만 남고 다 지워진다.

응용. 숫자열 표현하기, 한글열 표현하기

문서 = alpac123@gmail.com -> 123(숫자열)을 찾고 싶다면? -> re.findall('[0-9]', 문서) 1,2,3 따로  -> '1', '2', '3'
문서 = alpac123@gmail.com -> 123(숫자열)을 찾고 싶다면? -> re.findall('[0-9]+', 문서) 123 열로 ->  '123'
문서 = alpac123@gmail.com -> aplac123를 찾고 싶다면 -> re.findall('[a-z1-9]+, 문서) alpac123열로 -> alpac123 
[0-9]+                                            [가-힣]+
숫자+= 숫자 1회 이상 = 숫자열         한글

9.   .+  문자여러개 Greedy Quantifier(탐욕적인) , 문자열을 최대한 길게 

10.   .+? 문자 여러개 Reluctant Quantifier(내키지않는 , 게으른) , 문자열을 최대한 짧게

신라면이 집에 있다면 먹고 싶다 -> 신라면 -> re.findall('신 +면'. 문서) / re.findall('신+?'면, 문서)
문서 = resp.content =({~{~}~~~{~}~~~~~~}); ->{~~~~{~}~~~~~~}(json전체) -> {.+} / {.+?}
문서 = href = /research?title_id=78901234&no=1&sort=new&where=toon
-> title_id=788901234& -> title_id=.+?& 찾아옴
-> (응용) 그 중에서 78901234만 찾아내려면 -> title_id=(.+?)& -> () 은 위치적 특징을 나타내준다.

정규표현식 활용 훈련

문서에서 특정 대상을 찾아내고 싶을 때 -> 정규표현식 마렵다.
->정규표현식을 이용해 특정 대상을 어떻게 표현할 것인가?
-> 1) 대상의 내부적 특징을 표현할 것인가 : 정규표현식 문법 1번~8번 활용
-> 2) 대상의 외부적(위치적) 특징으로 표현할 것인지: Quantifier +()활용
-> 사실1)내부 2)외부(위치) 모두 고려하게 됨

문서 = 
삼성전자: 100,000
현대차 :   300,300
네이버 : 1,000,000 

가격만 뽑아내보자 -> refindall('.+?', 문서) -> ([1-9,]+0, 문서) -> 해석 : 숫자와 , 표를 찾는데 +1개이상 0까지 찾아라
우리끼리만 일치하는 공통적 특징 찾기!
1) 내부적 특징이든 외부적 특징이든 자신에게 편한쪽부터 먼저 찾는다
2) 자신에게 편한 한 쪽만으로 완벽하게 표현가능한지 판단!
3) 가능하다면 한 쪽만 표현하고 끝, 불가능하다면 다른 쪽까지 표현해서 완성
" 가장 중요한 것은 실수 하지 않는 것이 가장 중요! 1차원, 나의 표현식이 너무 구차하고 길어도 신경쓰지 말자!"

 

2️⃣ 노이즈/불용어 제거 : 분석에 도움이 되지 않는 '노이즈/불용어'들을 제거하는 작업이다.

 

"의미가 없는 노이즈와 의미는 있으나 필요치 않은 불용어를 삭제하는 작업"
-> 노이즈는 보통 정규표현식이나, 길이를 기준으로 삭제해주고, 불용어는 보통 불용어 사전을 만들어서 삭제해준다.

 

3️⃣ 통일화 : 형태는 다르나 같은 의미를 가진 단어들을 통일시키는 작업이다. '어간추출' 과 '표제어 추출'이 있다.

의미상 중복되는 단어들을 통합하여 단어의 개수를 줄이기 위함이다.
'어간 추출' 과 '표제어 추출'이 있다.
ex) going, goes -> go
      갔다, 갔었다 -> 가다 등
"어간(stem)"이란 어형(단어의 형태)변화 시, 변하지 않는 부분을 말한다."
가다,간다,갔다!,갔었다. 갈 것이다 -> 어간 = 가
go goes going -> 어간 = go

"어간 추출(Stemming)은 단어에만 어간만 남기는 작업이다."

표제어 추출 : 표제어 란 단어의 기본형을 말한다.
go -> go, has -> have, is -> be, are -> be

 

4️⃣ 품사 태깅 : 앞서 토큰화한 단어에 품사를 붙이는 작업이다.

"품사태깅"이란 단어 혹은 형태소에 품사를 붙이는(tagging) 작업을 말한다."

Text = ['나', '배고프다'] ->(pos()) -▶️ [('나','NOUN'), [('배고프다',VERB')}

: (token1, pos1), (token2, pos2) -▶️ 토큰과 품사가 튜플로 묶여서 반환된다.

 

나 -> ('나', 'NOUN')     # 태깅

한글에는 품사를 9가지로 구분한다.
명사 - 대명사 - 수사 - 동사 - 형용사 -관형사 -부사 - 감탄사 -조사
NLTK에서는 pos_tag()함수를 지원한다. 품사 태깅을 한 후, 원하는 품사들만 골라내는 작업이기도 하다
NOUN(명사) - PRON(대명사) - (NUM) - VERB(동사) - ADJ(형용사) - DET(관형사) - ADV(부사) - PRT(불변화사;조사) - CONJ(접속사) - ADP(전/후치사)

품사 태깅을 왜 할까?

일반적으로 필요한 품사만 남기기 위해서 ! 

명사, 수사, 관형사, 동사, 부사 등등 이중에 의미가 분명하다고 생각하는 품사들만 남기고 싶을 수 있다!

예를 들어 , 명사만 남기고 싶다! 명사와 동사만 남기고 싶다!

나 -> ('나', 'NOUN') -> 품사를 가지고 선택 할 수 있다!


5️⃣ 벡터화 : 비정형 데이터인 텍스트를 정형화하는 작업이다. BoW, TF-IDF, word embedding 등이 있다. (벡터 - 숫자's)

'벡터화'는 BoW, TF-IDF, 임베딩 등의 방법이 있다

 

1) Bow(Bag-of-words) : 해당 문서 내 단어들의 출현 빈도만을 가지고 텍스트를 벡터화(수치화)한 방법이다

(💬어떤 토큰이 얼마나 많이 나왔나? -> 문서의 의미정보(feature)   [토큰의 빈도수 -> 숫자]

 

- 벡터화 과정 (빈도수/불용어제거 , 희소표현)

✔️1. 하나의 문서 이상 등장한 모든 토큰 수집                        #희소표현 : ex) 허들을 높혀 10개의 문서 등 으로 특정값여러개로 올린다

✔️2. 수집한 토큰 뭉치 -> 문서의 feature로 설정한다.

✔️3. 각 문서마다 토큰(feature)의 빈도수를 Count

-

↪️Count한 feature 기준의 여러분석

여러 텍스트의 Bow 를 결합하여 "문서 단어 행렬"을 만들 수 있다

1) 빈도 높은 불용어에 의한 왜곡

2) 희소 표현

단어들의 길이가 데이터의 차원(feature, 요인)이 된다.

 

2) TF-IDF(Team Frequency-Inverse Document Frquency 역문서빈도수) : 해당 문서 내 단어들을 출현 빈도와 함께 단어의 문서 빈도수, 즉 희귀성까지 고려하여 좀 더 정확하게 단어의 중요성을 벡터화한 방법이다.

ex) 나한테만 밥먹을래 ?  , 친구 10명에게 밥먹을래? -> idf를 같이해서 계산하겠다. 문서빈도수 ⬆️ 중요도⬇️

TF-IDF

로그란?(벼는 익을수록 고개를 숙인다)

- x가 증가할때 로그, x는 우상향, x가 1일때 로그1은 0이다. 로그는 언젠가 뚫는다(화성) 도지코인같은놈임

-> TF(Team Frequency)는 긍정적인요인 DF(Document Frquency)는 부정적인요인

네거티브를 처음엔 강하게 주다가 가면 갈수록 더 러프하게 주어야 하기 때문에 로그를 씌어준다. 

❗️처음엔 강하게 먹이다 나중엔 너프를 먹인다

 

문서간의 유사도

1. 코사인 유사도

- 코사인 a/b 각도가 누워서 자기자신을 만나면 1이 되서 제일 큼

- 벡터화의 방향이 비슷하면 각이 작고(코사인 값이큼), 벡터화 방향이 다르면 각이 크다(코사인 값이 작음)

 

2. 유클리드 거리 유사도

루트 A제곱 + B제곱

 

3. 자카드 유사도

합집합/교집합


3) Word Embedding : 단어 하나 벡터화하여 문서 내 단어의 순서 정보를 유지하며 텍스트를 벡터화한 방법이다.

 

"워드 임베딩"의 출현은 기존 방식이 문서 내 단어의 순서 정보를 기억하지 못한다 에서 문제제기에서 출발한다

-> 단어(워드)를 숫자로 바꾸겠다.❗️


                                          나는 | 너를 | 정말 | 많이 | 좋아해

나는 너를 정말 좋아해 ->    1      |   1   |    1    |    0  |    1

                                             문장을 통으로 백터화

 

나는 ->(10000)

너를 ->(01000)

정말 ->(00100) 

많이 ->(00010)   --> 사용x              🌟  핵심은 서로 다른 벡터가 되도록

좋아해->(00001)

 

"나는 너를 정말 좋아해" -> [나는, 너를 , 좋아해] -> [(10000), (01000), (00100), (00001)] 

 

원 핫 벡터화🔥 (관습적으로 배제)

 정보가 긴것에 비해 낭비가 심하다 희소하다 하나만 1이고 나머지가 0이라 희소하다 실제 쓰기엔 애매하다


벡터화 방식은 어떤 것들이 있을까? word2vec , Glove 등의 방법이 있다.

일반적으로 워드 임베딩 방법론이란 함은 기존의 원-핫 벡터화 방식의 문제를 해결한 베터화 방식을 말한다.

  원-핫 벡터 임베딩벡터
길이(차원) 고차원 저차원
표현 희소 밀집
학습여부 x o
 0 또는 1 실수

N-Gram

인접한 토큰들을 묶어주는 작업들을 통해서.. 한개의 단어씩 토큰화 

 

 

#쉬운개념 : 문자열이 들어와 리스트(1) -> (2),(3),(4) 리스트 길이 줄이기 -> 문자를 숫자로 바꾼다(5)


텍스트 전처리 중간 정리

토큰화 이후의 [노이즈/불용어 제거, 통일화, 품사태깅] 과정은 토큰의 종류를 줄이는 과정이다.

 

원문서 -> 토큰화 : 1000가지 종류의 토큰 -> 토큰이 결국 1가지만 남는게 좋은걸까?

⬇️

 

적절한 종류의 토큰이 남아야 좋은 것


토큰의 종류가 공부 자료의 수 (데이터수를 의미X)

토큰의 종류가 많다는 것은 공부해야할 내용이 많다는 의미다.

 

 

 

728x90