LG U+ 유레카 종합 프로젝트로 맞춤형 요금제 추천 서비스
요기U+를 개발하면서, 추천 시스템 개발 과정에서 겪었던 트러블슈팅에 대한 회고를 정리하는 글입니다.
사용자에게 딱 맞는 요금제를 추천하는 것이 저희 서비스의 핵심 목표이었습니다. 이를 위해 사용자와 요금제의 특성을 벡터로 만들고, 두 벡터 간의 유사도를 계산해 가장 적합한 요금제를 찾아냅니다. 이때 어떤 방식으로 유사도를 계산하느냐에 따라 추천의 정확도가 크게 달라집니다.
이번 글에서는 기존에 사용하던 코사인 유사도에서 유클리드 거리 기반 방식으로 전환하게 된 배경과 그 이유를 정리해보려고 합니다.
먼저 사용자와 요금제를 비교 가능한 형태로 만들기 위해 특성 벡터(Feature Vector) 를 구성합니다. 사용자 측은 데이터 사용량, 월 평균 사용량, 희망 가격대, 테더링 사용량 등의 요소를, 요금제 측은 제공 데이터량, 월정액, 테더링 용량 등을 반영해 벡터를 만듭니다.
각 항목의 단위나 스케일이 다르기 때문에, 모든 값을 0~1 범위로 정규화하여 공정하게 비교할 수 있도록 처리합니다.
// 사용자 특성 벡터 생성
public double[] createUserFeatureVector(UserPreferenceDto pref, double avgDataUsage) {
return new double[] {
normalizer.normalizeDataUsage(targetUsage),
normalizer.normalizePrice(pref.getPreferencePrice()),
normalizer.normalizeSharedDataUsage(pref.getPreferenceSharedDataUsage())
};
}
// 요금제 특성 벡터 생성
public double[] createPlanFeatureVector(PlanDto plan) {
return new double[] {
normalizer.normalizeDataUsage(planDataAllowance),
normalizer.normalizePrice(plan.getMonthlyFee()),
normalizer.normalizeSharedDataUsage(plan.getTetheringDataAmount()),
};
}
이제 두 벡터 간의 유사도를 계산하면 추천 기준이 됩니다.
처음에는 널리 사용되는 코사인 유사도를 적용했습니다. 코사인 유사도는 두 벡터의 방향이 얼마나 유사한지를 기반으로 유사도를 계산합니다.
// 코사인 유사도 계산
public double calculateCosineSimilarity(double[] vector1, double[] vector2) {
double dotProduct = 0.0;
double norm1 = 0.0;
double norm2 = 0.0;
// 계산 로직 생략
return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
}
하지만 실제로 적용해보니 한계가 있었습니다. 예를 들어, 사용자가 희망하는 요금이 3만 원이고 추천된 요금제가 10만 원인 경우, 수치상 큰 차이가 있음에도 방향이 비슷하다는 이유로 높은 유사도로 판단되는 경우가 있었습니다. 즉, 절대적인 값 차이를 잘 반영하지 못하는 문제가 있었습니다.
이 문제를 보완하기 위해, 방향이 아닌 실제 거리를 기준으로 하는 유클리드 거리 방식으로 변경했습니다. 유클리드 거리는 두 벡터 간의 직선 거리를 계산해, 각 항목의 차이를 직접적으로 반영합니다.
// 유클리드 거리 기반 유사도 계산
public double calculateEuclideanSimilarity(double[] vector1, double[] vector2) {
double distance = 0.0;
for (int i = 0; i < vector1.length; i++) {
distance += Math.pow(vector1[i] - vector2[i], 2);
}
distance = Math.sqrt(distance);
return 1.0 / (1.0 + distance);
}
거리 값이 작을수록 두 벡터가 더 가깝다는 의미이기 때문에, 이를 바탕으로 1 / (1 + distance) 형태로 유사도를 계산합니다.
요약하자면, 요금제 추천처럼 각 요소의 절대적인 차이가 중요한 문제에서는 방향보다 거리를 기준으로 하는 방식이 더 적합했습니다.
유클리드 거리 방식으로 전환한 이후 내부 테스트에서 추천 정확도가 높아졌고, 사용자 선호를 더 정밀하게 반영할 수 있었습니다. 앞으로도 데이터의 특성을 면밀히 분석하고, 가장 효과적인 방식으로 반영해 나가겠습니다.