어텐션 메커니즘이란, 트랜스포머의 기반이 되는 모델이자, seq2seq의 단점을 보완할 수 있는 개념이다.

 

멀수록 잊혀진다(decoder) --- >  갈수록 흐려지는 정보에 ATTNETION하자!!

 

seq2seq 모델은 기존 RNN과 같이 고정된 길이의 벡터를 입력으로 받아 고정된 길이의 벡터를 출력하는 구조를 갖고 있음

이 구조는 시퀀스 길이가 길어질수록 정보 손실이 발생함!

 

이러한 한계를 보완하기 위해 Attention Mechanism이 도입되었다. 

어텐션 메커니즘은 입력 문장의 모든 단어를 동일한 가중치로 취급하지 않고, 출력 문장에서 특정 위치에 대응하는 입력 단어들에 더 많은 가중치를 부여하는 원리로 만들어졌다.

이를 통해 입/출력의 길이가 달라도 모델이 상대적으로 더 정확하고 유연하다고 볼 수 있다.

 

seq2seq

인코더: 입력 시퀀스를 context vector라는 하나의 고정된 크기의 벡터 표현으로 압축

디코더: 이 context vector를 통해서 출력 시퀀스를 만들어냄

문제점: 1 - 하나의 고정된 크기의 벡터에 모든 정보를 압축하려고 하다보니 정보 손실 발생!

             2 - RNN의 고질적인 문제인 기울기 소실이 존재!\

 

 

1. 어텐션의 기본 아이디어

어텐션의 기본 아이디어는 디코더에서 출력 단어를 예측하는 매 시점(time step)마다, 인코더에서의 전체 입력 문장을 다시 한 번 참고한다는 점이다.

단, 전체 입력 문장을 전부 다 동일한 비율로 참고하는 것이 아니라, 해당 시점에서 예측해야할 단어와 연관이 있는 입력 단어 부분을 좀 더 집중(attention)해서 보는 것이다.

 

중요하니까 자세히..!!

디코더(Decoder)에서 출력 단어 예측하는 매 시점(time step)마다 인코더(Encoder)에서의 전체 입력 문장(sequence)을 다시 한 번 참고한다는 것..

단, 전체 입력 sequence 참고하는게 아니라 해당 시점에서 예측해야할 단어 연관이 있는 입력 단어 부분을 좀 더 집중해서 보겠다는 것이다.

 

2. 어텐션 함수(Attention Function)

파이썬의 딕셔너리 함수를 떠올려보자. key-value, 쌍으로 이루어진 자료형이다.

이 딕셔너리 자료형은 키를 통해서 매핑된 값을 바로 찾아낼 수 있다는 특징을 갖고 있다.

 

dict = {"2017" : "Transformer", "2018" : "BERT"}의 경우, 2017은 키, Transformer은 값(value)에 해당한다.

이 개념을 통해서 어텐션 함수에 대해서 그림을 통해 알아보자.

 

어텐션을 함수로 표현하면 주로 다음과 같이 표현할 수 있다.
Attention(Q, K, V) = Attention Value

 

어텐션 함수는 주어진 '쿼리(Query)'에 대해서 모든 '키(Key)'와의 유사도를 각각 구한다. ★

그리고 구해낸 이 유사도를 키와 매핑되어있는 각각의 값에 반영하고 유사도가 반영된 값을 모두 더해서 리턴.

여기서는 이를 어텐션 값(Attention Value)이라고 하고, 지금부터 배우게 되는 seq2seq + 어텐션 모델에서 Q, K, V에 해당되는 각각의 Query, Keys, Values는 각각 다음과 같다.

Q = Query : t 시점의 디코더 셀에서의 은닉 상태
K = Keys : 모든 시점의 인코더 셀의 은닉 상태들
V = Values : 모든 시점의 인코더 셀의 은닉 상태들

 

Attention 모델은 인코더 층 seq2seq층 동일하지만 디코더 층에서 차이가 남.

디코더 층에서는 RNN계열 층을 지나고 Attention 층을 지나는데 이때 Attention층에서는 시점마다 RNN계열층 은닉상태(Quary)와 인코더에서의 전체 입력 시퀀스 정보(Key, Value)를 다시 한번 참고한다.

 

 

 

 

 

