반응형

K-means Clustering

K-means Clustering은 비지도 학습 기반의 Clustering 기법으로, 데이터를 Clustering하는 문제가 있으면, 가장 쉽게 연상되는 알고리즘이다. 워낙 많이 사용되어, 많이들 알고 있겠지만, K-means Clustering의 특징과 단계를 조금 더 자세히 알아보기로 한다. 


K-means Clustering 이란?

  • K-means Clustering은 데이터를 K개의 군집으로 나누기 위한, 거리 기반 Clustering 알고리즘이다.
  • K-means Clustering은 같은 집단 내 데이터들은 비슷한 특징을 가지고 있고, 다른 집단의 데이터와는 데이터적으로 상반된 특징을 가지고 있다는 것을 가정한다. 즉, 동일 집단의 군집화를 고려하는 것 뿐만 아니라, 타집단과의 관계도 고려한다. 
  • K-means Clustering은 간단하고, 빠르고, 성능도 좋은 편이기 때문에 비지도 학습 기반 이미지 분류나 데이터 마이닝, 이상점 탐지등에서도 자주 활용된다.

K-means Clustering의 특징

장점

1. 간단하고, 해석이 쉽다.

  • K-means Clustering 알고리즘은 거리 기반 알고리즘이기 때문에, 복잡한 연산을 포함하지 않는다. 따라서, 구현도 매우 쉬운편이고, 수행 시간도 빠르다. 또한, 거리 기반 알고리즘이기 때문에, 해석이 매우 용이하다. (같은 Cluster면, 거리가 가깝고, 다른 Cluster면 거리가 멀다.)

2. 성능이 좋다.

  • Clustering 문제에서 성능이 좋다라는 기준은 애매하지만, 일반적으로 좋은 성능을 보인다.

3. 연구가 많이 되었다.

  • 쉽고, 해석력이 높은 알고리즘이기 때문에, 다양한 분야에서 많이 활용 및 연구되었고, 개선되었다. 분석하고자 하는 데이터의 특성을 당장 알 수 없을때, 비슷한 분야에서  K-means Clustering 알고리즘을 활용한 연구들을 참고하기 쉽다.(중심점을 어디에 찍어야할지, 군집은 몇개로 나눌지 등등)

단점

1. 초기 값 의존도가 높다.

  • 초기 값(centroid)를 어떻게 설정하냐에 따라, Clustering 결과가 매우 다르다. 특히, 초기 값이 적절하게 설정되지 않으면, Local Optimum으로 수렴되어, 초기에 원하지 않는 Clustering 모양이 될 수 있다. 이러한 문제는 분류해야하는 Cluster의 대략적인 모습을 알 수 없을때는 치명적으로 작용한다. (Local Optimum을 Global Optimum으로 착각할 수 있어서)   

2. Cluster의 개수를 미리 알아야한다.

  • K-means Clustering이 매우 좋은 알고리즘임에도 불구하고, 가장 큰 단점이 있다면, Cluster 개수를 미리 알아야한다는 것이라고 생각된다. 실제 데이터에서 Cluster 개수를 미리 알기 어렵기 때문에(아직 특징을 모르거나, 사전에 이론적으로 정의한 K개의 Cluster가 실제 데이터에 모두 포함되지 않을 가능성도 있기 때문에), k-mean clustering을 단독으로 사용하기 어려운 약점이 된다. 

3. Cluster의 형태가 arbitrary한 경우 Clustering이 어렵다.

  • Distance 기반으로 Clustering하기 때문에, 일반적으로 구형의 모양이 된다. (Euclidean 거리 사용시)
  • 아래와 같이, Clustering 하고자 하는 데이터 분포가 구형 모양이 아니면,  의도한 Clustering 결과와 다르게 분류가 될 수 있다. 

4. Outlier에 민감한 편이다.

  • K-means Clustering은 Outlier에 민감한 편이다. 특히, Outlier가 centroid로 선택되면, 이상한 Clustering 결과가 될 수 있다. 
전체적으로, K-means Clustering은 간단하고, 좋은 해석력과 빠른 속도, 높은 성능등을 가지고 있지만, 몇가지의 단점이 존재하여, 단점들이 개선된 알고리즘이나, Outlier 제거 등의 다른 기법들과 함께 활용된다. 

 

K-means Clustering 알고리즘

K-means Clustering은 centroid를 설정하고, 데이터의 Cluster 할당 과정을 반복해가면서, Clustering을 수행한다.

 

