[AIS7] DL (7) & NLP (1)

BBakHye·2022년 12월 12일
0

🦁 AI SCHOOL 7기

목록 보기
44/52
post-thumbnail

💡 이번주 진행 주제 : 텍스트 분석과 자연어처리

  • CNN은 주로 이미지에 주로 사용이되고 물론 텍스트에도 사용을 합니다. 하지만 이미지에서 더 나은 성능을 보여줍니다.
  • 텍스트 분석을 할 때 머신러닝(Bag Of Words, TF-IDF), 딥러닝(RNN) 순서로 사용할 예정입니다.
    텍스트 분류, 텍스트로 주식의 가격을 예측하는 회귀 모델을 만든다든지 할 때는 주로 RNN이 CNN 보다 더 나은 성능을 내는 편입니다. RNN은 주로 순서가 있는 데이터에 사용합니다. 예를 들어 시계열데이터, 자연어도 말의 앞뒤에 순서가 있기 때문에 시계열, 자연어 등에 사용됩니다.
  • 자연어처리 실습 이후에는 RNN 으로 시계열 데이터를 다뤄볼 예정입니다.

1004 실습

🤔 정답값을 균일하게 나누기 위해 사용하는 train_test_split 의 옵션은 무엇일까요?
stratify=y

📌 Compile

모델을 훈련하기 전에 필요한 몇 가지 설정이 모델 컴파일 단계에서 추가됩니다:

  • 옵티마이저(Optimizer) - 데이터와 손실 함수를 바탕으로 모델의 업데이트 방법을 결정합니다.
  • 지표(Metrics) - 훈련 단계와 테스트 단계를 모니터링하기 위해 사용합니다. 다음 예에서는 올바르게 분류된 이미지의 비율인 정확도를 사용합니다.
  • 손실 함수(Loss function) - 훈련 하는 동안 모델의 오차를 측정합니다. 모델의 학습이 올바른 방향으로 향하도록 이 함수를 최소화해야 합니다. 최적의 가중치를 찾도록 해야함
    • 회귀 : MSE, MAE
    • 분류 :
      • 바이너리(예측할 값의 종류가 둘 중 하나) :
        • binary_crossentropy
      • 멀티클래스(예측할 값의 종류가 2개 이상) :
        • categorical_crossentropy(one-hot형태의 클래스 예: [0, 1, 0, 0])
        • sparse_categorical_crossentropy(정답값이 0, 1, 2, 3, 4 와 같은 형태일 때)

다중분류에서 손실함수는 훈련데이터의 라벨이 원핫벡터의 경우에는 categorical_crossentropy
라벨이 정수(int)의 형태인 경우에는 sparse_categorical_crossentropy를 사용해보실 수 있습니다

🤔 왜 완전밀집연결층을 첫 레이어 부터 사용하지 않고 합성곱 연산을 했을까요?
완전밀집연결층은 flatten해서 이미지를 입력해주는데 그러면 주변 이미지를 학습하지 못 하는 문제가 생깁니다. 합성곱, 풀링 연산으로 특징을 학습하고 출력층에서 flatten해서 완전연결밀집층에 주입해 주고 결과를 출력합니다.

✅ CNN Summary

1) MNIST, FMNIST, cifar10, 말라리아 혈액도말 이미지, 날씨이미지 를 통해 이미지 분류 실습을 알아보았습니다.
2) CNN Explainer 를 통해 Conv, Pooling 과정을 이미지로 이해해 봤습니다.
3) 기존에 사용했던 DNN 에서 배웠던 개념을 확장해서 합성곱 이후 완전연결밀집층을 구성하는 형태로 진행해 봤습니다.
4) 이미지 전처리 도구는 matplotlib.pyplot 의 imread 를 통해 array 로 읽어올 수도 있고, PIL, OpenCV를 사용할 수도 있습니다.
5) 이미지 증강 기법 등을 통해 이미지를 변환해서 사용할 수도 있습니다.

자연어 처리 (Natural Language Processing)

🤔 머신러닝에서 텍스트로 된 카테고리 범주 값을 어떻게 처리 했을까요?
인코딩

📌 자연어 처리로 할 수 있는 일

📌 데이터 정제 및 전처리

  • HTML 태그, 특수문자, 이모티콘
  • 정규표현식
  • 불용어 (큰 의미는 없지만 빈도수가 많은 것. 예) 그리고, 그런데 ...)
  • 어간 추출 (원형 보존 X)
  • 음소표기법 (원형 보존)

📌 정규표현식 (Regular Expression)