✅ 쿼리 (Query)
• 쿼리는 어텐션 메커니즘에서 주목할 대상을 나타내는 정보
• 쿼리는 보통 출력 시퀀스의 현재 위치 또는 상태와 관련이 있으며, 어텐션 메커니즘을 통해 중요한 입력 요소를 찾는 데 사용
• 기계 번역에서 디코더의 현재 출력 단어에 해당하는 쿼리가 사용될 수 있으며, 이 쿼리는 입력 문장의 어떤 부분에 더 집중해야 하는지를 결정

 

✅ 키 (Key)
• 키는 입력 시퀀스의 각 요소에 대한 정보를 나타냄
• 키는 쿼리와 비교되어 유사성을 측정하며, 어떤 입력 요소가 현재 쿼리와 얼마나 관련 있는지를 결정하는 데 사용.
• 키는 일반적으로 입력 시퀀스의 각 요소 (예: 단어 또는 문장)에 대한 벡터 또는 표현으로 표현됨

 

✅ 값 (Value)
• 값은 입력 시퀀스의 각 요소에 대한 정보를 담고 있다.
• 값은 어텐션 메커니즘에서 가중 평균을 계산할 때 사용되며, 쿼리와 키의 유사성에 따라 값에 가중치가 부여된다.
• 값은 주로 입력 시퀀스의 각 요소에 대한 정보를 포함하는 벡터 또는 표현으로 표현된다.

 

이러한 Q,K,V(쿼리, , 벨류)를 가지고 Attention층에서는 Attention 함수 사용되는데 이때 다양한 함수(Attention Score Function)를 이용해서 Attention Score가 만들어지고 보통 SoftMax 함수를 통해 Attention Value가 생성됨

 

 

어텐션 함수는 주어진 쿼리(Query)에 대해 모든 키(Key)와의 유사도를 구한다.

벡터간의 거리(유사도)를 구하는 방법은 내적코사인 유사도유클리디안 거리 방법 등이 있지만 내적 유사도를 보통 사용한다고 한다.

 

유사도 개념 중요 ★

 

여기서 Attention Score 함수 중 Dot-product Attention에 대해서 알아보자!!

아래 그림 참조

인코더의 시점(time step)을 각각 1, 2, ... N이라고 하였을 때 인코더의 은닉 상태(hidden state)를 각각 ℎ1, ℎ2, ... ℎ𝑁라고 합시다. 디코더의 현재 시점(time step) t에서의 디코더의 은닉 상태(hidden state)를 𝑠𝑡라고 해보자.

 

어텐션 메커니즘의 첫 걸음인 어텐션 스코어(Attention score)에 대해서 배우기전에, 이전 챕터 배웠던 디코더의 현재 시점 t에서 필요한 입력값을 다시 떠올려보자. 시점 t에서 출력 단어를 예측하기 위해서 디코더의 셀은 두 개의 입력값을 필요로 하는데, 바로 이전 시점인 t-1의 은닉 상태와 이전 시점 t-1에 나온 출력 단어다.

그런데 어텐션 메커니즘에서는 출력 단어 예측에 또 다른 값을 필요로 하는데 바로 어텐션 값(Attention Value)이라는 새로운 값이다. t번째 단어를 예측하기 위한 어텐션 값을 𝑎𝑡이라고 해보자.

 

어텐션 스코어란 현재 디코더의 시점 t에서 단어를 예측하기 위해, 인코더의 모든 은닉 상태 각각이 디코더의 현 시점의 은닉 상태 𝑠𝑡와 얼마나 유사한지를 판단하는 스코어값이다.

닷-프로덕트 어텐션에서는 이 스코어 값을 구하기 위해 𝑠𝑡를 전치(transpose)하고 각 은닉 상태와 내적(dot product)을 수행합니다. 즉, 모든 어텐션 스코어 값은 스칼라입니다. 예를 들어 𝑠𝑡과 인코더의 i번째 은닉 상태의 어텐션 스코어의 계산 방법은 아래와 같습니다.



-----------------------------------------------------------------------------------------------------------------------------------------------------------------

