[AI스쿨 7기, 14주차] RFM자료, RFM, qcut, 추천도서, 추천영상(PO SESSION), 3D 그래프, K-Means, DBSCAN, Elbow Method, 실루엣, Silhouette Score, 추천시스템, 벡터의 유사도, 추천도서

hyemin·2022년 12월 21일

멋쟁이사자처럼

목록 보기
51/51

221221 멋쟁이 사자처럼 AI스쿨 7기, 박조은 강사님 강의

✅ 1202 실습 파일

📌 미리 읽어오면 좋다. http://www.itdaily.kr/news/articleView.html?idxno=8371
상위 20%가 기업 총 매출에 80%를 차지한다는 파레토 법칙
R
F : 출석 스탬프를 주는 이벤트(F를 고려한 이벤트)
M

❓ RFM 기법으로 고객을 같은 간격으로 나누려면 우리가 사용했던 판다스에서 어떤 기능을 사용하면 될까?
→ cut : 절대평가, qcut : 상대평가
→ 예를 들어 Monetary 를 기준으로 금액의 절대값이 아니라 같은 비율로 나누고자 한다면 cut, qcut? 무엇일까?
→ qcut

RFM_score 은 최저점이 3점(1, 1, 1점) 최고점이 15점(5, 5, 5점) 이 된다.
5등급으로 등간격으로 분류하는 방법이다.
RFM 각 요소의 20% rule(꼭 20% 로 적용할 필요는 없다. 비율이 회사에서 관리하기 적합한 형태로 나눠준다.)
Life Time Value(구매패턴) : 고객이 소비하는 패턴

추천도서, 영상

📚 추천도서 : 그로스해킹, LEAN ANALYTICS, 빅데이터를 활용한 예측마케팅 전략
→ 그로스해킹 저자가 린 분석을 참고했다.
→ 용어를 익히기 좋은 책이 린 분석
→ 린 분석 책을 감수한 분이 만든 47p 짜리 슬라이드가 있다.
→ 그로스해킹도 슬라이드 있다.

📌 추천영상 : PO SESSION 토스 이승건님


원본 파일은 엑셀이지만 판다스에서 50만행 이상의 엑셀파일을 불러오면 매우 느리다.
파일 사이즈는 엑셀이 더 작지만 csv 파일로 로드하는게 더 빠르다.

  • 유효 데이터 추출
    raw_valid = raw[raw["CustomerID"].notnull() & (raw["Quantity"]>0) & (raw["UnitPrice"]>0)]

  • TotalPrice
    raw_valid["TotalPrice"] = raw_valid["Quantity"] * raw_valid["UnitPrice"]

  • 이상치 제거 : 160000 보다 큰 값 제외

R => 값이 작을 수록 높은 점수를 준다. 왜냐하면 최근에 왔는지를 보기 때문에
F => 값이 높을 수록 높은 점수를 준다. 왜냐하면 자주 왔는지를 보기 때문에
M => 값이 높을 수록 높은 점수를 준다. 왜냐하면 얼마나 많은 금액을 구매했는지 보기 때문에

  • 최근 주문일
    last_timestamp = df["InvoiceDate"].max() + dt.timedelta(days=1)
    최근 영업일과 같은 날에 마지막으로 거래를 했다면 0으로 될텐데
    마지막 거래일자에 거래한 값이 1이 되게 하기 위해서 last_timestamp 에 1을 더한다.
    리텐션을 구할 때도 코호트 인덱스 값을 1로 설정한 것 처럼 0부터 시작하지 않고 1부터 시작하도록 1을 더해주었다.

  • RFM
    (last_timestamp - df["InvoiceDate"]).iloc[0].days
    (last_timestamp - df["InvoiceDate"]).iloc[-1].days

  • agg 에도 lambda나 함수를 넣을 수 있다.
    컬럼 명 변경도 .columns 해도 되고, rename 으로 해도 된다.

RFM 모형, qcut

예를 들어 문제를 틀린 갯수로 점수를 산정한다 가정했을 때
print(range(1, 11))
pd.qcut(range(1, 11), 3, labels=["good", "medium", "bad"])

고객의 R, F, M 을 1-5 점으로 만들어주고 계산을 할 예정
print(range(1,11))
pd.qcut(range(1, 11), 5, labels=range(1,6))

f_labels = list(range(1,6))
m_labels = list(range(1,6))
❓ r 값은 값이 작을 수록 5, 4, 3, 2, 1 로 점수를 준다면 어떻게 만들어야 할까?
→ r_labels = list(range(5,0,-1))

r_cut = pd.qcut(rfm["Recency"],q=cut_size,labels=r_labels)
f_cut = pd.qcut(rfm["Frequency"],q=cut_size,labels=f_labels)
m_cut = pd.qcut(rfm["MonetaryValue"],q=cut_size,labels=m_labels)

RFM Segment, Score

rfm["RFM_segment"] = rfm["R"].astype(str) + rfm["F"].astype(str) + rfm["M"].astype(str)

rfm["RFM_score"] = rfm[["R", "F", "M"]].astype(int).sum(axis=1)

3D 그래프

