최종 프로젝트 트러블슈팅 - 와인 추천 로직(2)

노재원·2024년 9월 4일
0

내일배움캠프

목록 보기
85/90

Embedding 인풋 튜닝

어설프게 'Embedding으로 추천 로직을 구현할 수 있겠다!' 라고만 생각을 가지고 시작했기에 우선 본격적으로 Embedding에 대한 이해도부터 쌓기로 했다.

그 과정으로 인풋을 분리하면서부터 시작해봤다.

수치가 바뀌면 유사도가 크게 바뀌는가?

input1: "sweetness: 1"
input2: "sweetness: 5"
"similarity": 0.8617905483856242

input1: "sweetness: 1, acidity: 1, body: 1, tannin: 1"
input2: "sweetness: 5, acidity: 5, body: 5, tannin: 5"
"similarity": 0.9191116344041206

Embedding을 잘못 이해해서 생긴 이슈로 그냥 유사한 텍스트가 많아지기 때문에 수치랑 관련없이 텍스트가 길어지고 겹치는 부분이 많아지면 수치랑 별개로 유사도가 차이가 유의미하게 생겨버린다.

그래서 텍스트를 줄여봤다.

input1: "1, 1, 1, 1, "RED""
input2: "5, 5, 5, 5, "WHITE""
"similarity": 0.7077243483003013

input1: "1, 1, 1, 1, "RED""
input2: "2, 2, 2, 2, "RED""
"similarity": 0.8994053676336877

텍스트를 줄이고 나면 수치와 타입등으로 겹치는 부분에 따라 현저히 유사도가 차이가 벌어지게 된다. 그래서 사용자가 보지 않아도 될 인풋에 굳이 텍스트 안내를 포함하지는 않아도 되겠구나 라고 생각을 했다.

이후 이전 포스팅에서 썼던 인풋의 형태를 그대로 수치만 건드려서 테스트를 해봤다.

input1: "sweetness: 1, acidity: 1, body: 1, tannin: 1, type: RED, aroma: {lemon=[시트러스], pineapple=[열대과일, 파인애플], flower=[아카시아, 꽃], stone=[미네랄], ripen=[꿀]}, price: 100000, kind: 알바리뇨"
input2: "sweetness: 3, acidity: 1, body: 3, tannin: 1, type: RED, aroma: {lemon=[시트러스], pineapple=[파인애플], flower=[아카시아], stone=[미네랄], ripen=[꿀]}, price: 500000, kind: 알바리뇨"
"similarity": 0.9813840073573221

input1: "sweetness: 1, acidity: 1, body: 1, tannin: 1, type: RED, aroma: {lemon=[시트러스], pineapple=[열대과일, 파인애플], flower=[아카시아, 꽃], stone=[미네랄], ripen=[꿀]}, price: 100000, kind: 알바리뇨"
input2: "sweetness: 5, acidity: 5, body: 5, tannin: 5, type: RED, aroma: {lemon=[시트러스], pineapple=[파인애플], flower=[아카시아], stone=[미네랄], ripen=[꿀]}, price: 500000, kind: 알바리뇨"
"similarity": 0.9702990022385684

이렇게 수치만 바꿔도 유사도의 차이가 발생하는 걸 보고 이렇게 하면 되겠구나! 라고 생각했었다. (물론 아니고 이후 튜닝 과정에서 싹 다 빠지게 된다.)

튜닝1: 데이터 수치를 크게 잡아보기

기존 와인 데이터의 수치는 1~5 내에서의 값만 갖고 있어서 유사도의 차이를 더 크게 하고 싶으면 100을 곱해서 인풋으로 넣어봤다.

input1: "sweetness: 100, acidity: 100, body: 100, tannin: 100, type: RED, aroma: {lemon=[시트러스], pineapple=[열대과일, 파인애플], flower=[아카시아, 꽃], stone=[미네랄], ripen=[꿀]}, price: 100000, kind: 알바리뇨"
input2: "sweetness: 300, acidity: 100, body: 300, tannin: 100, type: RED, aroma: {lemon=[시트러스], pineapple=[파인애플], flower=[아카시아], stone=[미네랄], ripen=[꿀]}, price: 500000, kind: 알바리뇨"
"similarity": 0.9714583013080693

input1: "sweetness: 100, acidity: 100, body: 100, tannin: 100, type: RED, aroma: {lemon=[시트러스], pineapple=[열대과일, 파인애플], flower=[아카시아, 꽃], stone=[미네랄], ripen=[꿀]}, price: 100000, kind: 알바리뇨"
input2: "sweetness: 500, acidity: 500, body: 500, tannin: 500, type: RED, aroma: {lemon=[시트러스], pineapple=[파인애플], flower=[아카시아], stone=[미네랄], ripen=[꿀]}, price: 500000, kind: 알바리뇨"
"similarity": 0.9629096497717027

