TIL/딥러닝

12월 12일 NLP BOW TF-IDF

monawa 2022. 12. 13.
728x90

 ?? 이미지 데이터를 읽어오면 다차원 형태의 구조로 되어있는데 np.array 형태로 되어있음에도 왜 다시 np.array 로 만들어주었을까요?

 

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

 

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


 

<1004-weather-classification>

  • 실습 1004 의 목적 :
    • tf.kreas의 전처리 기능을 사용하지 않고 이미지 파일을 array 로 직접 만들어 봅니다.
    • 데이터셋(train, valid, test)도 직접 나누어 봅니다.
    • CNN 네트워크 구성 응용, 학습과 예측해 보기1

 

정답 인코딩이 제대로 되었는지 확인하고 클래스가 train, valid 균일하게 나뉘었는지 확인했습니다.

lb.classes_

# 예측값의 종류별 빈도수 입니다. 250~250 개 사이에 빈도수가 분포되어 있습니다.
np.argmax(y_train, axis=1)

y_train_raw

# 정답 인코딩이 제대로 되었는지 확인하고 클래스가 train, valid 균일하게 나뉘었는지 확인했습니다
# pd.Series 형태로 구성해 준 이유는 np.array 형태이기 때문에 
# 판다스 메서드를 사용하기 위해 Series 형태로 변경해 주었습니다.


pd.Series(y_train_raw).value_counts(1)

 

아래 코드에서 정답값을 균일하게 나누기 위해 사용하는 train_test_split 의 옵션은 무엇일까요???

 

# train_test_split
# fit을 할 때 validation_split 으로 나눠도 상관 없습니다.
# class 가 균일하게 나뉘지 않아서 학습이 불균형하게 되는 문제가 있습니다.
# valid 데이터를 직접 나눠 넣어주면 좀 더 잘 학습니다.
from sklearn.model_selection import train_test_split

x_train_raw, x_valid_raw, y_train_raw, y_valid_raw = train_test_split(
    x_train_arr, y_train_arr, test_size=0.2, stratify=y_train_arr, random_state=42)

x_train_raw.shape, x_valid_raw.shape, y_train_raw.shape, y_valid_raw.shape

stratify=y

 

validation_split 을 사용하지 않고 위에서 따로 validation_data를 나눠서 사용한 이유는 class 를 stratify 로 층화표집을 해주지 않으면 균일하게 학습이 되지 않는다. 멀티클래스일 때 데이터를 따로 균일하게 나눠서 학습시키지 않으면 성능이 낮게 나올 때가 많다.

 

df_hist[["loss","val_loss"]].plot()

해당 시각화를 봤을떄  오버피팅이 되어있습니다!

#### ✅테스트 이미지 시각화
* 주의할 점 : test 의 인코딩 값 순서와 train, valid 에서 사용한 순서가 맞는지 확인이 필요.
* 예를 들어  train 의 0 은 cloudy 인데 test 는 rain 이 아닌지 확인해볼 필요가 있음.

* 목적 : 전체 테스트 이미지 시각화 => 어떤게 맞았는지 틀렸는지
* 서브플롯으로 30개 이미지를 한번에 시각화를 하려면 row, col 을 구해서 해당 위치에 이미지를 넣어주어야 함.
* 이미지를 여러 개 시각화 했을 때 알아서 위치에 들어가지 않기 때문에 어떤 위치.
* 이미지의 주소를 지정해 준다고 생각하면 된다.

* 정답이 있는 test.csv 파일을 읽으면 파일이름과 정답이 있다.
* test.csv 순서대로 이미지를 가져와서 일단 먼저 시각화 하고 예측값과 비교해서 맞았는지 틀렸는지를 보기
[ 전체 Code ]
class_name = lb.classes_
fig, axes = plt.subplots(nrows=6, ncols=5, figsize=(20, 20))
for i, tcsv in test.iterrows():
col = i % 5
row = i // 5
Image_id = tcsv["Image_id"]
img_label = tcsv["labels"]
img = plt.imread(f"{root_dir}/alien_test/{Image_id}")
axes[row, col].imshow(img)
if img_label==y_predict[i]:
axes[row, col].set_title(
f"test: {class_name[img_label]}, predict : {class_name[y_predict[i]]}",
color = "blue")
else:
axes[row, col].set_title(
f"test: {class_name[img_label]}, predict : {class_name[y_predict[i]]}",
color = "red")

accuracy와 val_accuracy 혹은 loss와 val_loss가 대략 어느정도 차이나면 오버피팅이라 그러나요!?

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

성능 개선방법!

  1. Conv, Pooling Layer 의 층을 더 쌓는다든지 파라미터 값을 변경
  2. compile 설정을 변경해
  3. fit 의 설정 값도 변경
  4. 물론 이미지 사이즈나 이미지 전처리를 하면 더 나은 성능을 내지만
  5. fit(학습)속도를 빠르게 하기 위해 기존 사이즈로 진행하겠습니다.
  6. compile 설정 값 변경

 


지금까지 배운 CNN정리

1. MNIST, FMNIST, cifar10, 말라리아 혈액도말 이미지, 날씨이미지 를 통해 이미지 분류 실습을 알아보았습니다.