1. 초기 centroid 설정

  •  K-means Clustering에서 초기의 centroid를 잡는 것은 매우 중요하다. (잘못 설정 시, Local minimum에 빠질 수 있고, 수렴 속도도 느릴 수 있다.)
  • K-means Clustering의 cetroid를 설정하는 방법은 크게 3가지 방법이있다.

1) Random : 데이터 포인트 중, K개를 뽑아서, centroid로 지정한다. 

2) Hierarchical clustering : Hierarchical clustering 같은 다른 clustering 방법을 사용하여, centroid에 대한 hint를 얻는다.

3) K-means++ : K-means Clustering의 초깃값을 더 효율적으로 찾기 위해, 몇가지 단계를 수행한다. (Sklean default 방법)

  • 1개의 centroid를 무작위로 뽑는다.
  • 데이터포인트들과 centroid 간의 거리를 계산한다.
  • 각 데이터 포인트와 centroid 간 거리의 제곱을 확률로 하여, 다음 cluster의 centroid를 뽑는다. (거리가 멀수록, 다음 cluster로 뽑히는 확률이 높다는 의미)
  • K개의 centroid가 만들어질때까지 반복한다.

→ 보통은 K-means++ 알고리즘을 많이 사용하지만, 계산 비용이 추가적으로 든다는 점과, 맨 처음 centroid가 이상치를 선택하게 되면, cluster 모양이 이상해진다는 점 등의 단점도 존재한다. 따라서, 데이터의 중심을 추정이 가능하다면, 직접 설정하는 것도 좋은 방법이다. 

 

2. 각 데이터 포인트와 centroid 거리 측정 & Cluster 할당

K-menas Clustering 식

  • K-means Clustering의 수식은 위와 같다. 즉, K개의 centroid 들 중, 현재 point와 거리가 가장 가까운 centroid가 형성하는 cluster에 데이터가 포함한다. 
  • 거리를 구하는 방법은 지정하기 나름이지만, 보통 유클리디안 거리를 사용한다.

3. centroid 업데이트 

centroids update 식

  • 새로운 centroid로는 2번에서 할당한 cluster들의 평균 값을 활용한다. 
  • 새로운 centroid는 2번에 할당된 cluster의 중간으로 이동할 것이다.

 

4. 2~3 단계를 반복

  • 수렴할때까지, cluster 할당, centroid 업데이트를 반복한다.

K-means Clustering Python 구현

  • scikit-learn의 KMeans를 사용하면 쉽게 사용 가능하다.
import numpy as np
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs

if __name__ == '__main__':
    X, y = make_blobs(n_samples=1000, centers=5, random_state=10, cluster_std=2) # 데이터 생성

    kmeans = KMeans(n_clusters=5, init=rand_array, n_init=1, max_iter=100)
    kmeans.fit(X)

    kmeans.labels_ # 학습에 활용된 데이터의 cluster를 예측
    kmeans.predict(X) # 임의의 point가 어느 cluster에 포함되는지 예측
    kmenas.transform(X) # 임의의 point와 할당된 cluster의 centroid 간의 거리를 구함
  • n_clusters : 클러스터 개수 (*hyper-parameter)
  • init : 초깃값 설정 방법, 'k-means++', 'random', numpy_array(centroid를 직접 지정해줄 때) ,default는 k-means+
  • max_iter : 2~3 단계 최대 반복 횟수 (default:300)
  • random_state : k-means++ 등에서 무작위성을 제어하기 위한 시드 값, 재현을 위해 설정이 필요함
  • algorithm : k-means clustering 데이터 계산 시, 어떤 알고리즘을 사용할 것인지, 'auto', 'full', 'elkan'이 있다. full은 모든 데이터를 2~3 단계에서 활용하는 것이고, elkan은 데이터 연산 부하를 줄이기 위해, 불필요한 연산을 줄이는 방법이다. auto는 데이터 크기와 특징에 따라, 자동으로 설정해줌
  • metric : 거리 측정 방식, 'euclidean', 'manhattan', 'cosine', 'l1', 'l2', 'manhattan_l1', 'manhattan_l2' 등이 있음 (default : euclidean, 사용자 지정 함수도 활용 가능) 
반응형

GMM (Gaussian Mixture Model) Clustering


GMM Clustering은 Clustering 문제에서 각 Cluster에 포함될 확률이 포함될 때, 자주 사용하는 알고리즘이다. 대략적인 컨셉만 알고 쓰고 있지만, 조금 더 자세히 알아보고 싶었다.

