AI-рекомендаційна система товарів (Collaborative Filtering) в мобільних додатках
Collaborative Filtering будується на одній ідеї: якщо два користувачі подібно оцінили товари в минулому, їх майбутні переваги теж збіжатимуться. Інформація про самі товари не потрібна — тільки матриця взаємодій "користувач × товар". Саме тому CF працює там, де Content-Based пасує: рекомендаціях фільмів, музики, контенту з неструктурованими метаданими.
Технічна суть та основні складності
Matrix Factorization як основа
Класичний CF через dot-product пошук найближчих сусідів не масштабується при >100K користувачів. Робочий підхід — розкладання матриці взаємодій на два embedding-простору: користувачі та товари представляються векторами фіксованої розмірності (зазвичай 64–256). Рекомендація — це пошук товарів, чиї embeddings найближче до embedding користувача.
Бібліотеки для навчання: Implicit (Python, спеціалізована на implicit feedback), LightFM (гібридна CF+content), RecBole (дослідницький фреймворк з 70+ алгоритмами). Для production-деплою зазвичай вибирають Implicit + FAISS для ANN-пошуку.
Cold Start — головна проблема CF
Новий користувач без історії взаємодій — типічний cold start. Стандартне рішення: перші 5–10 взаємодій використовуємо правило "популярні товари з категорії інтересу" (onboarding flow з вибором переваг). Після накопилення мінімальної історії переходимо на персоналізовану модель.
У кодемо це виглядає як стратегічний паттерн:
// Android: стратегія рекомендацій в залежності від історії
interface RecommendationStrategy {
suspend fun getRecommendations(userId: String, count: Int): List<Product>
}
class ColdStartStrategy(private val api: RecommendationApi) : RecommendationStrategy {
override suspend fun getRecommendations(userId: String, count: Int) =
api.getPopularByPreferences(userId, count)
}
class CFStrategy(private val api: RecommendationApi) : RecommendationStrategy {
override suspend fun getRecommendations(userId: String, count: Int) =
api.getPersonalized(userId, count)
}
class RecommendationRepository(private val api: RecommendationApi) {
suspend fun getRecommendations(user: User): List<Product> {
val strategy = if (user.interactionCount < 10) {
ColdStartStrategy(api)
} else {
CFStrategy(api)
}
return strategy.getRecommendations(user.id, count = 20)
}
}
Implicit vs Explicit feedback
У більшості мобільних додатків користувачі не ставлять оцінки товарам явно. Implicit feedback — просмотри, клики, додавання в корзину, час перегляду карточки товару — набагато інформативніше, але потребує правильного взвешування: просмотр без клика ≠ інтерес, клик без покупки ≠ задоволення.
Схема ваг, яку використовуємо на практиці:
| Дія | Вага |
|---|---|
| Просмотр карточки > 3 сек | 1 |
| Клик "подробніше" | 3 |
| Додавання в улюблене | 5 |
| Додавання в корзину | 7 |
| Покупка | 10 |
| Повернення | -5 |
Логування подій на клієнті
Якість CF напрямо залежить від повноти та точності логування:
// iOS: логування взаємодій з точністю до часу переглядання
class ProductInteractionTracker {
private var viewStartTime: Date?
private let analytics: AnalyticsService
func trackViewStart(productId: String) {
viewStartTime = Date()
}
func trackViewEnd(productId: String) {
guard let start = viewStartTime else { return }
let duration = Date().timeIntervalSince(start)
if duration > 3.0 {
analytics.log(InteractionEvent(
productId: productId,
type: .view,
weight: min(Int(duration / 3), 3), // cap at weight 3
timestamp: start
))
}
viewStartTime = nil
}
func trackAddToCart(productId: String) {
analytics.log(InteractionEvent(productId: productId, type: .addToCart, weight: 7))
}
}
Трекинг часу переглядання через viewStartTime дозволяє розрізняти випадкові переглядання від реального інтересу. Без цього сигналу матриця взаємодій зашумлюється випадковими даними.
Serving: FAISS для ANN-пошуку embeddings
Навчена модель експортує embeddings товарів у FAISS-індекс. При запиті рекомендацій для користувача: отримуємо його embedding → шукаємо K найближчих товарів у FAISS → фільтруємо вже куплені → повертаємо список. Latency при 1M товарів — 5–15 мс на сервері.
Процес роботи
Аудит даних: обсяг матриці взаємодій, спарсність, наявність cold start проблеми.
Налаштування event-логування на клієнтах iOS/Android.
Навчання моделі (Implicit ALS або LightFM) на історичних даних.
Розробка recommendation API + FAISS serving.
A/B тест: CF-рекомендації vs популярні товари → вимірювання CTR та конверсії.
Ориентири за часовими рамками
MVP з Implicit ALS + базовим serving — 2–3 тижні. Повна система з event-логуванням, cold start fallback, A/B тестуванням та монітором — 6–8 тижнів.