2. CNN Explainer 를 통해 Conv, Pooling 과정을 이미지로 이해해 봤습니다.

3. ??왜 완전밀집연결층을 첫 레이어 부터 사용하지 않고 합성곱 연산을 했을까요??

  • FC Layer는 flatten이 필요하기 때문에 지나치게 계산이 복잡해지고, 공간정보가 많이 손실됩니다.
  • 완전밀집연결층은 flatten해서 이미지를 입력해주는데 그러면 주변 이미지를 학습하지 못 하는 문제가 생깁니다.
    • 합성곱 연산은 array로 입력하고 출력층에서 flatten해서 결과를 출력
    • 완전밀집연결층은 flatten해서 이미지를 입력해주는데 그러면 주변 이미지를 학습하지 못 하는 문제가 생긴다
    • (합성곱을 하면 3D => 2D 로 변경됩니다.
      합성곱은 1D, 2D, 3D 등의 기능을 제공합니다.
      텍스트 데이터는 1D로 넣어주고 주변 문맥을 학습하게 합니다.)

4. 기존에 사용했던 DNN 에서 배웠던 개념을 확장해서 합성곱 이후 완전연결밀집층을 구성하는 형태로 진행해 봤습니다.

5. 이미지 전처리 도구는 matplotlib.pyplot 의 imread 를 통해 array 로 읽어올 수도 있고, PIL, OpenCV를 사용할 수도 있습니다.

6. 이미지 증강 기법 등을 통해 이미지를 변환해서 사용할 수도 있습니다.


이번주 진행 주제 :

<텍스트 분석과 자연어처리>

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

 

자연어 처리(NLP)

: 자연어의 의미를 분석하여 컴퓨터가 처리할 수 있도록 하는 일

 

NLP로 할수 잇는일

음성 인식, 내용 요약, 번역, 감성 분석, 텍스트 분류 작업, 챗봇

 

사이킷런으로 자연어 처리 활용하기

  • [분류] 스팸 메일 / 뉴스 기사 분류
  • [회귀] 뉴스기사로 주가 예측
  • [군집화] 고객센터 비슷한 문의 모으기
  • [차원축소] 시각화

머신러닝을 활용한 자연어 분류 과정

데이터 로드 => 텍스트 데이터 전처리 => 데이터 나누기  => 텍스트 데이터 벡터화 => 모델에 학습 및 예측, 평가

텍스트 데이터 벡터화 :기계가 이해할 수 있는 수치 형태로 텍스트를 변환

 

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

인코딩(원핫, ordinary)해 줬습니다

 

Q. 텍스트는 영어로 학습한 내용을 한국어로 예측하면 성능이 어떻게 될까요?

정확도가 굉장히 떨어짐


  • 정규표현식 
    • 정규표현식 ⇒ 문자, 숫자를 제외한 특수문자를 제외할 때 주로 사용합니다. 특정 패턴으로 텍스트 전처리 시에도 사용합니다. 정규표현식은 그 자체로 프로그래밍 언어입니다.
    • regular expression => 학교마다 차이가 있지만 보통 대학에서 배우면 한 학기동안 배우기도 합니다. 한 과목으로 되어있기도 합니다.
    • 정규표현식 위키백과: https://ko.wikipedia.org/wiki/정규_표현식
      ⇒ 정규 표현식은 많은 텍스트 편집기와 프로그래밍 언어에서 문자열의 검색과 치환을 위해 지원하고 있다.
  • 데이터 정체 및 전처리 (텍스트 처리에서)
    • 기계가 텍스트를 이해할 수 있도록 텍스트를 정제하여 신호와 소음을 구분
    • 이상치로 인한 과대적합 방지

 

Q. 정규표현식 [0-9] 는 무엇을 의미할까요?

모든 숫자를 가져온다

Q 정규표현식 [^0-9] 는 무엇을 의미할까요?

모든 숫자를 제외한것

 

토큰화

텍스트 조각 => 토큰이라고 하는 더 작은 단위로 분리

(특정 문자(예. 띄어쓰기, 공백)으로 텍스트 데이터를 나눠주는것)

 

- 머신러닝에서 binning과 같은 효과가 있다. -

 

패턴을 찾는데 매우 유용하며 형태소 분석 및 표제어를 위한 기본 단계로 간주

 

Q 했다. 했어요. 했습니다. 했나요? 하다 ⇒ 하다로 통일해서 변형해 주면 어떤 효과가 있을까요?

  • 비슷한 의미의 단어를 하나로 전처리해서 나중에 벡터화(인코딩을) 했을 때 데이터의 용량을 줄이고 모델에게 힌트도 줄 수 있겠죠.
    • 머신러닝에서 binning과 같은 효과가 있다
  • 실습에서는 KoNLPy 를 사용할 예정입니다. 지원하는 형태소 분석기도 있고 그렇지 않은 형태소 분석기도 있습니다.
    • KoNLPy 는 박사학위 논문으로 만들었던 도구 입니다. 자바, C, C++ 등으로 만들어진 형태소 분석기를 파이썬으로 사용할 수 있게 연결해 주는 도구입니다.
    • 파이썬은 접착제 언어이기 때문에 다른 언어로 만들어진 형태소 분석기를 파이썬으로 래핑해서 사용할 수 있게 해주는 도구 입니다.

 