유튜브(https://www.youtube.com/watch?v=8E6-emm_QVg&t=80s)를 통해서 복습.

 

결국 어텐션이란 -> decoder의 각각의 상태에서, 시점마다 다른 context vector를 쓴다!!!! 

-> 4번째 시점에서 예측할 때는, 4번째에서 context vector를 구해야겠지?

Context Vector 4 = C4라고 하고, dot product를 써보면,  C4 = <S4,h1>h1 + <s4,h2>h2 + <s4,h2> + <s4,h3>h3 -> weighted sum이라고 할 수 있음.

 

weighted sum -> 취사 선택!! 즉, h1,h2,h3 중 어느것을 더 많이 쓸까? (어떤 단어를 더 볼까??~~)

-> 유사도 기준으로 쓰는게 논리적이겠지?? (내적 유사도를 구해보자!!)

 

-> 유사도가 더 높다 -> 더 닮았다!!! -> 너에게 더 Attention 해주겠다 -> 더 높은 가중치를 부여!

 

"선형 변환"

Loss를 가장 줄일 수 있는 벡터는 h1,h2,h3중 무엇일까~~요?

S4랑 어떤 단어를 더 가깝게 위치시킬지를 학습시킬까!,

l4 (loss)를 가장 잘 줄이기 위해서, S4랑 어떤 단어를 더 가깝게 놓도록 선형변환해야 좋을까??? 이게 핵심

-> h1이겠지!!!!

그럼 h1에 더 높은 가중치를 주게 되는 것이다!

h1가 가장 높은 가중치를 준 후, c4를 구해 -> s4랑 지지고 볶아서 y hat을 구해. -> 소프트맥스 통과 -> 디코더의 결과

 

또한, Attention과 Transformer를 통해서, Parallelization이 가능해졌다고 한다!

기존의 RNN연산은 구조적으로 Sequential연산 때문에, 병렬처리가 어려워 CPU로만 했어야 했지만, 

Transformer의 등장으로 GPU연산이 가능해졌다고 한다람쥐

 

 

참고1: (혁펜하임) https://www.youtube.com/watch?v=8E6-emm_QVg&t=80s

참고2: https://wikidocs.net/22893

 

15-01 어텐션 메커니즘 (Attention Mechanism)

앞서 배운 seq2seq 모델은 **인코더**에서 입력 시퀀스를 컨텍스트 벡터라는 하나의 고정된 크기의 벡터 표현으로 압축하고, **디코더**는 이 컨텍스트 벡터를 통해서 출력 …

wikidocs.net

참고3:https://velog.io/@sjinu/%EA%B0%9C%EB%85%90%EC%A0%95%EB%A6%AC-Attention-Mechanism

 

[개념정리] Attention Mechanism

Transformer의 기반이 되는 Attention 기법에 대해 정리한 글입니다.

velog.io

 

이번에 살펴본 RNN 구조는 두 개로 나누어, 하나는 인코더, 하나는 디코더로 명명한 후, 두 개의 RNN을 연결해서 사용하는 인코더-디코더 구조이다.

 

해당 인코더-디코더 구조는 "입력 문장"과 "출력 문장"의 길이가 다를 경우에 주로 사용한다.

대표적인 예시로 번역기/텍스트 요약이 있다.

 

(영어 -> 한국어로 번역 시 문장의 길이가 달라질 수 있으므로!

(원본 텍스트 -> 요약 -> 문장 수 감소 {문장 길이 변화})

 

1. 시퀀스-투-시퀀스 (Sequence-to-Sequence, seq2seq)

 

시퀀스-투-시퀀스는 입력된 시퀀스로부터 다른 도메인의 시퀀스를 출력하는 다양한 분야에서 사용된다고 한다. (챗봇, 기계 번역등)

입력 시퀀스와 출력 시퀀스를 각각 질문&대답으로 구성하면 챗봇을 만들 수 있고, 각각 입력 문장&번역 문장으로 만들면

번역기로 만들 수 있는 것이다. 그 외에도 텍스트 요약이니ㅏ STT(speech to text)에서도 쓰일 수 있다고 함.

seq2seq는 번역기에서 대표적으로 사용되는 모델로, 딥 러닝의 '블랙 박스'에서 확대해가는 방식으로 설명한다.

이제 위 그림에서 i am a student에서 프랑스어로 변화하는 내부 과정을 살펴보자.

인코더와 디코더를 통해 변환되는데, 여기서 중요한 포인트가 있다.

인코더는 입력 문장의 모든 단어들을 순차적으로 입력받은 뒤에 마지막에 모든 단어 정보를 압축해서 하나의 벡터로 만드는데, 이를 컨텍스트 벡터라고 한다.

(입력 문장의 정보가 하나의 context vector로 모두 압축 -> 인코더는 context vector를 디코더로 전송! -> 디코더는 입력받은 context vector를 하나씩 순차적으로 출력하는 과정)

 

실제로 사용되는 seq2seq 모델에서는 context vector가 수백개의 차원을 갖고 있다고 한다. (그림에서는 4차원)

또한, 성능 이슈로 인해 실제로는 바닐라 RNN이 아닌, LSTM/GRU 셀로 구성한다고 함!

 

주황색 인코더를 자세히 보면, 입력 문장은 단어 토큰화를 통해서 단어 단위로 쪼개어지고, 단어 토큰 각각은 RNN 셀의 각 시점에서 입력이 된다. 인코더 LSTM 셀은 모든 단어를 입력받은 뒤 인코더 LSTM 셀의 마지막 시점의 은닉 상태를 디코더 RNN 셀로 넘겨주는데, 이게 contexet vector인 것이다! 따라서 context vector는 디코더 RNN 셀의 첫 번쨰 은닉 상태겠지?

 

이제 그림의 디코더의 LSTM 셀을 보면, <sos>라는 심볼을 볼 수 있다.

sos는 초기 입력으로 문장의 시작을 의미하는 심볼이라고 하고, 이게 입력되면 다음에 등장할 확률이 높은 단어를 예측함

여기서는 je라고 예측했다고 볼 수 있다. 그리고 이 je가 다음 셀의 입력으로 들어가서 또 예측을 진행, suis를 결과! (반복)

참고로 이것은 테스트 과정 동안의 프로세스를 나타낸다. 

 

seq2seq는 훈련 과정과 테스트 과정의 작동 방식에 차이가 있다.

 

훈련 과정: context vector와 실제 정답을 동시에 가지므로, 지도 학습 방식을 통해 훈련함! = teacher forcing(교사 학습)

테스트 과정: 훈련 과정과 달리 오직 context vector와 sos 심볼만 입력받은뒤 예측 -> 결과 -> 예측 -> 결과 반복!!

 

알다 시피 기계는 텍스트보다 숫자 연산에 특화되어 있다. NLP는 기본적으로 tetx -> 벡터로 바꾸는 워드 임베딩을 주로 사용하고 있다 즉, seq2seq에서 사용되는 단어들은 모두 임베딩 벡터로 변환 후 입력으로 사용됨. 아래 그림은 임베딩 층임

                                                                   (I, am, a student의 embedding layer)

 

현재 시점을 t라고 할 때, RNN셀은 t-1에서의 은닉 상태와 t에서의 입력 벡터를 입력으로 받고, t에서의 은닉 상태를 만든다.

이때 t에서의 은닉 상태는 바로 위에 또 다른 은닉층이나 출력층이 존재할 경우 위 층으로 보내거나, 필요없다면 무시 할 수있다. 그리고 RNN 셀은 다음 시점에 해당하는 t+1의 셀의 입력으로 현재 t에서의 은닉 상태를 입력으로 보낸다.

 

(현 시점 t의 은닉 상태는 과거 심저의 동일한 RNN 셀에서의 모든 은닉 값들에 영향을 누적해 받아온 값임)

 

2. seq2seq 코드 실습

seq2seq2 모델을 설계하고, teacher forcing을 사용하여 훈련시켜보자.


참고로, vocab size 변수에 대한 정보는 아래 그림과 같다.

 

인코더 코드를 보자.

lstm의 은닉 상태 크기는 256

return_state = True -> 인코더의 내부 상태를 디코더로 넘겨주어야 하기 때문

 

LSTM에서 state_h, state_c를 리턴받는데, 이는 은닉 상태와 셀 상태에 해당한다.

이 두 가지 상태를 encoder_states에 저장한다.

그리고 encoder_states를 디코더에 전달함으로, 두 가지 상태 모두를 디코더로 전달하게 된다,! (이게 context vector)

 

디코더 코드)

디코더는 인코더의 마지막 은닉 상태를 초기 은닉 상태로 사용한다.

위에서 initial_state의 인자값으로 encoder_states를 주는 코드가 이에 해당한다고 볼 수 있다.

또한 동일하게 디코더의 은닉 상태 크기도 256으로 설정

 

 

테스트(activate) 동작 설계

 

디코더를 설계해보자. 

단어로부터 인덱스를 얻는 것이 아니라 인덱스로부터 단어를 얻을 수 있는 index_to_src와 index_to_tar로 만들기

 

sdsd

 

컴퓨터는 텍스트보다는 숫자를 더 잘 처리한다.

이를 위해 자연어 처리에서는 텍스트를 숫자로 바꾸는 여러가지 기법들이 있다. 그리고 그러한 기법들을 본격적으로 적용시키기 위한 첫 단계로 각 단어를 고유한 정수에 맵핑(mapping)시키는 전처리 작업이 필요함.

 

예를 들어 갖고 있는 텍스트에 단어가 5,000개가 있다면, 5,000개의 단어들 각각에 1번부터 5,000번까지 단어와 맵핑되는 고유한 정수. 다른 표현으로는 인덱스를 부여합니다. 가령, book은 150번, dog는 171번, love는 192번, books는 212번과 같이 숫자가 부여됩니다.

인덱스를 부여하는 방법은 여러 가지가 있을 수 있는데 랜덤으로 부여하기도 하지만, 보통은 단어 등장 빈도수를 기준으로 정렬한 뒤에 부여합니다. ("빈도수 기준" -> 허프만 알고리즘 같다.)

 

정수인코딩 = 단어를 정수와 매핑 = 빈도수 기준 ! 

 

1. 정수 인코딩(Integer Encoding)

단어에 정수를 부여하는 방법 중 하나로 단어를 빈도수 순으로 정렬한 단어 집합(vocabulary)을 만들고, 빈도수가 높은 순서대로 차례로 낮은 숫자부터 정수를 부여하는 방법이 있다.

이해를 돕기위해 단어의 빈도수가 적당하게 분포되도록 의도적으로 만든 텍스트 데이터를 가지고 실습해보겠습니다.

예제)

