ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 딥러닝 모델 유형(2) - 비지도 학습
    딥러닝/데이터분석 2023. 3. 12. 13:52

    비지도 학습

    지도 학습처럼 레이블이 필요하지 않으며 정답이 없는 상태에서 훈련시키는 방식

     

    비지도학습 종류 :

     

    군집

    각 데이터의 유사성(=거리)를 측정한 후 유사성이 높은(거리가 짧은) 데이터끼리 집단으로 분류하는 것 

     

    # K-means clustering

    레이블이 없는 데이터를 입력받아 각 데이터에 레이블을 할당해서 군집화를 수행

    K-means 학습 과정 

     

    1. 중심점 선택: 랜덤하게 초기 중심점(centroid)을 선택합니다(그림에서는 K=2로 초기화).

    2. 클러스터 할당: K개의 중심점과 각각의 개별 데이터 간의 거리(distance)를 측정한 후, 가장 가까운 중심점을 기준으로 데이터를 할당(assign)합니다. 이 과정을 통해 클러스터가 구성됩니다(이때 클러스터링은 데이터를 하나 혹은 둘 이상의 덩어리로 묶는 과정이며, 클러스터는 덩어리 자체를 의미합니다).

    3. 새로운 중심점 선택: 클러스터마다 새로운 중심점을 계산합니다.

    4. 범위 확인(convergence): 선택된 중심점에 더 이상의 변화가 없다면 진행을 멈춥니다. 만약 계속 변화가 있다면 2~3 과정을 반복합니다.

     

    그림으로 학습 과정 확인하기 

     

     

    데이터가 비선형적일 때 

    군집 크기가 다를 떄 

    군집마다 밀집도와 거리가 다를 때

     

    사용하지 않는다. 

     

     

    K-평균 군집화 모델 학습 과정 

     

     

    # 라이브러리 호출
    import pandas as pd
    from sklearn.preprocessing import MinMaxScaler
    from sklearn.cluster import KMeans
    import matplotlib.pyplot as plt
    
    #데이터 불러오기 
    data = pd.read_csv('train.csv')
    data.head()
    data.shape
    data.tail()
    
     #Channel: 고객 채널(호텔/레스토랑/카페) 또는 소매 채널(명목형 데이터)
    
     #Region: 고객 지역(명목형 데이터)
    
     #Fresh: 신선한 제품에 대한 연간 지출(연속형 데이터)
    
     #Milk: 유제품에 대한 연간 지출(연속형 데이터)
    
     #Grocery: 식료품에 대한 연간 지출(연속형 데이터)
    
     #Frozen: 냉동 제품에 대한 연간 지출(연속형 데이터)
    
     #Detergents_Paper: 세제 및 종이 제품에 대한 연간 지출(연속형 데이터)
    
     #Delicassen: 조제 식품에 대한 연간 지출(연속형 데이터)
     
     
     #데이터 전처리하기
     #데이터 features가 여러가지이므로, 데이터 형태에 따라 카테고리화 시켜주어야 한다. 
     #연속형 데이터와 명목형 데이터로 분류하기 
     
     categorical_features = ['Channel', 'Region'] #명목형 데이터
     continuous_fatures = ['Fresh', 'Milk', 'Grocery', 'Frozen', 'Detergents_Paper', 'Delicassen'] # 연속형 데이터
     
     for col in categorical_features:
         dummies = pd.get_dummies(data[col], prefix=col)
         # 명목형 데이터는 판다스의 get_dummies() 메서드를 사용하여 숫자(0과 1)로 변환
         data = pd.concat([data, dummies], axis=1)
         data.drop(col, axis=1, inplace=True) 
      data.head()

    연속형 데이터랑 명목형 데이터로 분류가 가능해진다. (channel과 region은 0,1 이진표기가 됨)

     

     정규화해준 뒤 data_transformed 가지고 모델 훈련시키기 

    #scaling(정규화하기) : 모든 특성에 동일하게 중요성을 주여함 
    # 데이터 범위에 따라 중요도가 달라지는 것을 방지하기(1000원과 1억원이 있을 때 1000원의 데이터 무시)
    #MinMaxScaler() : 일정한 범위 유지: K-means에서는 MinmaxScaler를 통한 데이터 전처리(스케일링)을 해주게 된다.
    
    
    #정규화를 통한 데이터 전처리 
    
    mms = MinMaxScaler()
    mms.fit(data)
    data_transformed = mms.transform(data)
    
    적당한 K 값 추출하기 
    
    Sum_of_squared_dsitances =[]
    K = range(1,15) #K의 범위를 1~14까지 있을수 있다고 하고 range값을 설정해주기
    for K in K:
         km = KMeans(n_clusters = K) #  1~14의 K 값 적용
         km = km.fit(data_transformed) # KMeans 모델 훈련
         Sum_of_squared_distnaces.append(km.inertia_)
         
    plt.plot(K, Sum_of_squared_dsitances, 'bx-') #plt.plot(x축에 들어갈 값 , y축에 들어갈 값, )
    plt.xlabel('K') #x축 이름 설정해주기
    plt.ylabel
    plt.title('Optimal K')
    plt.show()

     

    ** Sum of Squared Distances (거리 제곱의 합)

    x, y두 데이터의 차를 구해서 제곱한 값을 모두 더한 후 유사성을 측정해준다.

    가장 가까운 클러스터 중심까지 거리의 제곱한 값의 합을 구할 때 사용함 

     

     

    K가 증가하면 거리 제곱의 합은 0에 가까워짐

    **K를 최댓값 n(여기에서 n은 샘플 수)으로 설정하면 각 샘플이 자체 클러스터를 형성하여 거리 제곱 합이 0과 같아지기 때문!

     

    위의 출력 그래프는 클러스터 개수(x축)에 따른 거리 제곱의 합(y축)을 보여 줍니다. K가 6부터 0에 가까워지고 있으므로 K=5가 적정하다고 판단할 수 있다. 

     

     

     

    # 밀도 기반 군집 분석 (DBSCAN)

    일정 밀도 이상을 가진 데이터를 기준으로 군집을 형성함 

     

     

    노이즈에 영향을 받지 않음

    K-means가 잘 처리하지 못하는 오목하거나 볼록한 부분을 처리함 

    ** 노이즈와 이상치 

     

    노이즈 : 주어진 데이터셋과 무관하거나 무작위성 데이터로 전처리 과정에서 제거해야 함

    이상치 : 관측된 데이터 범위에서 많이 벗어난 아주 작은 값이나 아주 큰 값

     

    밀도 기반 군집 분석 (DBSCAN) 과정 

     

    1. 앱실론 내 점 개수 확인 및 중심점 결정 (새로운 군집 만들기)

     

    다음 그림과 같이 원 안에 점 P1이 있다고 할 때, 점 P1에서 거리 엡실론 내에 점이 12개 있으면 하나의 군집으로 인식한다고 함.

    이때 엡실론 내에 점 m개를 가지고 있는 점 P1을 중심점(core point)이라고 할 수 있다. 예를 들어 minPts=3이라면 파란색 점 P1을 중심으로 반경 엡실론 내에 점이 세 개 이상 있으면 하나의 군집으로 판단할 수 있는데, 다음 그림은 점이 네 개 있기 때문에 하나의 군집이 되고, P1은 중심점이 된다.

     

    2. 군집 확장 

    데이터의 밀도 기반으로 군집을 생성하기 때문에 밀도가 높은 지역에서 중심점을 만족하는 데이터가 있다면 그 지역을 포함하여 새로운 군집을 생성하게됨 ( 예를 들어 P1 옆에 있던 빨간색 점을 중심점 P2로 설정하면 minPts=3을 만족하기 때문에 새로운 군집을 생성할 수 있음)

     

     

     

     

     

     

    차원 축소 

    차원을 나타내는 특성을 줄여서 데이터를 줄임 

     

    #주성분 분석(PCA)

    고차원 데이터를 저차원(차원 축소) 데이터로 축소

     

    PCA는 데이터 하나하나에 대한 분석 X 여러 데이터들이 분포를 이루고 그 분포의 주성분을 분석함 O(나무가 아닌 숲을 보기!)

     

    PCA 기법 과정 

    1.  벡터 두 개를 위한 적절한 가중치를 찾을 수 있을 때까지 학습을 진행하기( e1의 방향과 크기, e2의 방향과 크기를 알아 데이터 분포 형태를 찾아내기

    - 데이터 하나하나에 대한 성분을 분석하는 것이 아니라 여러 데이터가 모여 하나의 분포를 이룰 때 이 분포의 주성분을 분석하는 것 

    pca = decomposition.PCA(n_components=1)
    pca_x = pca.fit_transform(x_std)
    
    result = pd.DataFrame(pca_x, columns=['dog'])
    result['y-axis'] = 0
    result['label'] = Y
    
    sns.Implot('dog', 'y-axis', data =result, fit_reg = False, scatter_kws = {"s" : 50}, hue = 'label');

     

     

     

    분석 과정

     - 사용 : 밀도 기반 분석 & PCA

    - 밀도 기반 분석 : 클러스터링

    - 시각화: PCA

     

     

    # 라이브러리 호출하기
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    
    from sklearn.cluster import DMSCAN #밀도 기반 군집 분석
    from sklearn.preprocessing import StandardScaler
    from sklearn.preprocessing import normalize
    from sklearn.decomposition import PCA #데이터 차원 축소
    
    # 데이터 불러오고 기본적인 처리 해주기 
    x = pd.read_csv('train.csv')
    X = X.drop('CUST_ID', axis=1) #------ 불러온 데이터에서 ‘CUST_ID’ 열(칼럼)을 삭제
    E전처리 해주기 
    X.fillna(method='ffill', inplace=True)   
    print(X.head()) #------ 데이터셋 형태 확인

    df.fillna(method='ffill') 

    - 앞의 값으로 결측치가 채워진다. 

     

     

     

    #데이터 전처리 해주기
    scaler = StandardScaler()
    x_scaled = scaler.fit_transform(x) #------ 평균이 0, 표준편차가 1이 되도록 데이터 크기를 조정
    
    
    #차원 축소 진행하기 
    
    X_normalized = normalize(X_scaled) ------ 데이터가 가우스 분포를 따르도록 정규화
    X_normalized = pd.DataFrame(X_normalized) ------ 넘파일 배열을 데이터프레임(dataframe)으로 변환
    
    pca = PCA(n_components=2) ------ 2차원으로 차원 축소 선언
    X_principal = pca.fit_transform(X_normalized) ------ 차원 축소 적용
    X_principal = pd.DataFrame(X_principal)
    X_principal.columns = ['P1', 'P2']
    print(X_principal.head())

     

    데이터를 2차원으로 차원 축소한 결과

     

    DBSCAN 모델 생성 및 결과의 시각화

    db_default = DBSCAN(eps = 0.0375, min_sample=3).fit(X_principal) #모델 생성 및 훈련하기 
    labels = db_default.labels_ # 각 데이터 포인트에 할당된 모든 클러스터 레이블의 넘파이 배열을 labels에 저장한다.
    
    colours = {} # 출력 그래프의 색상을 위한 레이블을 생성함 : 클러스터 별 색상
    colours[0] = 'y'
    colours[1] = 'g'
    colours[2] = 'b'
    colours[-1] = 'k'
    
    cvec = [colours[label] for label in labels]  # 각 데이터 포인트에 대하여 색상 벡터를 설정함
    
    # 플롯의 범례를 지정함
    
    
    r = plt.scatter(X_principal['P1'], X_principal['P2'], color='y');
    g = plt.scatter(X_principal['P1'], X_principal['P2'], color='g');
    b = plt.scatter(X_principal['P1'], X_principal['P2'], color='b');
    k = plt.scatter(X_principal['P1'], X_principal['P2'], color='k');
    
    plt.figure(figsize=(9,9))
    #위의 범례에 맞추어 X축에 P1, y축에 P2를 놓는다.(특징들)
    plt.scatter(X_principal['P1'], X_principal['P2'], c=cvec) 
    범례 구축 
    plt.legend((r,g,b,k), ('Label 0', 'Label 1', 'Label 2', 'Label -1'))
    plt.show()

     

     

     

    클러스터링 튜닝하기

    - min_samples값 변경

     

     

Designed by Tistory.