<1101-BOW-tfidf>

목표 : BagOfWords,TF-IDF ⇒ 단어를 숫자로 인코딩 하는 방법에 대해 알아보겠습니다. (scikit-learn시용)

 

빈도 기반 워드 임베딩

  • 원핫인코딩: 텍스트 데이터, 범주형 데이터 -> 수치형 데이터로 변경 : 머신러닝이나 딥러닝은 수치로된 데이터만 이해하므로 벡터에서 해당되는 하나의 데이터만 1로 변경하고 나머지는 0ㅇ으로 채움

 

  • BOW(bag of words)
    ⇒ 가장 간단하지만 효과적이라 널리쓰이는 방법
    • 장, 문단, 문장, 서식과 같은 입력 텍스트의 구조를 제외하고 각 단어가 이 말뭉치에 얼마나 많이 나타나는지만 헤아림
    • 구조와 상관없이 단어의 출현횟수만셈
      때문에 텍스트를 담는 가방(bag)으로 생각할 수 있습니다.
    • BOW는 단어의 순서가 완전히 무시 된다는 단점이 있다.

      이를 보완하기 위해 n-gram을 사용하는 데 BOW는 하나의 토큰을 사용하지만 n-gram은 n개의 토큰을 사용할 수 있도록 합니다.
      • N_gram 언어모델: 모든 단어를 고려하는 것이 아니라 일부 언어만 고려하여 접근하는 방법, n개만큼 묶어서 사용함. 앞뒤 맥락을 조금 더 보전할 수 있음
        => 문서 단어 행렬(DTM: Document-Term Matrix)
    • min_df는 문서에 특정 단어가 최소 몇 번 이상 문서에 등장하는 단어를 가방에 담겠다는 의미
예시문장  토큰화 백터화
(1) 동물원에 버스를 타고 갔다.
(2) 동물원에서 사자를 봤다.
(3) 동물원에서 기린을 봤다.
["동물원에" ,"동물원에서", "버스를","사자를","기린을","타고",갔다",봤다" (1)[1,0,1.0.0.1.1.0]
(2)[0.1.0.1.0.0.0.1]
(3)[0.1.0.0.1.0.0.1]
  • CountVectorizer
    ⇒ 사이킷런에서 제공하는 bag of words 를 만들 수 있는 방법
    • 텍스트 문서 모음을 토큰 수의 행렬로 변환합니다.
    • 단어들의 카운트(출현 빈도)로 여러 문서들을 벡터화
    • 문서목록에서 각 문서의 feature(문장의 특징) 노출수를 가중치로 설정한 BOW 벡터를 생성
    • 카운트 행렬, 단어 문서 행렬 (Term-Document Matrix, TDM))
    • max_df, min_df 인수를 사용하여 문서에서 토큰이 나타난 횟수를 기준으로 단어장을 구성할 수도 있음
    • 토큰의 빈도가 max_df로 지정한 값을 초과 하거나 min_df로 지정한 값보다 작은 경우에는 무시하며 인자 값은 정수인 경우 횟수, 부동소수점인 경우 비율을 의미
      • 매개변수 
        • 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 : 불용어 정의
from sklearn.feature_extraction.text import CountVectorizer

cvect = CountVectorizer()
dtm = cvect.fit_transform(corpus) -> fit하고 transform 해주기

vocab = cvect.get_feature_names_out()
->단어 사전 보기

cvect.vocabulary_
-> 단어사전 {'단어':인덱스번호}로 보기

df_dtm = pd.DataFrame(dtm.toarray(), columns=vocab)
df_dtm

문서 빈도가 주어진 임계값보다 낮은 용어는 무시하여, 희귀단어나 오타를 제외하는 효과가 있는것은?

  • min_df

문서 빈도가 주어진 임계값보다 높은 용어는 무시하여 많이 등장하는 불용어를 제외하는 효과가 있는 것은 무엇일까요?

  • max_df

BOW를 사용하다보면 앞뒤 맥락을 고려하지 않는 단점이 있습니다. 이것을 해결하기 위한 것은 무엇일까요?

  • ngram_range

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

  • max_features
  min_df max_df
정수(int)
빈도수의미
 
빈도수로 해당 빈도 이상인 단어만 사용

예) 2라면 한 번만 등장하는 단어는 제외
빈도수로 해당 빈도 이하까지 사용

예) 100이라면 101번이상 등장하는 단어 제외
실수(float)
빈도비율의미
해당 비율 이하로 등장하는 단어는 제외

예) 0.1이라면 10% 이상 등장하는 단어를 사용
해당비율 이상으로 등장하는 단어는 제외

예) 0.9라면 90%까지 등장하는 단어만 사용
효과  오타, 희귀 단어 제거 효과 너무 자주 등장하지만 큰 의미가 없는
불용어 제거 효과

 
 

참고자료 :

멋쟁이 사자처럼 AI School 7기 박조은님 수업내용

728x90

댓글