: 문자, 숫자를 제외한 특수문자를 제외할 때 주로 사용합니다. 특정 패턴으로 텍스트 전처리 시에도 사용합니다. 정규표현식은 그 자체로 프로그래밍 언어입니다.

🤔 정규표현식 [0-9] 는 무엇을 의미할까요?
모든 숫자를 의미

🤔 정규표현식 [^0-9] 는 무엇을 의미할까요?
모든 숫자를 제외

[정규 표현식] https://ko.wikipedia.org/wiki/%EC%A0%95%EA%B7%9C_%ED%91%9C%ED%98%84%EC%8B%9D

1101 실습

💡 1101 번의 실습 목표 : BagOfWords, TF-IDF (단어를 숫자로 인코딩 하는 방법)

토큰화 => 특정 문자(예. 띄어쓰기, 공백)로 텍스트 데이터를 나눠주는 것
NLTK, Spacy 도 대표적인 텍스트 전처리 도구이며, 토큰화, stemming, lematization 등의 기능을 제공합니다.
하지만 한글을 지원하지 않아서 실습에서 사용하지 않겠습니다. 실습에서는 KoNLPy 를 사용할 예정입니다. 지원하는 형태소 분석기도 있고 그렇지 않은 형태소 분석기도 있습니다.

KoNLPy 는 박사학위 논문으로 만들었던 도구 입니다. 자바, C, C++ 등으로 만들어진 형태소 분석기를 파이썬으로 사용할 수 있게 연결해 주는 도구입니다.
파이썬은 접착제 언어이기 때문에 다른 언어로 만들어진 형태소 분석기를 파이썬으로 래핑해서 사용할 수 있게 해주는 도구 입니다.

🤔 "했다." "했어요." "했습니다." "했나요?" "하다." 를 "하다."로 통일해서 변형해 주면 어떤 효과가 있을까요?
비슷한 의미의 단어를 하나로 전처리해서 나중에 벡터화(인코딩을) 했을 때 데이터의 용량을 줄이고 모델에게 힌트를 줄 수 있다

📌 Bag of Words

  • BOW(bag of words)
    • 가장 간단하지만 효과적이라 널리쓰이는 방법
    • 장, 문단, 문장, 서식과 같은 입력 텍스트의 구조를 제외하고 각 단어가 이 말뭉치에 얼마나 많이 나타나는지만 헤아립니다.
    • 구조와 상관없이 단어의 출현횟수만 세기 때문에 텍스트를 담는 가방(bag)으로 생각할 수 있습니다.
    • BOW는 단어의 순서가 완전히 무시 된다는 단점이 있다. 예를 들어 의미가 완전히 반대인 두 문장이 있다고 합니다.
      • it's bad, not good at all.
      • it's good, not bad at all.
    • 위 두 문장은 의미가 전혀 반대지만 완전히 동일하게 반환됩니다.
    • 이를 보완하기 위해 n-gram을 사용하는 데 BOW는 하나의 토큰을 사용하지만 n-gram은 n개의 토큰을 사용할 수 있도록 합니다.
    • min_df는 문서에 특정 단어가 최소 몇 번 이상 문서에 등장하는 단어를 가방에 담겠다는 의미입니다.

📌 CountVectorizer

  • CountVectorizer 는 사이킷런에서 제공하는 bag of words 를 만들 수 있는 방법입니다.
  • 텍스트 문서 모음을 토큰 수의 행렬로 변환합니다.
  • 단어들의 카운트(출현 빈도)로 여러 문서들을 벡터화
  • 문서목록에서 각 문서의 feature(문장의 특징) 노출수를 가중치로 설정한 BOW 벡터를 생성
  • 카운트 행렬, 단어 문서 행렬 (Term-Document Matrix, TDM))
  • max_df, min_df 인수를 사용하여 문서에서 토큰이 나타난 횟수를 기준으로 단어장을 구성할 수도 있음
  • 토큰의 빈도가 max_df로 지정한 값을 초과 하거나 min_df로 지정한 값보다 작은 경우에는 무시하며 인자 값은 정수인 경우 횟수, 부동소수점인 경우 비율을 의미
  • API documentation: https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html