위 코드 -> 문장 단위로 토큰화 수행.

 

이제 앞으로는 정제 작업과 정규화 작업을 병행하며, 단어 토큰화를 수행.

여기서는 단어들을 소문자화하여 단어의 개수를 통일시키고, 불용어와 단어 길이가 2이하인 경우에 대해서 단어를 일부 제외.

텍스트를 수치화하는 단계라는 것은 본격적으로 자연어 처리 작업에 들어간다는 의미이므로, 단어가 텍스트일 때만 할 수 있는 최대한의 전처리를 끝내놓아야 한다는 점이 뽀인뜨

 

이에 따른 단어 토큰화 진행

 

현재 vocab에는 각 단어에 대한 빈도수가 기록되어 있다. 출력해보자.

 

파이썬의 딕셔너리 구조로 단어를 키(key)로, 단어에 대한 빈도수가 값(value)으로 저장되어 있음.

vocab에 단어를 입력하면 빈도수를 리턴.

 

이제 빈도수가 높은 순서대로 정렬해보자.

 

 

높은 빈도수를 가진 단어일수록 낮은 정수를 부여한다! 정수는 1부터 부여

따라서 1의 인덱스를 가지는 단어가 가장 빈도수가 높다는 뜻이다.

스트에서 등장 빈도가 매우 낮은 단어의 경우는 의미가 없을 가능성이 농후하기 때문에, 제외하는 것이 국룰이다.

