TIL(24.06.19.)

codataffee·2024년 6월 19일

TIL

목록 보기
72/135
post-thumbnail

#INTRO

요즘 추출 폼 미쳤다ㅋㅋ

coffeeeeeeeee makes me happy.


#코드카타 (09:00 ~ 10:00)

  • KATA #67

  • SQL

    • MySQL의 8.0 이하 버전에서는 WITH 절을 활용한 CTE 생성이 불가능하다..
      WITH 절로 가독성 있고 간단하게 쿼리 작성이 가능한 것을
      인라인 뷰(서브쿼리)로 작성하려니 헷갈렸었다.
      			SELECT earnings, COUNT(*)
      			FROM (
      			    SELECT employee_id
      			    	 , name
      			         , months
      			         , salary
      			         , (months * salary) earnings
      			    FROM EMPLOYEE
      			) AS earn
      			GROUP BY earnings
      			ORDER BY earnings DESC
      			LIMIT 1
  • PYTHON

    • PYTHON #DFS,BFS

    • DFS (Depth-First Search) : 깊이 우선 탐색
      가능한 깊이까지 탐색한 후에 다시 돌아와서 다음 경로를 탐색한다.
      깊이 있는 부분을 먼저 탐색하는 함수

    • 특징

      • 재귀적 구현 :
        스택 자료 구조 사용

      • 메모리 사용량 :
        방문한 정점과 경로를 저장하기 위해 최대 O(V)의 공간이 필요 (V ; 정점의 수)

      • 완전성 :
        모든 경로를 탐색할 수 있다.

      • 적용 :
        미로 찾기, 퍼즐 풀이, 경로 찾기 등.

def solution(numbers, target):
    # dfs 함수 정의
    def dfs(index, current_sum):
        # 모든 숫자를 다 사용했을 때
        if index == len(numbers):
            # 현재 합이 타겟 넘버와 일치하면 1을 반환하고, 그렇지 않으면 0을 반환
            return 1 if current_sum == target else 0
        
        # 현재 숫자를 더하거나 빼는 두 가지 경우를 재귀적으로 탐색
        # index + 1은 다음 숫자로 이동, current_sum + numbers[index]는 현재 숫자를 더하는 경우
        # current_sum - numbers[index]는 현재 숫자를 빼는 경우
        return dfs(index + 1, current_sum + numbers[index]) + dfs(index + 1, current_sum - numbers[index])
    
    # dfs 탐색 시작: 인덱스 0부터 시작하고 초기 합은 0
    return dfs(0, 0)

# 프로젝트 진행 (10:00 ~ 22:00)

  • 군집분석 후 평가를 위한 실루엣 계수를 구하는 데 시간이 너무 오래 소요됐다..

  • 코랩과 로컬(VSCODE) 환경을 함께 코드를 돌리면서, 최대한 시간절약..

  • 군집 분석 시도

목표 : 17만 개 데이터셋으로 군집 분석 후 군집 결과가 좋은 모델 찾기

  1. 수치형 데이터들을 로버스트(ROBUST SCALER) 스케일링 후
    K-MEANS 알고리즘으로 군집화 및 평가

# 기본 라이브러리 import
import pandas as pd
import numpy as np
# 시각화 라이브러리 import
import seaborn as sns
import matplotlib.pyplot as plt
# 표준화 라이브러리 import
from sklearn.preprocessing import StandardScaler
# k 값 참고: scree plot을 통한 k 값 확인을 위한 라이브러리 import
from yellowbrick.cluster import KElbowVisualizer
# k 값 참고: distance map 라이브러리 import
from yellowbrick.cluster import intercluster_distance
from sklearn.cluster import MiniBatchKMeans
# k 값 참고: 실루엣 계수 확인을 위한 라이브러리 import
from sklearn.metrics import silhouette_score
# 데이터셋 주성분 분석중 하나인 pca 를 수행하기 위한 라이브러리 import
from sklearn.decomposition import PCA
# k-means 알고리즘 활용을 위한 라이브러리 import
from sklearn.cluster import KMeans
import warnings
warnings.filterwarnings('ignore')
# 데이터 불러오기
sp_w_df = pd.read_csv('C:/Users/BAEK/Desktop/CSV DB/ML/data_files/spotify_clustering/data_w_genres.csv')
# 음악 특징과 관련이 있는 수치형 컬럼 선택
cols = ['acousticness', 'danceability', 'energy', 'instrumentalness', 'liveness', 'loudness', 'valence', 'tempo', 'popularity', 'key']
scale_cols = ['tempo', 'popularity', 'key']
# 데이터 스케일링 (로버스트)
from sklearn.preprocessing import RobustScaler
rs = RobustScaler()
display(sp_w_df[cols].head(3))
# sp_w_df[scale_cols] = sd.fit_transform(sp_w_df[scale_cols])
sp_w_df[scale_cols] = rs.fit_transform(sp_w_df[scale_cols])
display(sp_w_df[cols].head(3))
df_scaled = sp_w_df[cols]