GMM 이란?

  • GMM(Gaussian Mixture Model) Clustering은 어떠한 데이터 분포가 여러 개의 Gaussian 분포 여러 개가 섞여서 만들어졌다고 생각하고, 해당 데이터 분포를 이루는 여러 개의 Gaussian 분포로 나타내는 확률적 생성 모델이다.
  • GMM Clustering은 다른 Clustering 모델과 달리, 해당 Cluster에 속할 확률을 같이 나타내주기 때문에, Clustering 결과에 불확실성도 함께 고려할 수 있다.
  • GMM Clustering은 확률을 포함한 Clustering이나, 데이터 생성, 이상치 탐지(다른 이상치 제거 알고리즘과 함께 사용되는 경우) 등에 유용하게 사용된다.

GMM Clustering, K-Means Clustering, DBSCAN과의 차이

  • 보통 GMM Clustering을 단독으로 사용하지는 않지만, (초기값 설정에서 다른 Clustering 알고리즘의 도움을 많이 받음), 같은 Clustering 알고리즘이라는 점에서 DBSCAN과 K-means Clustering과 비교해 보기로 한다.
특징 GMM Clustering DBSCAN K-means Clustering
Cluster의 모양 데이터의 Cluster 모양이 Gaussian 분포를 따르는 것을 가정 데이터의 Cluster 모양이 arbitrary하게 묶이는 경우 잘 Clustering 됨. (비선형 구조) 데이터의 Cluster 모양이 Spherical한 경우에 잘 Clustering 됨. (비선형 구조)
Cluster의 갯수 .군집화될 갯수를 미리 정해줘야 함 군집화 갯수를 미리 정해주지 않아도 됨(밀도 기반) 군집화될 갯수를 미리 정해줘야함 (centroid 기반)
Outlier 데이터를 Gaussian 분로 가정하기 때문에, 잘못된 모델링이 될 수 있음 (Outlier에 취약함) Clustering에 포함되지 않는 Outlier를 특정할 수 있음 모든 데이터가 하나의 Cluster에 포함됨
Initial Setting 초기 군집 중심, 초기 공분산 행렬에 따라 결과가 많이 달라짐 초기 Cluster 상태가 존재하지 않음 초기 Centroid 설정에 따라 결과가 많이 달라짐
Computing Cost 높음 (EM 알고리즘) 낮음 (K-means Clustering보다는 높음) 낮음
Cluster 속할 확률 Gaussian 다변수 정규 분포를 사용하여, 각 Cluster 포함될 확률을 계산 가능 밀도 기반으로 간접 추정 거리 기반으로 간접 추정

GMM Clustering 원리

  • GMM Clustering 알고리즘은 데이터 분포를 여러개의 Gaussian 분포들의 합 들이 혼합된 상태로 구성되어 있다고 가정하기 때문에, 데이터는 아래 수식과 같이 모델링 된다.

GMM 수식

- 𝑝(𝑥) : 데이터 포인트 x의 확률
- 𝜙𝑖 : 번째 Gaussian 분포의 합의 weight (weight의 합은 1)
- N(𝑥|𝜇𝑖,Σ𝑖) : i번째 Gaussian 분포의 확률 밀도 함수
- 𝜇𝑖 : i번째 Gaussian 분포의 평균
- Σ𝑖 : i번째 Gaussian 분포의 공분산 행렬
  • GMM Clustering 알고리즘은 결국 GMM 수식에서 𝜙𝑖(각 Gaussian 분포의 weight), 𝜇𝑖 (각 Gaussian 분포의 평균), Σ𝑖 (각 Gaussian 분포의 공분산 행렬)을 찾는 과정이다.
  •  이를 위해, EM (Expectation & Maximization) 알고리즘을 사용한다. EM 알고리즘은 Expectation step과 Maximization Step으로 나뉜다.
    • E-step (Expectation step) :
      • 각 데이터 포인트가 어떤 Gaussian 분포에 속하는지에 대한 확률을 추정한다. 
    • M-step (Maximization step)
      • E-step에서 추정된 확률을 이용해서, Gaussian 분포의 Parameter(weight, 평균, 공분산 행렬)를 업데이트한다. 
      • 이때, 업데이트를 위한 목적함수는 log-likelihood 함수를 이용한다. 
      • log-likelihood 함수가 최대화하는 방향으로 Parameter를 업데이트한다. (어떠한 data point가 어떤 Gaussian 분포에 포함될 확률이 높도록 학습. 즉, 모든 데이터 포인트가 어떠한 Gaussian 분포에 포함될 확률이 높도록 parameter를 업데이트)

