데이터를 분석하기에 앞서 분석에 용이하도록 데이터를 정제/ 가공하는 작업
-> 영어는 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를 같이해서 계산하겠다. 문서빈도수 ⬆️ 중요도⬇️
로그란?(벼는 익을수록 고개를 숙인다)
- 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)
토큰의 종류가 많다는 것은 공부해야할 내용이 많다는 의미다.
'bootcamp' 카테고리의 다른 글
(국민청원을 바탕으로한 예습)통계, 기술용어 (0) | 2022.11.07 |
---|---|
[웹크롤링] 요청거절당한 동적크롤링 (0) | 2022.10.31 |
[웹크롤링] 동적페이지 크롤링 (0) | 2022.10.31 |
[웹크롤링] 공부방법!? (0) | 2022.10.30 |
[웹크롤링] 썸네일 이미지 가져오기 (0) | 2022.10.28 |