ax = plt.axes(projection='3d')
ax.scatter3D(rfm["R"], rfm["F"], rfm["M"])

ax = plt.axes(projection='3d')
ax.scatter3D(rfm["Recency"], rfm["Frequency"], rfm["MonetaryValue"])

✅ 1203 실습 파일

워드 임베딩을 수업하면서, 시퀀스로 벡터화 한 다음 벡터화 된 단어들이 연관이 있는지 임베딩해서 수치화하게 되는데, 그 때 '거리' 개념을 말했다.
사이킷런 클러스터링 알고리즘 : 공통 키워드가 거리

K-Means

💡 위키피디아 K-평균 알고리즘 문서
🔸입력값
k : 클러스터 수
D : n 개의 데이터 오브젝트를 포함하는 집합
출력값 : k 개의 클러스터
알고리즘
1. 데이터 오브젝트 집합 D 에서 k 개의 데이터 오브젝트를 임의로 추출하고, 이 데이터 오브젝트들을 각 클러스터의 중심으로 설정
2. D 에 대해 k 개의 클러스터 중심 오브젝트와의 거리를 각각 구하고, 각 데이터 오브젝트가 어느 중심점과 가장 유사도가 높은지 알아낸다. 그렇게 찾아낸 중심점으로 각 데이터 오브젝트들을 할당한다.
3. 클러스터 중심점을 다시 계산. 2에서 재할당된 클러스터를 기준으로 중심점 다시 계산
4. 각 데이터 오브젝트의 소속 클러스터가 바뀌지 않을 때까지 2, 3 과정 반복

❓ K-근접이웃을 어디에서 사용해 봤을까?
→ SMOTE

클러스터의 거리를 계산할 때 같은 클러스터끼리는 가까운 거리에 있어야 하고
다른 클러스터와는 멀리 떨어져 있어야지 잘 군집화가 되었다고 평가할 수 있다.
=> Elbow, 실루엣 기법 등을 사용해서 평가하게 된다.

❓이상치 탐지에 주로 사용하는 군집화 기법은 무엇일까? 1) K-means 2) 덴드로그램 3) DBSCAN
→ DBSCAN
→ 이상치는 군집에 포함시키지 않는다. 그래서 이상치 탐지에 주로 사용한다.

  • 수치 데이터 변환 시 🔥로그 변환 후 스케일링 한다.🔥

  • n_clusters 값은 1을 지정할 수 없다. 전체 데이터가 한 개의 그룹이면 클러스터링을 할 필요가 없다.

  • k-평균 클러스터링 이전에 주성분 분석(PCA)과 같은 차원 감소 알고리즘을 실행하면 차원의 저주(매우 높은 차원 공간에서는 유클리드 거리가 부풀려지는 경향) 문제를 완화하고 계산 속도를 높일 수 있다.

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

inertia = []
silhouettes = []
# range 는 1로 시작하게 할 수 없다.
range_n_clusters = range(2, 20)
for i in range_n_clusters:
    kmeans = KMeans(n_clusters=i, random_state=42)
    kmeans.fit(X)
    inertia.append(kmeans.inertia_)
    silhouettes.append(silhouette_score(X, kmeans.labels_))

반복문을 통해 nclusters를 특정 범위만큼 지정한 이유는
클러스터의 수는 사용자가 지정해야 하는 파라미터 값이다.
어느 값으로 설정해야 잘 군집화가 되었는지를 평가할 때 inertia
값을 사용한다.
군집의 중심(centroid)와 데이터 포인트간의 거리로 측정한다.
차이가 적게 나면 거리가 가깝다는 의미이기 때문에 inertia_ 값이 작게 나온다.

Elbow Method

현실 세계 데이터는 팔꿈치가 꺽이는 것처럼 값이 급격하게 낮아지게 구해지려면 전처리 등을 잘 해주어야 한다.

plt.figure(figsize=(15,4))
plt.plot(range_n_clusters, inertia)
plt.title('The Elbow Method')
plt.xlabel('Number of clusters')
plt.ylabel('Within-Cluster Sum of Square')
plt.xticks(range_n_clusters)
plt.show()

Silhouette Score 실루엣

https://scikit-learn.org/stable/auto_examples/cluster/plot_kmeans_silhouette_analysis.html

실루엣 분석은 각 군집 간 거리가 얼마나 효율적으로 분리되어 있는지를 나타낸다. 다른 군집과의 거리는 떨어져 있고, 동일 군집끼리는 가깝게 잘 뭉쳐있다면 효율적으로 잘 분리된 것. 군집화가 잘 될수록 개별 군집은 비슷한 정도의 여유공간을 가지고 떨어져 있다.
실루엣 계수 점수가 높을수록 클러스터가 잘 정의된 모델
a: 샘플과 동일한 클래스의 다른 모든 점 사이의 평균 거리
b: 표본과 다음으로 가장 가까운 군집의 다른 모든 점 사이의 평균 거리

KElbowVisualizer

https://www.scikit-yb.org/en/latest/api/cluster/elbow.html#module-yellowbrick.cluster.elbow
첫번째 방법

from yellowbrick.cluster import KElbowVisualizer