숫자가 커진다고 유사도에 유의미할 만큼 차이가 크게 발생하진 않았다. 그래서 이 튜닝은 폐기됐다.

물론 임베딩의 성격을 생각해보면 당연한건데 트러블슈팅 과정이라 전혀 감을 못잡았었다.

튜닝2: Kind 빼보기

인풋의 대상을 줄여서 조금 더 수치적인 데이터에 집중해보겠다고 Kind를 빼보게 됐었다.

input1: "sweetness: 1, acidity: 1, body: 1, tannin: 1, type: RED, aroma: {lemon=[시트러스], pineapple=[열대과일, 파인애플], flower=[아카시아, 꽃], stone=[미네랄], ripen=[꿀]}, price: 100000"
input2: "sweetness: 3, acidity: 1, body: 3, tannin: 1, type: RED, aroma: {lemon=[시트러스], pineapple=[파인애플], flower=[아카시아], stone=[미네랄], ripen=[꿀]}, price: 500000"
"similarity": 0.9714740953104094

input1: "sweetness: 1, acidity: 1, body: 1, tannin: 1, type: RED, aroma: {lemon=[시트러스], pineapple=[열대과일, 파인애플], flower=[아카시아, 꽃], stone=[미네랄], ripen=[꿀]}, price: 100000"
input2: "sweetness: 5, acidity: 5, body: 5, tannin: 5, type: RED, aroma: {lemon=[시트러스], pineapple=[파인애플], flower=[아카시아], stone=[미네랄], ripen=[꿀]}, price: 500000"
"similarity": 0.958816754260851

간단한 값만 있어도 유사도 차이가 나는데 굳이 인풋에서 대상을 빼봤자 유사도가 정확한지 아닌지 체크하기는 부족했다. 애초에 수치가 달라지는 것에는 영향을 받고 있었다.

튜닝3: Key 값을 전부 제거하기

input1: "1, 1, 1, 1, RED, {lemon=[시트러스], pineapple=[열대과일, 파인애플], flower=[아카시아, 꽃], stone=[미네랄], ripen=[꿀]}, 100000, 알바리뇨"
input2: "3, 1, 3, 1, RED, {lemon=[시트러스], pineapple=[파인애플], flower=[아카시아], stone=[미네랄], ripen=[꿀]}, 500000, 알바리뇨"
"similarity": 0.9685879494011795

input1: "1, 1, 1, 1, RED, {lemon=[시트러스], pineapple=[열대과일, 파인애플], flower=[아카시아, 꽃], stone=[미네랄], ripen=[꿀]}, 100000, 알바리뇨"
input2: "5, 5, 5, 5, RED, {lemon=[시트러스], pineapple=[파인애플], flower=[아카시아], stone=[미네랄], ripen=[꿀]}, 500000, 알바리뇨"
"similarity": 0.9524340499416417

겹치는 부분이 줄어들어 유사도가 조금 줄어들긴 했으나 사실 딱히 차이가 나진 않았다.

향기의 key도 전부 제거하기

input1: "1, 1, 1, 1, RED, {[시트러스], [열대과일, 파인애플], 아카시아, 꽃], [미네랄], [꿀]}, 100000, 알바리뇨"
input2: "3, 1, 3, 1, RED, {[시트러스], [파인애플], [아카시아], [미네랄], [꿀]}, 500000, 알바리뇨"
"similarity": 0.9150122442827834

input1: "1, 1, 1, 1, RED, {[시트러스], [열대과일, 파인애플], 아카시아, 꽃], [미네랄], [꿀]}, 100000, 알바리뇨"
input2: "5, 5, 5, 5, RED, {[시트러스], [파인애플], [아카시아], [미네랄], [꿀]}, 500000, 알바리뇨"
"similarity": 0.886654153682611

기본적으로 겹치는 값이 현저히 줄어든 만큼 가장 유사도가 작긴 해서 이 때는 방향성을 이걸로 가기로 했던 걸로 기억한다.

결론

이 때 당시의 결론은 수치의 차이가 유사도에서 유의미할 정도로 크게 벌어지진 않길래 겹치는 텍스트를 적게 한다고 인풋 튜닝을 해야겠다고 생각했었다. 이 생각은 나중 포스팅에서 완전 새로 공부해서 바뀌게 됐다.

0개의 댓글