# 주성분 개수를 판단하기 위한 pca 임의 시행
pca = PCA(n_components = 3)
pca.fit(df_scaled)
# 설정한 주성분의 갯수로 전체 데이터 분산을 얼만큼 설명 가능한지
print(pca.explained_variance_ratio_)
# pca 시행
pca_df = pca.fit_transform(df_scaled)
pca_df = pd.DataFrame(data = pca_df, columns = ['PC1','PC2','PC3'])
pca_df.head()
# PC1 : 95 % 설명력에 대한 회의가 필요
# 주성분 나누는 컬럼 기준? 

# 초기 k 값 참고를 위한 scree plot 을 그리고, 군집이 나뉘는 시간까지 고려한 k 값 확인
model = KMeans()
# k 값의 범위를 조정해 줄 수 있습니다.
visualizer = KElbowVisualizer(model, k=(3,12))
# 데이터 적용
visualizer.fit(pca_df)
visualizer.show()

#  KMEANS
# 군집개수(n_cluster) 6, 초기 중심 설정방식 랜덤,
optimal_k = 6
kmeans = KMeans(n_clusters = optimal_k, random_state = 42,init = 'random')
# pca df 를 이용한 kmeans 알고리즘 적용
kmeans.fit(pca_df)
clusters = kmeans.fit_predict(pca_df)
# 클러스터 번호 가져오기
labels = kmeans.labels_
# 클러스터 번호가 할당된 데이터셋 생성
kmeans_df = pd.concat([pca_df, pd.DataFrame({'Cluster' : labels})], axis = 1)

# 2차원으로 시각화
plt.figure(figsize=(8, 8))
sns.scatterplot(data = kmeans_df, x = 'PC1', y='PC2', hue='Cluster')
plt.title('The Plot Of The Clusters(2D)')
plt.show()

# 2차원으로 시각화
plt.figure(figsize=(8, 8))
sns.scatterplot(data = kmeans_df, x = 'PC1', y='PC3', hue='Cluster')
plt.title('The Plot Of The Clusters(2D)')
plt.show()

# 2차원으로 시각화
plt.figure(figsize=(8, 8))
sns.scatterplot(data = kmeans_df, x = 'PC2', y='PC3', hue='Cluster')
plt.title('The Plot Of The Clusters(2D)')
plt.show()

from sklearn.metrics import silhouette_score, silhouette_samples
# 실루엣 계수 계산
silhouette_avg = silhouette_score(df_scaled, clusters)
silhouette_values = silhouette_samples(df_scaled, clusters)
silhouette_avg

from sklearn.metrics import silhouette_score, silhouette_samples
# 전체 데이터셋의 평균 실루엣 점수 계산
silhouette_avg = silhouette_score(df_scaled, clusters)
# 각 데이터 포인트의 실루엣 점수 계산
silhouette_values = silhouette_samples(df_scaled, clusters)
# 플롯을 설정하고 크기 지정
fig, ax = plt.subplots(figsize=(10, 6))
# 초기 y축 위치 설정
y_lower = 10
# 각 클러스터에 대해 반복
for i in range(optimal_k):
    # 현재 클러스터에 속하는 데이터 포인트들의 실루엣 값을 가져옴
    ith_cluster_silhouette_values = silhouette_values[clusters == i]
    # 실루엣 값 정렬
    ith_cluster_silhouette_values.sort()
    # 현재 클러스터의 크기 계산
    size_cluster_i = ith_cluster_silhouette_values.shape[0]
    # 현재 클러스터의 y축 상한을 설정
    y_upper = y_lower + size_cluster_i
    # 현재 클러스터의 색상 설정
    color = plt.cm.nipy_spectral(float(i) / optimal_k)
    # 현재 클러스터의 실루엣 값을 채움
    ax.fill_betweenx(np.arange(y_lower, y_upper), 0, ith_cluster_silhouette_values,
                     facecolor=color, edgecolor=color, alpha=0.7)
    # 현재 클러스터의 레이블 추가
    ax.text(-0.05, y_lower + 0.5 * size_cluster_i, str(i))
    # 다음 클러스터를 위한 y축 시작 위치 업데이트
    y_lower = y_upper + 10