(등장 빈도가 낮다는 것 = 인덱스 num이 높다는 것!)

 

글 참조 : https://wikidocs.net/31766

 

텍스트 전처리에서 정규 표현식은 아주 유용한 도구입니다. 이번에는 정규 표현식 모듈 re의 사용 방법 & NLTK를 통한 정규 표현식을 이용한 토큰화에 대해서 알아보자.

 

기본적으로 re 모듈에 대한 복습시간이 될 것 같다.

 

1) 정규 표현식 문법

정규 표현을 위해 사용되는 문법 중 특수 문자들은 아래와 같다.

또한, 정규 표현식 문법에는 백슬래쉬를 ( \ ) 이용해서 쓰이는 문자 규칙 또한 존재한다.

2) 정규표현식 모듈 함수

정규표현식 모듈에서 지원하는 함수는 아래와 같다.

 

실습

 

#1 " . "

실습#1

 .(점) 은 한 개의 임의의 문자를 나타다. 예를 들어서 정규 표현식이 a.c라고 합시다. a와 c 사이에는 어떤 1개의 문자라도 올 수 있습니다. akc, azc, avc, a5c, a!c와 같은 형태는 모두 a.c의 정규 표현식과 매치된다고 할 수 있다.

 

#2 " ?  " 기호

?는 ?앞의 문자가 있을 수도, 없을 수도 있는 경우를 말한다. ex) ab?c -> 물음표(?) 앞의 "b"는 슈뢰딩거의 고양이마냥 있을수도, 없을 수 도 있는 것이다. 따라서 abc, ac 모두 가능하다.

 