GMM Clustering 목적함수

  • 다만, GMM은 초기값 설정에 매우 민감하다. 만약 inital mean 값이 잘못 찍혔을 때, Clustering의 결과가 원하는 바와 다르게 나올 수 있다. 

  • 따라서, GMM Clustering을 단독으로 사용하기 보다는 K-means Clustering 등을 이용하여, Initial 값들을 setting 한다. (scikit-learn의 GaussianMixture 함수도 초깃값의 default 설정이 k-means 방법을 통해 구하는 것으로 되어있다.)

GMM Clustering Python 구현

  • scikit-learn의 GaussianMixture 함수를 사용하면 쉽게 사용 가능하다.
import numpy as np
from sklearn.datasets import make_blobs # Clustering 데이터 생성을 위해
from sklearn.mixture import GaussianMixture

if __name__ == '__main__':
    X, y = make_blobs(n_samples=1000, centers=5, random_state=1) # Sample 데이터 생성
    gmm = GaussianMixture(n_components=5, random_state=42, n_init=10)
    gmm.fit(X)

    gmm.means_ #gmm의 mean 값들을 확인 가능
    gmm.weights_ #gmm의 weight 값들을 확인 가능
    gmm.covariances_ #gmm의 공분산 행렬 확인 가능

    gmm.predict(X) #각 point가 어느 Cluster에 포함되는지 결과를 확인
    gmm.predict_proba(X) #각 point가 각 Cluster에 포함될 확률 (point 당 n_components개 만큼)

 

반응형

DBSCAN (Density-Based Spatial Clustering of Application with Noise)


포인트 데이터 분석에서 DBSCAN은 항상 빠지지 않고 등장한다. 항상 무의식적으로 사용했었는데, 조금 더 자세히 알아보고 싶었다.  

DBSCAN 이란?

  • DBSCAN(Density-Based Spatial Clustering of Applications with Noise)은 머신 러닝에 주로 사용되는 클러스터링 알고리즘으로 Multi Dimension의 데이터를 밀도 기반으로 서로 가까운 데이터 포인트를 함께 그룹화하는 알고리즘이다.
  • DBSCAN은 밀도가 다양하거나 모양이 불규칙한 클러스터가 있는 데이터와 같이 모양이 잘 정의되지 않은 데이터를 처리할 때 유용하게 사용 가능하다.

K-Means Clustering과의 차이

  • 보통 Clustering 문제에서 K-Means Clustering을 우선 떠올리지만, DBSCAN이 필요한 경우도 있다.
  • K-Means Clustering과 DBSCAN의 차이는 다음과 같다.
특징 DBSCAN K-means Clustering
Cluster의 모양 데이터의 Cluster 모양이 arbitrary하게 묶이는 경우 잘 Clustering 됨. 데이터의 Cluster 모양이 Spherical한 경우에 잘 Clustering 됨.
Cluster의 갯수 군집화 갯수를 미리 정해주지 않아도 됨(밀도 기반) 군집화될 갯수를 미리 정해줘야함 (centroid 기반)
Outlier Clustering에 포함되지 않는 Outlier를 특정할 수 있음 모든 데이터가 하나의 Cluster에 포함됨
Initial Setting 초기 Cluster 상태가 존재하지 않음 초기 Centroid 설정에 따라 결과가 많이 달라짐
  • DBSCAN과 K-means Clustering 사이에 어느 것이 좋다는 다루는 데이터에 따라 많이 달라진다.
  • DBSCAN은 일반적으로 K-means Clustering에 비해 1) 불규칙 데이터를 다룰때, 2) Noise와 Outlier가 많을 것으로 예상될 때, 3) 데이터에 대한 사전 예측이 어려울때, 활용하는 것이 좋다.
  • 하지만, DBSCAN은 K-means Clustering에 비해 1) Computational Cost가 많이 든다는 점, 2) 예측과 해석이 어렵다는 점의 단점이 있다.

