Loading backend/src/route/utils/recommendations.ts 0 → 100644 +70 −0 Original line number Diff line number Diff line import { RecommendPlace } from '../dto/recommend-route.dto'; import { DataFrame, Series } from './math'; import { customSort } from './sort'; export class RecommendationsSystem { getCategories(places: RecommendPlace[]): number[] { const categories = new Set<number>(); for (const place of places) { for (const category of place.categories) { categories.add(category); } } return Array.from(categories); } oneHotEncode(categories: number[], placesToEncode: RecommendPlace[]): DataFrame { const data: DataFrame = {}; for (const category of categories) { data[category] = []; for (const place of placesToEncode) { data[category].push(place.categories.includes(category) ? 1 : 0); } } return data; } rankVisited(visited: RecommendPlace[]): Series { const visitedCategories = this.getCategories(visited); const visitedEncoded = this.oneHotEncode(visitedCategories, visited); const grades = visited.map((place) => place.grade); const dataframe: DataFrame = visitedEncoded; const result: Series = {}; for (const category in dataframe) { result[category] = dataframe[category].reduce((sum, value, index) => sum + value * grades[index], 0); } const sumResult = Object.values(result).reduce((a, b) => a + b, 0); for (const category in result) { result[category] /= sumResult; } return result; } rankCandidates(candidates: RecommendPlace[], visited: Series): [number, number][] { const visitedCategories = Object.keys(visited).map(Number); const candidatesEncoded = this.oneHotEncode(visitedCategories, candidates); const dataframe: DataFrame = candidatesEncoded; const result: number[] = candidates.map((_, i) => { return visitedCategories.reduce((sum, category) => { return sum + dataframe[category][i] * visited[category]; }, 0); }); let ranked: [number, number][] = candidates.map((place, i) => [place.idPlace, result[i]]); ranked.sort(customSort); return ranked; } recommend(visited: RecommendPlace[], candidates: RecommendPlace[]) { const visitedRanking = this.rankVisited(visited); const candidatesRanked = this.rankCandidates(candidates, visitedRanking); return candidatesRanked; } } Loading
backend/src/route/utils/recommendations.ts 0 → 100644 +70 −0 Original line number Diff line number Diff line import { RecommendPlace } from '../dto/recommend-route.dto'; import { DataFrame, Series } from './math'; import { customSort } from './sort'; export class RecommendationsSystem { getCategories(places: RecommendPlace[]): number[] { const categories = new Set<number>(); for (const place of places) { for (const category of place.categories) { categories.add(category); } } return Array.from(categories); } oneHotEncode(categories: number[], placesToEncode: RecommendPlace[]): DataFrame { const data: DataFrame = {}; for (const category of categories) { data[category] = []; for (const place of placesToEncode) { data[category].push(place.categories.includes(category) ? 1 : 0); } } return data; } rankVisited(visited: RecommendPlace[]): Series { const visitedCategories = this.getCategories(visited); const visitedEncoded = this.oneHotEncode(visitedCategories, visited); const grades = visited.map((place) => place.grade); const dataframe: DataFrame = visitedEncoded; const result: Series = {}; for (const category in dataframe) { result[category] = dataframe[category].reduce((sum, value, index) => sum + value * grades[index], 0); } const sumResult = Object.values(result).reduce((a, b) => a + b, 0); for (const category in result) { result[category] /= sumResult; } return result; } rankCandidates(candidates: RecommendPlace[], visited: Series): [number, number][] { const visitedCategories = Object.keys(visited).map(Number); const candidatesEncoded = this.oneHotEncode(visitedCategories, candidates); const dataframe: DataFrame = candidatesEncoded; const result: number[] = candidates.map((_, i) => { return visitedCategories.reduce((sum, category) => { return sum + dataframe[category][i] * visited[category]; }, 0); }); let ranked: [number, number][] = candidates.map((place, i) => [place.idPlace, result[i]]); ranked.sort(customSort); return ranked; } recommend(visited: RecommendPlace[], candidates: RecommendPlace[]) { const visitedRanking = this.rankVisited(visited); const candidatesRanked = this.rankCandidates(candidates, visitedRanking); return candidatesRanked; } }