# 플롯의 제목 설정
ax.set_title("Silhouette plot for the various clusters")
# x축 레이블 설정
ax.set_xlabel("Silhouette coefficient values")
# y축 레이블 설정
ax.set_ylabel("Cluster label")
# 평균 실루엣 점수를 나타내는 수직선 추가
ax.axvline(x=silhouette_avg, color="red", linestyle="--")
# y축의 티크 제거
ax.set_yticks([])
# x축의 티크 설정
ax.set_xticks(np.arange(-0.1, 1.1, 0.2))
plt.show()
  1. 수치형 데이터들을 스탠다드(STANDARD SCALER) 스케일링 후
    K-MEANS 알고리즘으로 군집화 및 평가

# 기본 라이브러리 import
import pandas as pd
import numpy as np
# 시각화 라이브러리 import
import seaborn as sns
import matplotlib.pyplot as plt
# 표준화 라이브러리 import
from sklearn.preprocessing import StandardScaler
# k 값 참고: scree plot을 통한 k 값 확인을 위한 라이브러리 import
from yellowbrick.cluster import KElbowVisualizer
# k 값 참고: distance map 라이브러리 import
from yellowbrick.cluster import intercluster_distance
from sklearn.cluster import MiniBatchKMeans
# k 값 참고: 실루엣 계수 확인을 위한 라이브러리 import
from sklearn.metrics import silhouette_score
# 데이터셋 주성분 분석중 하나인 pca 를 수행하기 위한 라이브러리 import
from sklearn.decomposition import PCA
# k-means 알고리즘 활용을 위한 라이브러리 import
from sklearn.cluster import KMeans
import warnings
warnings.filterwarnings('ignore')
# 데이터 불러오기
sp_df = pd.read_csv('C:/Users/BAEK/Desktop/CSV DB/ML/data_files/spotify_clustering/data.csv')
# 음악 특징과 관련이 있는 수치형 컬럼 선택
cols = ['valence', 'acousticness', 'danceability', 'duration_ms', 'energy', 'instrumentalness', 'key', 'liveness', 'loudness', 'tempo']
rs = RobustScaler()
# 데이터 스케일링 (스탠다드)
from sklearn.preprocessing import StandardScaler
sd = StandardScaler()
display(sp_df[cols].head(3))
sp_df[cols] = sd.fit_transform(sp_df[cols])
# sp_w_df[scale_cols] = rs.fit_transform(sp_w_df[scale_cols])
display(sp_df[cols].head(3))
df_scaled = sp_df[cols]

# 주성분 개수를 판단하기 위한 pca 임의 시행
pca = PCA(n_components = 5)
pca.fit(df_scaled)
# 설정한 주성분의 갯수로 전체 데이터 분산을 얼만큼 설명 가능한지
print(pca.explained_variance_ratio_.sum())
# pca 시행
pca_df = pca.fit_transform(df_scaled)
pca_df = pd.DataFrame(data = pca_df, columns = ['PC1','PC2','PC3','PC4', 'PC5'])
pca_df.head()

# 초기 k 값 참고를 위한 scree plot 을 그리고, 군집이 나뉘는 시간까지 고려한 k 값 확인
model = KMeans()
# k 값의 범위를 조정해 줄 수 있습니다.
visualizer = KElbowVisualizer(model, k=(3,12))
# 데이터 적용
visualizer.fit(pca_df)
visualizer.show()