DBSCAN 알고리즘

  • DBSCAN도 2가지의 hyper parameter를 갖는다.
  1. Epsilon : Cluster를 구성하는 최소의 거리
  2. Min Points: Cluster를 구성 시, 필요한 최소 데이터 포인트 수
  • DBSCAN의 동작 과정은 다음과 같다. 
  1. 데이터 중, 임의의 포인트를 선택함.
  2. 선택한 데이터와 Epsilon 거리 내에 있는 모든 데이터 포인트를 찾음.
  3. 주변에 있는 데이터 포인트 갯수가 Min Points 이상이면, 해당 포인트를 중심으로 하는 Cluster를 생성한다.
  4. 어떠한 포인트가 생성한 Cluster 안에 존재하는 다른 점 중, 다른 Cluster의 중심이 되는 데이터 포인트가 존재한다면 두 Cluster는 하나의 Cluster로 간주한다.
  5. 1~4번을 모든 포인트에 대해서 반복한다.
  6. 어느 Cluster에도 포함되지 않는 데이터 포인트는 이상치로 처리한다. 

DBSCAN Python 구현

from sklearn.datasets import make_moons
from sklearn.cluster import DBSCAN
import matplotlib.pyplot as plt

if __name__ == '__main__':
	N = 1000
    
    X, y = make_moons(n_samples=N, noise=0.05) # make_moons 함수를 사용

    dbscan = DBSCAN(eps=0.2, min_samples=5) # DBSCAN (eps : epsilon, min_samples : min point)
    dbscan.fit(X)

    plt.scatter(X[:, 0], X[:, 1], c=dbscan.labels_) # Clustering 결과 시각화 용도
    plt.show()

 

 

반응형

💬 비윤리적 텍스트 검출 데이터셋 분석

  • 지난 장에서, '텍스트 윤리검증 데이터'의 train, validation, test 데이터의 양과 형태에 대해서 확인해보았다.
  • 이번 장에서는, 텍스트 데이터를 조금 더 자세하게 분석해보기로 한다.
  • 텍스트 데이터를 분석하는 것은 추후 불용어나, 텍스트 정수 인코딩에서 빈도수 제한을 거는 등에 활용되어, 더 좋은 모델을 만드는데 사용될 수 있다.

  • 텍스트의 윤리검증 기준은 사람마다 다르다. 데이터셋을 구성한 명확한 기준을 알 수 없기에, 우선 데이터셋으로 구성된 비윤리적 텍스트들에는 어떠한 공통점이 있는지 확인해보면 좋을 것이다.

 

data_dir = r"{설치위치}\data\val"
df = pd.read_csv(data_dir, sep='\t', header=None)
df_true = df[df[1]==True]