#3 " * " 기호

 

*은 바로 앞의 문자가 0개 이상일 경우를 나타낸다. 앞의 문자는 존재하지 않을 수도 있으며, 또는 여러 개일 수도 있는 것이다. 만약 정규 표현식이 ab*c라면 ac, abc, abbc, abbbc 등과 매치할 수 있으며 b의 개수는 무수히 많을 수 있다.

?기호에서 존재하는 개수의 제한이 없다는 점이 추가되었다고 볼 수 있다.!

 

#4  " + " 기호

" + " 기호는 " * " 기호와 유사하다고도 볼 수 있다.

다른 점은 앞의 문자가 최소 1개 이상이어야 한다는 점. 정규 표현식이 ab+c라고 한다면 ac는 해당 X.

하지만 abc, abbc, abbbc 등과 매치할 수 있으며 b의 개수는 무수히 많을 수 있습니다.

 

#4  " ^ " 기호

^는 시작되는 문자열을 지정한다.

정규표현식이 ^ab라면 문자열 ab로 시작되는 경우 매치.

 

기타) 자주쓰이는 함수 실습

1) re.split()

파이썬 내장함수인 split메소드와 매우 유사하다.

예제1)

위 방법 말고도, 줄바꿈이나 다른 정규표현을 기준으로 텍스트를 분리할 수 도 있다.

예제2)

 

2) re.findall()

findall() 메소드는  정규 표현식과 매치되는 모든 문자열들을 리스트로 리턴한다.

단, 매치되는 문자열이 없다면 빈 리스트를 리턴.

임의의 텍스트에 정규 표현식으로 숫자를 의미하는 규칙으로, 전체 텍스트로부터 숫자만 찾아내서 리스트로 리턴.

 

 

3) re.sub()

sub() 함수는 정규 표현식 패턴과 일치하는 문자열을 찾아 다른 문자열로 대체할 수 있습니다. 아래와 같은 정제 작업에 많이 사용되는데, 영어 문장에 각주 등과 같은 이유로 특수 문자가 섞여있는 경우에 특수 문자를 제거하고 싶다면 알파벳 외의 문자는 공백으로 처리하는 등의 용도로 쓸 수 있습니다.

 

 

2. 정규 표현식을 이용한 토큰화

RegexpTokenizer()에서 괄호 안에 하나의 토큰으로 규정하기를 원하는 정규 표현식을 넣어서 토큰화를 수행한다. tokenizer1에 사용한 \w+는 문자 또는 숫자가 1개 이상인 경우를 의미.

tokenizer2에서는 공백을 기준으로 토큰화하도록 진행. gaps=true는 해당 정규 표현식을 토큰으로 나누기 위한 기준으로 사용한다는 의미. 만약 gaps=True라는 부분을 기재하지 않는다면, 토큰화의 결과는 공백들만 나오게 된다. tokenizer2의 결과는 위의 tokenizer1의 결과와는 달리 아포스트로피나 온점을 제외하지 않고 토큰화가 수행된 것을 확인할 수 있다.

 

글 참조 :https://wikidocs.net/21703

 

02-05 정규 표현식(Regular Expression)

텍스트 전처리에서 정규 표현식은 아주 유용한 도구입니다. 이번에는 파이썬에서 지원하고 있는 정규 표현식 모듈 re의 사용 방법과 NLTK를 통한 정규 표현식을 이용한 토큰화에 대…

wikidocs.net

 

텍스트 전처리에서 정규 표현식은 아주 유용한 도구입니다. 이번에는 정규 표현식 모듈 re의 사용 방법 & NLTK를 통한 정규 표현식을 이용한 토큰화에 대해서 알아보자.

 

