[javascript] Ramda를 활용한 추천 시스템 개발

추천 시스템은 사용자에게 관심 있는 항목을 추천해주는 중요한 기능입니다. 이를 위해 데이터 처리와 분석에 대한 효율적인 라이브러리는 필수입니다. 이번 포스트에서는 JavaScript의 함수형 프로그래밍 라이브러리인 Ramda를 활용하여 추천 시스템을 개발하는 방법에 대해 알아보겠습니다.

Ramda 소개

Ramda는 JavaScript의 함수형 프로그래밍을 보다 편리하게 해주는 라이브러리입니다. Immutable 데이터와 순수 함수를 지향하는 Ramda는 데이터의 변이를 최소화하고, 함수의 재사용성과 가독성을 높이는데 탁월한 성능을 발휘합니다.

추천 시스템 개발

추천 시스템은 주어진 사용자와 항목 간의 상호작용 데이터를 기반으로 가장 유사한 항목을 추천하는 과정을 포함합니다. 이를위해 다음과 같은 단계로 추천 시스템을 개발할 수 있습니다.

1. 데이터 전처리

데이터 전처리는 추천 시스템의 가장 중요한 단계입니다. Ramda에서는 다양한 함수를 제공하여 데이터를 처리할 수 있습니다. 예를 들어, map, filter, reduce 함수를 활용하여 데이터를 변형하고 원하는 형태로 가공할 수 있습니다.

const users = [
  { id: 1, name: "John", age: 30 },
  { id: 2, name: "Jane", age: 25 },
  { id: 3, name: "Tom", age: 40 }
];

const filteredUsers = R.filter(user => user.age > 20, users);
// [{ id: 1, name: "John", age: 30 }, { id: 2, name: "Jane", age: 25 }, { id: 3, name: "Tom", age: 40 }]

const userNames = R.map(user => user.name, filteredUsers);
// ["John", "Jane", "Tom"]

const totalAge = R.reduce((acc, user) => acc + user.age, 0, filteredUsers);
// 95

2. 유사도 계산

유사도 계산은 추천 시스템의 핵심 알고리즘입니다. Ramda에서는 zipWith, map, reduce, pipe 등의 함수를 활용하여 유사도를 계산할 수 있습니다. 예를 들어, 두 벡터의 유사도를 계산하는 함수는 다음과 같이 작성할 수 있습니다.

const vec1 = [1, 2, 3];
const vec2 = [4, 5, 6];

const dotProduct = R.pipe(
  R.zipWith((a, b) => a * b),
  R.reduce((acc, val) => acc + val, 0)
);

const norm = R.pipe(
  R.map(x => x * x),
  R.reduce((acc, val) => acc + val, 0),
  Math.sqrt
);

const similarity = (vec1, vec2) => dotProduct(vec1, vec2) / (norm(vec1) * norm(vec2));

const similarityScore = similarity(vec1, vec2);
// 0.9746318461970762

3. 추천 항목 결정

유사도 계산을 통해 각 항목과의 유사도를 계산한 후, 가장 유사한 항목을 추천할 수 있습니다. 예를 들어, 다음과 같이 사용자의 선호도와 각 항목과의 유사도를 고려하여 추천 항목을 결정할 수 있습니다.

const userPreferences = [
  { itemId: 1, rating: 4 },
  { itemId: 2, rating: 5 },
  { itemId: 3, rating: 3 }
];

const itemSimilarities = [
  { itemId: 1, similarity: 0.8 },
  { itemId: 2, similarity: 0.6 },
  { itemId: 3, similarity: 0.7 }
];

const recommendedItems = R.pipe(
  R.map(pref => {
    const sim = R.find(R.propEq("itemId", pref.itemId))(itemSimilarities);
    return { itemId: pref.itemId, score: sim.similarity * pref.rating };
  }),
  R.sort((a, b) => b.score - a.score)
)(userPreferences);

// [{ itemId: 2, score: 3 }, { itemId: 3, score: 2.1 }, { itemId: 1, score: 1.6 }]

결론

Ramda를 활용하여 추천 시스템을 개발할 수 있습니다. 함수형 프로그래밍의 장점을 살려 데이터 처리와 유사도 계산을 효율적으로 수행할 수 있습니다. Ramda의 다양한 함수를 익히고 활용하여 추천 시스템을 개발해보세요.

참고자료