우선, validation 데이터 파일을 다시 불러온다.(train 데이터의 텍스트를 분석하는 것이 더 좋겠지만, 너무 양이 많아서 오래 걸린다.

 

from konlpy.tag import Hannanum

word_parser = Hannanum()

text_list = list(df_true[5].values)
word_list = []

for text in text_list:
    word_list += word_parser.morphs(text)

 

"Hannanum"이라는 한국어 형태소 분석기를 통해, 데이터셋에 존재하는 text들을 parsing할 것이다. 형태소 분석을 하는 이유는, 형태소 단위로 의미있는 형용사나 명사를 추출하기 위함이다. 

위의 코드에서 "비윤리적" 텍스트들을 형태소 단위로 parsing하여 "word_list"에 넣어주었다. 

 

"word_list"에는 "비윤리적" 텍스트들이 list 형태로 들어가있다. 그중 여러 텍스트들에서 공통되는 단어들은 중복으로 들어가 있을 것이다. 우리는 어느 단어가 많이 등장하는지를 확인하기 위해, "Counter" 함수를 사용할 것이다.

 

from collections import Counter

c = Counter(word_list)
c_dict = dict(c)
c_dict = sorted(c_dict.items(), reverse=True, key=lambda item: item[1])

"word_list"를 "Counter" 함수를 통해 각 단어의 빈도수를 구했고, "sorted" 함수를 통해, 빈도수대로 정렬하였다.

 

비윤리적 텍스트 데이터 단어 빈도수

 

빈도수를 확인해보면, '이','하','는' 등등 "비윤리적" 텍스트들의 특징이라기보다는 한국어 텍스트 데이터들에서 공통으로 찾아볼 수 있는 단어들이 많이 등장하는 것을 볼 수 있다.

 

보통 검색엔진 등에서는 index 구성 시, stopword(불용어)라는 단계를 추가하여 이러한 데이터들을 제거하는데, 우리는 아직 데이터 분석 단계니, 해당 과정을 거치지 않는다. 

 

한 글자로는공통되는 단어가 직관적으로 파악되지 않아, 2글자 이상의 글자만 다시 확인해본다.  

 

word_list = [word for word in word_list if len(word)>1]

c = Counter(word_list)
c_dict = dict(c)
c_dict = sorted(c_dict.items(), 
                              reverse=True, 
                              key=lambda item: item[1])

2글자 이상에서 다시 확인해보니, 의미 있는 단어들이나, 이해가는 단어들이 등장하기 시작하였다. 

 

마찬가지로, 3글자 이상도 추출해본다. 

한 눈에 봐도, 비윤리적으로 보이는 단어들도 다수 등장한다.

 

해당 과정을 반복하면, 단어의 길이가 길수록 빈도수는 적지만, 단어 그 자체로 좋지 않은 의미를 담고 있는 단어들이 많다는 것을 확인 할 수 있다.

 

추후에 word를 정수로 인코딩하는 과정이 들어가는데, word_list에 존재하는 frequency에 따라 해당 단어를 정수로 encoding 할 것인지, 모르는 단어로 놔둘 것인지 설정할 수 있다.

 

이 단계에서 encoding 단계에서 매우 낮은 frequency 기준을 잡아야겠다는 생각을 할 수 있다.

 

 

사실, 이 단계에서 끝내도 되지만, 이왕한 김에 빈도를 wordcloud로 확인해보기로한다. 

 

from wordcloud import WordCloud
import matplotlib.pyplot as plt

wc = WordCloud(font_path='malgun', width=400, height=400, scale=2.0, max_font_size=250)
gen = wc.generate_from_frequencies(c)
plt.figure()
plt.imshow(gen)

 

 

2글자 이상의 데이터를 wordcloud 한 결과는 다음과 같다. (2글자까지는 그나마, 모자이크가 필요없다.)

 

윤리적 데이터에 대해서도 wordcloud를 만들어본다. 

내가 평소에 많이하는 '아니', '어서', '진짜' 같은 단어 들이 많다. 

 

데이터들을 직접 살펴보면서 분석의 방향을 잡은 것은 다음과 같다.

1. 윤리적 기준이 사람마다 달라서 단순 단어의 유무로 판단하는 것은 문제가 있다. (문맥을 파악해야할 것 같다.)
2. 글자 하나가 있냐 없냐에 따라, 의미가 완전히 달라져서 불용어를 최대한 조심해서 사용해야할 것 같다.
3. 긴 단어일수록, 데이터셋 내에서 빈도수는 적지만, 그 단어 하나가 판정에 powerful한 역할을 할 것 같다.
4. 데이터셋의 비윤리적 텍스트와 윤리적 텍스트의 양에 어느 정도 차이가 있다.  (Class Imbalance가 일어날 정도는 아닌 것 같은데, 추후 확장을 생각했을 때 고려해야한다.)
5. 윤리적/비윤리적 데이터의 소스가 비슷해서 그런지 서로 겹치는 단어들이 너무 많다. 추후 확장성을 생각한다면 윤리적 데이터를 추가적으로 더해서 학습해야할 것 같다. 
6. 형태소 분석에 시간이 꽤나 오래 걸려서, 미리 전처리를 해놔야겠다. 

 

지금까지 데이터를 분석해보았다. 다음 장부터, 본격적으로 데이터 모델을 만들고 처리하는 과정을 담도록 하겠다.

반응형

💬 비윤리적 텍스트 검출 데이터셋 분석

 

  • 딥러닝의 학습 모델 및 학습 방법에서 가장 중요한 것은 내가 풀고자 하는 문제가 무엇인지에 관한 것이다. 이를 위해 가장 좋은 방법은 내가 풀고자 하는 문제의 데이터들을 분석하는 것이다.
  • 사실, AI Hub는 데이터셋 사용자를 위해, 구성된 데이터에 대해서 자세한 설명을 적어두었다. 따라서, 그냥 설명을 읽어도 되지만, 그냥 스스로 분석해보고 싶어서 해당 장을 적었다. (데이터 분석이 익숙한 사람들은 해당 장의 내용은 넘어가도 된다.) 
  • 나는 원래 Jupyter Notebook을 좋아하지 않았다. (뭔가 코드를 짠다는 느낌보다는 단순히 입력한다는 느낌이 강하다.) 하지만, 데이터 분석을 간단하게 하기에는 Jupyter Notebook만 한 툴이 없기에, 의식적으로 Jupyter Notebook을 사용하여 데이터를 분석해볼 것이다. 

우리가 다운 받은 데이터는 데이터 수집된 자체의 Raw 데이터와 윤리/비윤리 판정을 위해, 전처리가 된 데이터가 있다. 이번 장에서는 전처리 데이터만 다루기로 한다.

 

 

전 장에서 전처리 데이터를 다운로드하였으면, 해당 디렉토리의 data 디렉토리에 들어가 본다. (해당 데이터들이 NLP 공부를 위해 사용될 데이터들이다.)

 

전처리된 데이터들

 

파일들을 메모장을 통해서 열어보면, 대략적인 데이터가 어떻게 생겼는지 확인할 수 있다.(용량이 크므로, 가장 작은 test 데이터셋을 열어보길 권유함)

 

 

jupyter notebook

Jupyter notebook을 이용한 다양한 분석을 위해, anaconda cmd 창에 "jupyter notebook"을 입력해 준다.

 

Jupyter notebook 창이 뜨면, New-Python3을 클릭하여 새로운 창을 띄운다. 

 

%pip install pandas
%pip install numpy
%pip install pillow
%pip install konlpy
%pip install wordcloud

 

 

Jupyter notebook 창이 뜨면, 첫 block에 위의 명령어를 실행하여 pandas, numpy, pillow와 konlpy(한글 형태소 분석기)와 wordcloud(wordcloud)를 설치한다. 

 

import pandas as pd

from wordcloud import WordCloud
import matplotlib.pyplot as plt
from collections import Counter
from konlpy.tag import Hannanum
from PIL import Image
import numpy as np

 

설치가 완료되었다면, 위처럼 각 패키지를 import 한다. (konlpy에서는 다양한 태깅 라이브러리를 제공하지만, Hannanum으로 사용: 실사용에서는 내가 처리하고자 하는 텍스트 데이터를 가장 잘 parsing 하는 형태소를 테스트 및 선택하는 과정이 필요)

 

 

패키지를 import 했다면, 데이터를 살펴볼 차례이다. 

 

data_dir = r"{설치위치}\data\train"
df = pd.read_csv(data_dir, sep='\t', header=None)

 

pandas에서는 데이터를 쉽게 import 할 수 있는 "read_csv" 함수를 제공한다. read_csv로 우선 train 데이터를 불러온다. 이제 df의 dataframe에는 "train" 데이터가 담겨있다.  

 

 

데이터 샘플

다음 블럭에서 df를 출력하여, 데이터의 형태를 확인한다. 출력 결과를 보면, "train" 데이터는 약 348,073개의 윤리적/비윤리적 문장들로 구성되어 있다는 것을 확인할 수 있다. 

 

 

홈페이지에서 데이터셋의 설명을 미리 읽었다면 확인 할 수 있겠지만, 해당 데이터셋의 Raw 데이터는 단순히 윤리적/비윤리적 구분을 위해서만 구성된 것이 아니기 때문에 추가적인 다양한 정보들을 가지고 있다. (비윤리적 강도, 비윤리적 문장의 유형 등...)

 

 

우리가 관심 있어 하는 부분은 "1"번 칼럼(비윤리성), "5"번 칼럼(텍스트 데이터)이기 때문에, "1"번 칼럼과 "5"번 칼럼을 집중적으로 살펴본다.

list(df[1].unique())

출력값 : [True, False]

1번 데이터에 존재하는 데이터는 True와 False 2개의 class로 구성되어 있다.

각 Class에 해당하는 문장은 어느 것들이 있는지 확인해 보자.

 

df_true = df[df[1]==True]

 

True(비윤리적 문장)은 총 192,187개의 문장으로 구성되어 있다. 텍스트 데이터를 몇 개 확인해 보니, 문장 그 자체로도 비윤리적으로 판정되는 데이터도 있고, 문맥 파악 없이 그 문장 자체로는 그다지 비윤리적인 것 같지 않은 문장들도 다수 존재한다.

df_false =df[df[1]==False]

False(윤리적 문장)은 총 155,886개의 문장으로 구성되어 있다. 텍스트 데이터를 몇 개 확인해보니, 이게 윤리적인 것 맞나 하는 데이터도 다수 포함되어 있다. (사람마다 윤리적 기준이 다르기 때문에 그런 것 같다.)

 

 

비슷하게 train, val, test 파일에 대해서도 다음을 수행해 준다. 각 파일에서 각 class에 포함된 데이터 개수를 세면, 아래와 같다. 

 

  Total 비윤리적 문장(True) 윤리적 문장(False)
Train (train 파일) 348,073 192,187 155,886
Validate (val 파일) 40,612 22,430 18,182
Test (test 파일) 44,998 26,011 18,987

 

다음 장에서는 데이터셋 내, 텍스트 데이터를 조금 더 자세히 분석해 보기로 한다. 

반응형

💬 자연어처리(NLP) 모델 만들기


💎 배경

  • 요즘 ChatGPT가 대세다. 석사 과정때는 이미지 처리 중심으로 연구를 진행했어서, 자연어처리에 관련해서 공부를 해보고 싶다는 생각이 들어 자연어처리의 초기 모델부터 현재 ChatGPT까지 흐름을 직접 코드를 짜보면서 이해해보고자 한다.

데이터셋 준비

  • 기본적으로 딥러닝 모델을 만들때, 가장 중요한 것은 “어떤 데이터를 처리하고자 하는가?”이다. 이왕 공부하는 김에 재밌는 데이터를 처리하고 싶어서, 자연어 처리에 필요한 데이터를 뒤져보았다.
  • 내가 선택한 데이터는 한국지능정보사회진흥원에서 운영하는 “AI Hub”에서 다운로드 받을 수 있는 “_텍스트 윤리검증 데이터_”이다. (내국인은 로그인 후, 다운 받을 수 있다)

  • 해당 데이터는 인터넷 상에서 윤리적인 데이터와 비윤리적인 데이터를 구분하기 위해 구축된 데이터로 451,110 문장을 대상으로 하였다고한다.
  • 구축 및 갱신 년도가 나름 최근이여서, 데이터셋을 확인해보았을때, 현재 인터넷에서 난무하는 밈들이나 악플들을 담고 있다. (심신이 약하면 데이터셋을 직접 눈으로 확인안하는 것을 추천한다... 정말 나쁜 글들이 많다.)
  • 해당 데이터를 선택한 이유는 다음과 같다.

① 데이터 및 만들고자 하는 모델이 흥미롭다. (실제로 필요하다고 생각이 들기도하고, 최신 데이터라 그런지 고전 데이터셋 특유의 정적인 맛이 덜해서 좋았다.)
② 데이터가 무겁지 않다.
③ 풀고자 하는 문제가 명확하다. (윤리 VS 비윤리)
④ 참과 거짓 간의 기준이 모호하다
→ 윤리와 비윤리의 정의는 사람마다 기준이 다르기 때문에 그 경계선이 모호하다. 예를들어, "이거 진짜 골때린다"라는 문장이 있을때, 이 문장은 윤리적일까 비윤리적일까? 이렇게 Class간 모호한 기준이 있는 데이터들은 오히려 학습 모델과 학습 방법에 따른 효과를 더 드라마틱하게 확인 가능하고, 추후 개선 아이디어도 만들기 좋다.

 

  • 데이터셋 설치 방법은 다음과 같다.

1. Raw 데이터를 다운 받는다. 

Raw 데이터 다운로드

 

2. 아래로 내려서, 데이터에 대한 전체적인 소개를 읽어본 후, 아래의 AI 샘플코드를 받는다.

(윤리 검증 이진 분류 학습용으로 전처리된 데이터를 포함)

전처리된 데이터 다운로드

 

데이터에 대한 상세한 설명은 다음 장에 진행하도록한다...

 

개발 환경 셋팅

  • Anaconda 환경에서 가상환경을 신규로 구축한 뒤, pypi를 이용하여 몇개의 라이브러리를 설치해준다.
pip install torch   
pip install torchtext==0.6.0
pip install konlpy
pip install pandas
  • torch : 딥러닝 도구 pytorch (CUDA 환경인 경우 홈페이지 설치 추천합니다)
  • torchtext : 자연어처리 분야에서 torch 활용을 쉽게 할 수 있도록 만들어진 라이브러리, 추후 데이터 loader 작성 시 쉽게 활용하기 위해 설치함. torchtext는 버전 0.6.0을 추천함. (이유는 추후에 별도로 설명할 계획)
  • konlpy : 한국어 정보처리를 위한 파이썬 라이브러리, 추후 한국어 형태소 분석에 필요한 모듈들을 사용할 계획임.
  • pandas : 데이터를 분석 조작하기 위해, 쉽게 만들어진 파이썬 라이브러리, 데이터 전처리 과정을 용이하게 진행하기 위해 활용할 계획임.

데이터와 개발 환경 셋팅이 모두 마무리되었다면, 다음 장에서 데이터 전처리를 해보자!

+ Recent posts