✅ 사용법

  1. 문서를 토큰 리스트로 변환한다.
  2. 각 문서에서 토큰의 출현 빈도를 센다.
  3. 각 문서를 BOW 인코딩 벡터로 변환한다.
  4. 매개 변수
    • analyzer : 단어, 문자 단위의 벡터화 방법 정의
    • ngram_range : BOW 단위 수 (1, 3) 이라면 1개~3개까지 토큰을 묶어서 벡터화
    • max_df : 어휘를 작성할 때 문서 빈도가 주어진 임계값보다 높은 용어(말뭉치 관련 불용어)는 제외 (기본값=1.0)
      • max_df = 0.90 : 문서의 90% 이상에 나타나는 단어 제외
      • max_df = 10 : 10개 이상의 문서에 나타나는 단어 제외
    • min_df : 어휘를 작성할 때 문서 빈도가 주어진 임계값보다 낮은 용어는 제외합니다. 컷오프라고도 합니다.(기본값=1.0)
      • min_df = 0.01 : 문서의 1% 미만으로 나타나는 단어 제외
      • min_df = 10 : 문서에 10개 미만으로 나타나는 단어 제외
    • stop_words : 불용어 정의

🤔 N-grams 은 왜 사용할까요?
BOW 의 앞뒤 맥락을 고려하지 않는다는 단점을 해결하기 위해

🤔 너무 희귀한 단어를 제외하는 효과가 있는 것은 무엇을까요?
min_df

🤔 너무 많이 등장하는 불용어를 제외하는 효과가 있는 것은 무엇일까요?
max_df

🤔 단어를 너무 많이 사용해서 dtm 가 너무 커지는 것을 방지하기 위해 최대 단어를 제한하는 것은 무엇일까요?
max_features

📌 N-grams

  • 토큰을 몇 개 사용할 것인지를 구분합니다. 지정한 n개의 숫자 만큼의 토큰을 묶어서 사용합니다.
  • 예를 들어 (1, 1) 이라면 1개의 토큰을 (2, 3)이라면 2~3개의 토큰을 사용합니다.
  • analyzer 설정에 따라 단어단위, 캐릭터 단위에 따라 사용할 수 있습니다.
  • 기본값 = (1, 1)
  • ngram_range(min_n, max_n)
  • min_n <= n <= max_n

💡 TF-IDF 전체 문서에서는 자주 등장하지 않지만 특정 문서에서 자주 등장한다면 가중치 값이 높게 나오게 됩니다. 모든 문서에 자주 등장하는 값은 가중치가 낮게 나오게 됩니다.


🙋🏻‍♀️ 질문

Q: 이미지 데이터를 읽어오면 다차원 형태의 구조로 되어있는데 np.array 형태로 되어있음에도 왜 다시 np.array 로 만들어주었을까요?
A: 리스트 안에는 np.array 로 되어있더라도 여러 장의 이미지를 하나로 만들 때 파이썬 리스트에 작성해 주었습니다. 그래서 이미지 여러 장을 하나의 변수에 넣어주었을 때 해당 변수의 데이터 타입은 파이썬 리스트 구조입니다. train_test_split에 사용하기 위해, 계산의 편의를 위해 넘파이 형태로 변경해 주었습니다.

Q: 영어나 다른 외국어는 불용어 사전을 NLTK, Spacy 등에서 제공합니다. 하지만 한국어는 불용어 사전이 따로 없습니다. 왜 그럴까요?
A: 정답이 따로 있지는 않습니다. 한국어는 맥락에 따라 복잡하고 다양한 의미를 갖고 또 도메인마다의 불용어가 다 다릅니다. 예를 들어 코로나 치료제 관련 논문을 연구 한다면 코로나 라는 단어는 불용어가 되겠죠. 예를 들어 파이썬 문서를 본다라고 했을 때 파이썬 문서에서도 파이썬이라는 단어는 불용어가 되겠죠.


🦁 질문

Q: accuracy와 val_accuracy 혹은 loss와 val_loss가 대략 어느정도 차이나면 오버피팅이라 하나요?
A: 시각화를 해보는게 좀 더 직관적으로 볼 수 있는데 더 이상 val_loss 값이 감소하지 않는데, loss 값은 줄어든다면 오버피팅 되었다고 판단하는게 나아보이며, 딱 수치가 얼마가 차이가 나면 오버피팅이다 이렇게 공식으로 얘기는 잘 하지 않는 편입니다. val_loss 값이 나아지지 않는데 loss 값만 나아진다면 확실하게 오버피팅이라고 볼 수 있을것 같습니다.


✏️ TIL

  • 사실(Fact): 자연어처리에 대해 배웠다.
  • 느낌(Feeling): 와, 진짜 헷갈린다.
  • 교훈(Finding): 새로운 개념은 꾸준한 복습으로 이해하자.
profile
데이터 분석가가 되기 위한 기록 ✏️

0개의 댓글