기본적으로 re 모듈에 대한 복습시간이 될 것 같다.

 

1) 정규 표현식 문법

정규 표현을 위해 사용되는 문법 중 특수 문자들은 아래와 같다.

또한, 정규 표현식 문법에는 백슬래쉬를 ( \ ) 이용해서 쓰이는 문자 규칙 또한 존재한다.

2) 정규표현식 모듈 함수

정규표현식 모듈에서 지원하는 함수는 아래와 같다.

 

실습

 

#1 " . "

실습#1

 .(점) 은 한 개의 임의의 문자를 나타다. 예를 들어서 정규 표현식이 a.c라고 합시다. a와 c 사이에는 어떤 1개의 문자라도 올 수 있습니다. akc, azc, avc, a5c, a!c와 같은 형태는 모두 a.c의 정규 표현식과 매치된다고 할 수 있다.

 

#2 " ?  " 기호

?는 ?앞의 문자가 있을 수도, 없을 수도 있는 경우를 말한다. ex) ab?c -> 물음표(?) 앞의 "b"는 슈뢰딩거의 고양이마냥 있을수도, 없을 수 도 있는 것이다. 따라서 abc, ac 모두 가능하다.

 

#3 " * " 기호

 

*은 바로 앞의 문자가 0개 이상일 경우를 나타낸다. 앞의 문자는 존재하지 않을 수도 있으며, 또는 여러 개일 수도 있는 것이다. 만약 정규 표현식이 ab*c라면 ac, abc, abbc, abbbc 등과 매치할 수 있으며 b의 개수는 무수히 많을 수 있다.

?기호에서 존재하는 개수의 제한이 없다는 점이 추가되었다고 볼 수 있다.!

 

#4  " + " 기호

" + " 기호는 " * " 기호와 유사하다고도 볼 수 있다.

다른 점은 앞의 문자가 최소 1개 이상이어야 한다는 점. 정규 표현식이 ab+c라고 한다면 ac는 해당 X.

하지만 abc, abbc, abbbc 등과 매치할 수 있으며 b의 개수는 무수히 많을 수 있습니다.

 

#4  " ^ " 기호

^는 시작되는 문자열을 지정한다.

정규표현식이 ^ab라면 문자열 ab로 시작되는 경우 매치.

 

기타) 자주쓰이는 함수 실습

1) re.split()

파이썬 내장함수인 split메소드와 매우 유사하다.

예제1)

위 방법 말고도, 줄바꿈이나 다른 정규표현을 기준으로 텍스트를 분리할 수 도 있다.

예제2)

 

2) re.findall()

findall() 메소드는  정규 표현식과 매치되는 모든 문자열들을 리스트로 리턴한다.

단, 매치되는 문자열이 없다면 빈 리스트를 리턴.

임의의 텍스트에 정규 표현식으로 숫자를 의미하는 규칙으로, 전체 텍스트로부터 숫자만 찾아내서 리스트로 리턴.

 

 

3) re.sub()

sub() 함수는 정규 표현식 패턴과 일치하는 문자열을 찾아 다른 문자열로 대체할 수 있습니다. 아래와 같은 정제 작업에 많이 사용되는데, 영어 문장에 각주 등과 같은 이유로 특수 문자가 섞여있는 경우에 특수 문자를 제거하고 싶다면 알파벳 외의 문자는 공백으로 처리하는 등의 용도로 쓸 수 있습니다.

 

 

2. 정규 표현식을 이용한 토큰화

RegexpTokenizer()에서 괄호 안에 하나의 토큰으로 규정하기를 원하는 정규 표현식을 넣어서 토큰화를 수행한다. tokenizer1에 사용한 \w+는 문자 또는 숫자가 1개 이상인 경우를 의미.

tokenizer2에서는 공백을 기준으로 토큰화하도록 진행. gaps=true는 해당 정규 표현식을 토큰으로 나누기 위한 기준으로 사용한다는 의미. 만약 gaps=True라는 부분을 기재하지 않는다면, 토큰화의 결과는 공백들만 나오게 된다. tokenizer2의 결과는 위의 tokenizer1의 결과와는 달리 아포스트로피나 온점을 제외하지 않고 토큰화가 수행된 것을 확인할 수 있다.

 

+ Recent posts