#  KMEANS
# 군집개수(n_cluster) 6, 초기 중심 설정방식 랜덤,
optimal_k = 6
kmeans = KMeans(n_clusters = optimal_k, random_state = 42,init = 'random')
# pca df 를 이용한 kmeans 알고리즘 적용
kmeans.fit(pca_df)
clusters = kmeans.fit_predict(pca_df)
# 클러스터 번호 가져오기
labels = kmeans.labels_
# 클러스터 번호가 할당된 데이터셋 생성
kmeans_df = pd.concat([pca_df, pd.DataFrame({'Cluster' : labels})], axis = 1)

# 2차원으로 시각화
plt.figure(figsize=(8, 8))
sns.scatterplot(data = kmeans_df, x = 'PC1', y='PC2', hue='Cluster')
plt.title('The Plot Of The Clusters(2D)')
plt.show()

from sklearn.metrics import silhouette_score, silhouette_samples
# 실루엣 계수 계산
silhouette_avg = silhouette_score(df_scaled, clusters)
silhouette_values = silhouette_samples(df_scaled, clusters)
silhouette_avg

from sklearn.metrics import silhouette_score, silhouette_samples
import random
# 실루엣 계수 계산
silhouette_avg = silhouette_score(df_scaled, clusters)
silhouette_values = silhouette_samples(df_scaled, clusters)
# 클러스터별 실루엣 플롯 생성
fig, ax = plt.subplots(figsize=(10, 6))
y_lower = 10
for i in range(optimal_k):
    ith_cluster_silhouette_values = silhouette_values[clusters == i]
    ith_cluster_silhouette_values.sort()    
    size_cluster_i = ith_cluster_silhouette_values.shape[0]
    y_upper = y_lower + size_cluster_i    
    color = plt.cm.nipy_spectral(float(i) / optimal_k)
    ax.fill_betweenx(np.arange(y_lower, y_upper), 0, ith_cluster_silhouette_values,
                     facecolor=color, edgecolor=color, alpha=0.7)    
    ax.text(-0.05, y_lower + 0.5 * size_cluster_i, str(i))    
    y_lower = y_upper + 10
ax.set_title("Silhouette plot for the various clusters")
ax.set_xlabel("Silhouette coefficient values")
ax.set_ylabel("Cluster label")
ax.axvline(x=silhouette_avg, color="red", linestyle="--")
ax.set_yticks([])
ax.set_xticks(np.arange(-0.1, 1.1, 0.2))
plt.show()

  • 3일차 스크럼 정리
17만 개의 데이터셋으로 군집화하는 것까지는 크게 어려움이 없었으나,
그 군집화의 결과를 평가하기 위해 진행하는 실루엣 계수 계산에
많은 시간이 소요되었다.

결국 실루엣 계수가 높고 군집화가 잘 되었다고 평가할 수 있는 모델을
만들어내지 못했다.

방향성을 찾기 위해 튜터님께 질문,
군집화에 영향을 주는 주성분의 갯수와 K 값을 바꿔가면서
그 실루엣 계수들을 시각화하고 비교하면서 제일 군집화가 잘된 
(실루엣 계수의 면적이 넓고 비슷하며, 평균값이 높은) 
모델을 찾을 때까지 군집분석을 시도해야 한다. 는 결론을 내렸다.
  • 팀 회의 결과 :

    • 튜터님께 조언 받은 내용 중 전처리(표준화)는 StandardScaler 로 통일하기.

    • 주성분 분석과 K 값을 자유롭게 변화해보며 K-means 분석을 진행하기.

    • 주성분과 K값의 변화마다 실루엣 계수 계산하고 시각화하여 기록하기.

      실루엣 계수의 면적이 넓고 균등하며, 평균값이 가장 높은 모델 선택하기.

  • 내일까지 해야할 내용 :

    • 주성분 : 3 ~ 5개 (설명력 65% ~ 85% 사이)

    • K 값 : 3 ~ 6개 (군집화 갯수)

      목표 : 실루엣 계수 0.5 이상, 면적이 넓고 균등한 모델 찾기


# 빅분기(실기) 준비 (22:00 ~ 23:00)

  • PYTHON #28 : 작업형 1 예시문제 다양하게 풀어보기

#OUTRO

오늘의 한 줄.

멘탈 관리 !
컨디션 관리 !
화이팅 !

profile
커피 좋아하는 데이터 꿈나무

0개의 댓글