kelbow = KElbowVisualizer(kmeans, k=10)
kelbow.fit(X)

두번째 방법

from yellowbrick.cluster.elbow import kelbow_visualizer
kelbow_visualizer(kmeans, X, k=20)

❓ CAC 천원은 무슨 의미일까?
→ 유료 결제 고객 1명 확보에 들어간 비용이 천원


추천 시스템

추천시스템 실습파일은 13번 부터 시작하고
1) online-retail => movie 데이터로 실습하는 순서로 구성이 되어 있습니다.
2) output 파일을 먼저 실행해 보고 input 에 옮겨적는 스터디를 해봐도 좋겠습니다.
3) 콘텐츠 기반(01 online-retail => 02 movie) => 협업필터링(03 online-retail => 04 movie) 순으로 파일이 되어 있습니다.

deview 쿠팡 추천시스템 변천사 슬라이드

고객에 대한 빅데이터를 구축하기 시작하면서, 파레토의 법칙에서 롱테일의 법칙이 주목된다. 빅데이터를 활용하면 주목받지 못하던 80%도 집중할 수 있지 않을까.

추천시스템의 역사 : 연관상품추천 > 협업 필터링(SVD) > Spark 를 이용한 빅데이터 > 협업필터링과 딥러닝을 이용한 추천시스템 > 개인화 추천시스템

SVD : 특이값 분해. 이미지 데이터 압축, 텍스트 데이터 차원 축소로 내용은 요약하면서 데이터 용량은 줄일 때 사용한다.
문서 유사도를 사용해서 콘텐츠 베이스 추천을 하게 되면 비슷한 문서를 추천해 줄 수 있다. 해당 문서와 유사도 값이 높은 문서를 추천해 주게 된다.

❓ OTT 서비스를 오픈했는데, 오픈 초기라서 유저의 행동 정보가 없다. 어떻게 추천을 해주면 좋을까?
→ 고객이 어떤 작품을 봤다면 해당 작품의 정보를 참고해서 비슷한 작품 설명을 갖고 있는 작품을 추천한다. => 콘텐츠 기반 추천시스템.
→ 유저 정보가 쌓였다면 협업 필터링으로 넘어간다.

벡터의 유사도(Vector Similarity)

  • 유클리디안 유사도 : 유클리드 공간에서의 최단거리
    (직선거리). 유클리드 거리의 값이 가장 작다는 것은 문서 간 거리가 가장 가깝다는 것을 의미한다.
  • 코사인 유사도 : 내적 공간 내에서 두 벡터 사이의 코사인 각도를 구하는 방법. -1~ 1 사이 값. 1에 가까울수록 유사도가 높다. 벡터의 크기가 아닌 방향의 유사도를 판단하는 목적으로 사용. 방향이 완전히 같을 경우 1, 90도 각이면 0
  • 피어슨 유사도 : 두 벡터가 주어졌을 때 상관관계를 계산하며 각 벡터의 표본평균으로 정규화. 코사인 유사도를 산출하면 피어슨 유사도
  • 자카드 유사도

서비스 초기에 고객의 행동 정보가 없을 때는 콘텐츠 기반의 추천을 하고, 유저 행동 데이터가 쌓이게 되면 협업필터링을 사용하는 하이브리드 추천 방식을 사용하기도 한다.

✅ 1301 실습파일
❓ 0~1 사이 값으로 유사도가 만들어졌다. 어떤 값에 가까울 수록 유사도가 높을까? → 1

  • 특정 제품과 유사도가 높은 제품 찾기
    🔥 코드 변경해주기 n_largest => sort_values
    sim_cos = df_cosine[item_id].sort_values(ascending=False)

  • 데이터 프레임 만들기(코드변경)

df_sim_cos = df.loc[
    sim_cos.index, 
    ["StockCode", "Description"]].join(sim_cos)
df_sim_cos.drop_duplicates("Description").head(10)

❓ online-retail 데이터로 유저-아이템-행렬을 만든다면? 어떻게 만들면 될까?
행 인덱스가 user, 열이 item 이 되도록 만든다.


추천 도서

📚 책 추천
홀로 성장하는 시대는 끝났다.
http://www.yes24.com/Product/Goods/80138025
당신은 다른 사람의 성공에 기여한 적 있는가?
http://www.yes24.com/Product/Goods/98832816

머신러닝, 딥러닝(이미지, 자연어처리), 추천시스템
네이버는 CV, NLP, RecSys 선택할 수 있도록
NLP 시작 => 정통 or 추천시스템이나 시퀀스 데이터 다룰지 선택 =>

군집화를 회귀에서도 사용할 수 있을까 : B그룹에 결측치가 많다면 군집화로 채울 수도 있다. == KNN 으로 결측치를 채우거나 SMOTE랑 비슷한 느낌

target 값들이 cluster 에서 같은 값이 나오면 군집화가 잘 되었다.

지도학습 에서는 정답값-예측값 비교
비지도 군집화일 때 잘 되었는지 비교해 볼 수 있게 하는게 실루엣 분석

profile
아직 고쳐나가는 중.

0개의 댓글