# 라이브러리
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# 데이터
iris_df = sns.load_dataset('iris')
iris_df.head(3)
# 분석 데이터 선정
iris_df2 = iris_df[['sepal_length','sepal_width','petal_length','petal_width']]
# KMean
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters = 3, init = 'k-means++', max_iter = 300, random_state= 42)
kmeans.fit(iris_df2)
# 답과 비교를 위해 분석 결과 컬럼으로 추가
iris_df2['target'] = iris_df['species']
iris_df2['cluster'] = kmeans.labels_
# 시각화를 통해 정답과 비교
plt.figure(figsize = (12,6))
plt.subplot(1,2,1)
sns.scatterplot(data = iris_df2, x = 'sepal_length', y = 'sepal_width', hue = 'target')
plt.title('Original')
plt.subplot(1,2,2)
sns.scatterplot(data = iris_df2, x = 'sepal_length', y = 'sepal_width', hue = 'cluster', palette= 'viridis')
plt.title('Clustering')
plt.show()
# 라이브러리
!pip install openpyxl
# 데이터 가져오기
retail_df = pd.read_excel('/Users/t2023-m0092/Desktop/J/Python/강의/강의_머신러닝/실습코드/Online Retail.xlsx')
retail_df.head(3)
retail_df.info()
retail_df.isnull().sum()
# 데이터 EDA
retail_df.info()
retail_df.isnull().sum()
retail_df.describe(include = 'all')
# 데이터 전처리 - customerID 결측치 삭제
cond_cust = (retail_df['CustomerID'].notnull())
retail_df[cond_cust].isnull().sum()
# 데이터 전처리 - invoice가 C로 시작하는 것 삭제
cond_invo = (retail_df['InvoiceNo'].astype(str).str[0] != 'C')
retail_df[cond_invo].head(3)
# 데이터 전처리 - quantity, unitprice가 음수인 것 삭제
cond_minus = (retail_df['Quantity'] >0 ) & (retail_df['UnitPrice'] >0)
retail_df[cond_minus].head(3)
# 데이터 전처리 적용
retail_df_2 = retail_df[cond_cust & cond_invo & cond_minus]
retail_df_2.info()
# 데이터 전처리 - country 영국만 선택
cond_uk = (retail_df_2['Country'] =='United Kingdom')
retail_df_2 = retail_df_2[cond_uk]
# 데이터 전처리 - 수량&가격 곱해서 총 구매금액 컬럼 추가
retail_df_2['Amt'] = retail_df_2['Quantity'] * retail_df_2['UnitPrice']
retail_df_2['Amt'] = retail_df_2['Amt'].astype('int')
# 데이터 전처리 - customerid 중복 제거
retail_df_2[['CustomerID']].drop_duplicates()
# 데이터 전처리 - 전체 데이터 중 가장 최근 날짜 기준으로 구매 날짜 빼고 +1
# 추후 CustomerID 기준으로 Priod의 최소의 Priod를 구하면 그것이 Recency
retail_df_2['Period'] = (dt.datetime(2011,12,10) - retail_df_2['InvoiceDate']).apply(lambda x: x.days+1)
# 피벗 보기
rfm_df = retail_df_2.groupby('CustomerID').agg({
'Period' : 'min',
'InvoiceNo' : 'count',
'Amt' : 'sum'
})
# 컬럼명 변경
rfm_df.columns = ['Recency','Frequency','Monetary']
# 데이터 정규화
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_features = sc.fit_transform(rfm_df[['Recency','Frequency','Monetary']])
# 평가
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
kmeans = KMeans(n_clusters = 3, random_state = 42)
labels = kmeans.fit_predict(X_features)
rfm_df['label'] = labels
silhouette_score(X_features, labels)
# 군집 확인
from kmeans_visaul import visualize_silhouette
visualize_silhouette([2,3,4,5,6], X_features)
# log 스케일을 통한 추가전처리
import numpy as np
rfm_df['Recency_log'] = np.log1p(rfm_df['Recency'])
rfm_df['Frequency_log'] = np.log1p(rfm_df['Frequency'])
rfm_df['Monetary_log'] = np.log1p(rfm_df['Monetary'])
X_features2 = rfm_df[['Recency_log','Frequency_log','Monetary_log']]
sc2 = StandardScaler()
X_features2_sc = sc2.fit_transform(X_features2)
visualize_silhouette([2,3,4,5,6], X_features2_sc)