각 제품을 설명하는 단어 모음이 있다면 간단한 추천 모델 개발이 가능합니다.
아래 예시는 제품별 상세 내역 이미지에서 문장을 추출한 뒤 전처리를 한 결과입니다.
prod_seq는 제품별 고유 넘버이며 text_new는 각 제품의 키워드를 담은 리스트입니다.
여기서 인덱싱의 편의를 위해 prod_seq를 index로 설정하였음을 기억해 주세요.
아래 데이터프레임을 df 변수로 지정합니다.
진행 과정은 아래와 같습니다.
1. 키워드를 전부 꺼내 고유값을 제거한 하나의 리스트로 만듭니다.
2. row는 prod_seq로, columns는 각 키워드 하나하나로 구성된 데이터 프레임을 생성합니다.
3. 신규 생성한 데이터프레임에서 제품별 키워드가 존재할 경우 1, 없으면 0으로 표기합니다.
4. 제품 간 코사인 유사도를 계산하여 유사한 정도를 구합니다.
5. 지정한 제품과 유사도가 높은 순으로 타 제품을 추천합니다.
유사도 비교를 위한 매트릭스 만들기
# 키워드들을 하나의 리스트로 합치기
total_keywords = list(set(df['text_new'].sum()))
total_keywords
>>
['물화', '금방', '날로', '냉면', '한번', '볼스터', '크랩', '조로', '뚝딱',...]
먼저 text_new 컬럼에 포함된 리스트를 모두 더하여(sum) 하나의 리스트로 만들어 줍니다.
그런 뒤 set으로 감싸주면 자연스레 중복값이 제거되고, 이를 다시 리스트로 감싸줍니다.
리스트 전체 길이는 12,248입니다.
import pandas as pd
import numpy as np
# 빈 매트릭스 만들기
prod_list = df.index.values
zerodata = np.zeros((len(prod_list), len(total_keywords)))
matrix = pd.DataFrame(data=zerodata, index=prod_list, columns=total_keywords)
# 제품별 키워드 존재 유무 확인 (포함 시 1, 미포함 시 0)
for i in index:
matrix.loc[i, df.loc[i, 'text_new']] = 1
matrix
위 코드를 통해 0으로 가득찬 2차원 메트릭스를 생성하여 데이터 프레임으로 변환하고,
각 제품별 포함 키워드에 인덱싱하여 값을 1로 변경해 줍니다.
그렇게 하면 위와 같은 결과를 얻을 수 있습니다.
13712 제품을 보시면 '한번' 이라는 키워드를 가지고 있었기에 1로 표기 된 것을 확인할 수 있습니다.
대부분 0으로 되어있어 당황하실 수 있지만 컬럼 수가 무려 12,248개나 되기 때문에 각 제품의 키워드가
어딘가에는 반드시 포함되어 있습니다.
from numpy.linalg import norm
def cos_sim(A, B):
return (A @ B) / (norm(A) * norm(B))
위 코드는 두 제품의 벡터 간 코사인 유사도를 구해주는 함수입니다.
A와 B자리에 0과 1로 구성된 벡터값을 각각 넣어주면 코사인 유사도값을 출력합니다.
prod = 9453 # 유사도 측정 대상
cal_result = []
for idx in matrix.index:
cal_result.append(cos_sim(matrix.loc[prod], matrix.loc[idx]))
# 유사도 높은 순으로 제품 리스트를 출력합니다.
top_k_idx = np.argsort(np.array(cal_result))[::-1]
top_prod_list = prod_list[top_k_idx]
top_prod_list
>>
array([ 9453, 557, 9573, 9572, 8860, 9481, 6788, 7061, 8864,
9576, 6791, 9534, 7254, 9558, 9472, 9495, 9538, 9507,...])
9453 제품과 유사한 제품에는 어떤 것들이 있는지 확인해 보는 코드입니다.
먼저 for문을 통해 지정한 제품과 모든 제품 각각에 대한 유사도를 계산해서 cal_result 리스트에 append 합니다.
이렇게 하면 9453제품과 matrix의 첫번째 row였던 190번 제품 간 유사도를 가장 먼저 계산한 뒤
결과값을 cal_result에 넣고, 그 다음에는 252번 제품과 유사도를 계산하는 순으로 진행됩니다.
그런 다음 cal_result를 numpy array로 변환하여 argsort 함수를 적용합니다.
argsort 함수는 코사인 유사도 결과 출력에서 유용하게 사용되는데,
해당 array 를 오름차순으로 정렬한 뒤, 각 요소의 정렬 전 인덱스 번호를 출력해 줍니다.
예를들어 np.array([2, 1, 3]) 을 argsort할 경우 [1, 0, 2]를 출력해 줍니다.
값을 기준으로 정렬한 뒤 가장 작은 숫자 1의 이전 위치였던 1번 인덱스가 맨 앞자리에 옵니다.
argsort를 내름차순으로 재정렬하기 위해 [::-1]을 적용한 뒤 top_k_idx 변수로 지정합니다.
top_k_idx의 요소는 미리 생성해 둔 prod_list(제품 번호 리스트)를 기준으로 한 인덱스 넘버로 볼 수 있으므로
prod_list에 top_k_idx를 인덱싱해 주면 인덱스 번호를 제품 번호로 치환하게 됩니다.
제품 번호를 조회해보면 가장 1순위로 지정 제품 본인이 위치하게 되고, 그 밑으로 유사도 높은 순으로
제품 추천이 잘된 것을 확인할 수 있습니다.
단순히 같은 단어를 포함하고 있고, 없고의 차이를 통한 유사도를 계산했다 보니 메이커 이름으로 예상되는
'보만' 단어가 포함된 제품이 다수 추천된 것을 확인할 수 있습니다.
'파이썬 코딩 한줄' 카테고리의 다른 글
pyenv와 virtualenv 활용법 (for Mac) (0) | 2023.01.10 |
---|---|
함수에서 *args 와 **kwargs를 알아보자 (0) | 2022.11.03 |
[pandas apply] 텍스트를 일정 길이만큼 잘라서 분리하기 (0) | 2022.10.14 |
아직도 셀레니움(Selenium)에서 벗어나지 못했다면... (0) | 2022.10.10 |
파이썬 groupby로 요소 모아 보기 (단순 집계 이상으로 활용하기) (0) | 2022.09.21 |