AI

[AI 도전기 18일차] 코사인 유사도 구하기

alsruds 2024. 5. 6. 19:33

드디어 코사인 유사도 기반으로 음식 추천하는 방식을 이해해 왔어요 :-) 오예

 

🚀 순서

1. 사용할 음식 데이터 파일 전처리하기

2. 사용자가 선호하는 음식 카테고리를 입력받아 다시 한 번 전처리

3. 해당 음식 파일을 벡터로 나타내기

4. 사용자 선호도를 벡터로 나타내기

5. 코사인 유사도 계산하기

6. 유사도가 가장 큰 음식 추천

 


 

1️⃣ 

🏠 2024.04.28 - [AI] - [AI 도전기 17일차] 음식 데이터 전처리하기

 

[AI 도전기 17일차] 음식 데이터 전처리하기

📍 오늘 할 일 📍음식 영양 정보 데이터에서 내가 필요한 정보만 남겨두자 ! 📎사용한 데이터 📎 전국통합식품영양성분정보(음식)표준데이터   😭 시행착오들....⬇️⬇️⬇️⬇️⬇️⬇

alsrudalsrudalsrud.tistory.com

 

 

2️⃣

사용자가 선호하는 음식 카테고리로 다시 한 번 전처리하겟슴니당 !

# 사용자가 선호하는 음식 카테고리로 전처리하기
# 사용자가 선호하는 카테고리가 '구이류' 라고 할 때 -> 나중에 입력값으로 받기
preferred_data = selected_data[selected_data['식품대분류명'] == '구이류']

 

아직은 백엔드와 연결을 안했기 때문에.. ㅎㅎ 선호하는 음식 카테고리를 임의로 선택!

 

 

3️⃣

음식의 특성을 벡터로 나타내기 위해서 저는 Min-Max Scaling 을 이용하여 0과 1 사이 값으로 변환하기로 했어요

데이터의 최솟값을 0으로! 최댓값을 1로 변환하여 데이터를 일정한 범위 내에 배치하는 정규화 방법입니닷

 

선호하는 음식 카테고리마다, 영양 성분마다 특성의 범위가 다를 수 있기 때문에

해당 카테고리를 선택한 후에 각각의 영양 성분에 최대 최소값을 적용하기로 했어요

# 해당 파일의 각 음식을 벡터 값으로 나타내기
# 각각의 특성을 0과 1 사이값으로 정규화 (min-max scaling)
# 최대 최소값 알아내기
kcal_max = preferred_data[['에너지(kcal)']].max().values[0]
kcal_min = preferred_data[['에너지(kcal)']].min().values[0]

carbo_max = preferred_data[['탄수화물(g)']].max().values[0]
carbo_min = preferred_data[['탄수화물(g)']].min().values[0]

protein_max = preferred_data[['단백질(g)']].max().values[0]
protein_min = preferred_data[['단백질(g)']].min().values[0]

fat_max = preferred_data[['지방(g)']].max().values[0]
fat_min = preferred_data[['지방(g)']].min().values[0]

 

정규화 표를 새로 생성!

# 정규화 표 생성하기
normalized_data = preferred_data[['식품명']].copy()
normalized_data['에너지(kcal)_정규화'] = (preferred_data['에너지(kcal)'] - kcal_min) / (kcal_max - kcal_min)
normalized_data['탄수화물(g)_정규화'] = (preferred_data['탄수화물(g)'] - carbo_min) / (carbo_max - carbo_min)
normalized_data['단백질(g)_정규화'] = (preferred_data['단백질(g)'] - protein_min) / (protein_max - protein_min)
normalized_data['지방(g)_정규화'] = (preferred_data['지방(g)'] - fat_min) / (fat_max - fat_min)

 

호호.. 뭐가 되고 있네요 !_!

 

 

4️⃣

일단 사용자 벡터를 임의로 가정하겠습니다!

[ 권장 칼로리, 권장 탄수화물, 권장 단백질, 권장 지방 ] 이렇게용

# 사용자 벡터가 있다고 가정 ex)[0.5, 0.5, 0.1, 0.7] -> 나중에 입력받아 변환 
# 코사인 유사도 계산하기

# 사용자 벡터
user_vector = np.array([0.5, 0.5, 0.1, 0.7])

 

 

5️⃣

새로 만든 정규화 표에서 '식품명' 을 제외하고..

# 음식의 정규화된 특성 벡터
food_vectors = normalized_data[['에너지(kcal)_정규화', '탄수화물(g)_정규화', '단백질(g)_정규화', '지방(g)_정규화']].values

 

각각의 음식 벡터와 코사인 유사도 값을 계산해줍니다!

# 각 음식과 사용자 벡터 간의 코사인 유사도 계산
cosine_similarities = np.dot(food_vectors, user_vector) / (np.linalg.norm(food_vectors, axis=1) * np.linalg.norm(user_vector))

 

 

6️⃣

여기서 유사도가 가장 높은 음식을 추출하면 ~~~~

# 가장 유사한 음식 찾기
most_similar_food_index = np.argmax(cosine_similarities)
most_similar_food_name = preferred_data.iloc[most_similar_food_index]['식품명']
most_similar_food_similarity = cosine_similarities[most_similar_food_index]

print("가장 유사한 음식:", most_similar_food_name)
print("유사도:", most_similar_food_similarity)

 

핳... 나왓당... 😭

 

다음은 Flask 에 코드 적용한 후 백엔드와 연동하는 모습으로 찾아오겠습니다 ^.^