Реалізація AI-рекомендаційної системи контенту (Content-Based) у мобільному додатку

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Реалізація AI-рекомендаційної системи контенту (Content-Based) у мобільному додатку
Складний
~1-2 тижні
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

AI-рекомендаційна система контенту (Content-Based) в мобільних додатках

Content-Based Filtering не потребує даних про інших користувачів — будує профіль конкретного користувача на основі характеристик контенту, з яким той взаємодіяв. Для нових додатків без накопленої користувальницької базри це часто єдиний робочий варіант рекомендацій з першого дня.

Коли Content-Based переважає Collaborative Filtering

Три сценарії, де CB-підхід переважніший:

Нішевий контент з унікальними метаданими. Статті, рецепти, туристичні маршрути — кожний айтем має багатий набір атрибутів (теги, категорії, автори, локації). CF працює на сигналі "користувачі схожі", але для нішевого контенту схожих користувачів може бути замало.

Privacy-first архітектура. CB може працювати повністю на пристрої — профіль користувача зберігається локально, рекомендації будуються без відправки даних на сервер.

Довгий хвіст контенту. Нова стаття, опублікована час назад, не має історії взаємодій для CF. CB рекомендує її одразу, як тільки метаданні проіндексовані.

Ядро системи: представлення контенту та користувача

TF-IDF та embeddings для текстового контенту

Для статей, описів, новин — два підходи: TF-IDF для швидкості, sentence embeddings для якості. На практиці використовуємо sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 (278 MB, підтримує російську): кожний айтем перетворюється на 384-мірний вектор.

from sentence_transformers import SentenceTransformer

model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')

def embed_article(article: Article) -> np.ndarray:
    text = f"{article.title}. {article.description}. {' '.join(article.tags)}"
    return model.encode(text, normalize_embeddings=True)

# Косинусна подібність через numpy
def similarity(v1: np.ndarray, v2: np.ndarray) -> float:
    return float(np.dot(v1, v2))  # нормалізовані вектори, dot = cosine

Профіль користувача — скользящее середнє embeddings

Профіль користувача — це взвешене середнє embeddings контенту, з яким він взаємодіяв. Недавні взаємодії важать більше (експоненціальне затухання):

def update_user_profile(profile: np.ndarray, new_item_embedding: np.ndarray,
                         interaction_weight: float, decay: float = 0.9) -> np.ndarray:
    updated = decay * profile + (1 - decay) * interaction_weight * new_item_embedding
    return updated / np.linalg.norm(updated)  # перенормалізуємо

On-device рекомендації на iOS через CoreML

Для невеликих каталогів (до 50K айтемів) весь CB-пошук можна вивести на пристрій:

// iOS: локальний CB-пошук без мережевих запитів
class OnDeviceRecommender {
    private let userProfileKey = "user_embedding_v2"
    private var itemIndex: [(id: String, embedding: [Float])] = []

    func loadItemIndex(from url: URL) {
        // загружаємо передвичислені embeddings при запуску
        let data = try! Data(contentsOf: url)
        itemIndex = try! JSONDecoder().decode([(id: String, embedding: [Float])].self, from: data)
    }

    func getRecommendations(count: Int) -> [String] {
        guard let profileData = UserDefaults.standard.data(forKey: userProfileKey),
              let profile = try? JSONDecoder().decode([Float].self, from: profileData)
        else { return popularItemIds(count: count) }

        return itemIndex
            .map { item in (item.id, cosineSimilarity(profile, item.embedding)) }
            .sorted { $0.1 > $1.1 }
            .prefix(count)
            .map { $0.0 }
    }

    private func cosineSimilarity(_ a: [Float], _ b: [Float]) -> Float {
        zip(a, b).map(*).reduce(0, +)  // припускаємо нормалізовані вектори
    }
}

Embeddings індекс оновляється при старті додатка або за розкладом — загружаємо JSON з передвичисленими векторами з сервера (~20 MB для 50K айтемів × 384d float32).

Структуровані метаданні: не тільки текст

Для каталогу товарів текстові embeddings доповнюються категоріальними ознаками: категорія, бренд, ціновий діапазон, колір. Остаточний вектор — конкатенація нормалізованого текстового embedding та one-hot/ordinal ознак:

def build_item_vector(item: Product) -> np.ndarray:
    text_emb = embed_text(f"{item.name} {item.description}")  # 384-dim
    cat_features = encode_categorical({
        'category': item.category_id,
        'brand': item.brand_id,
        'price_range': bucket_price(item.price)  # [0-500, 500-2000, 2000+]
    })  # ~50-dim
    return np.concatenate([text_emb * 0.7, cat_features * 0.3])  # взвешена конкатенація

Процес роботи

Аналіз структури контенту: які метаданні доступні, їх якість та повнота.

Вибір моделі embeddings під мову та домен.

Побудова індексу та механізму оновлення профілю користувача.

Рішення про on-device vs серверні рекомендації в залежності від розміру каталогу та вимог до privacy.

Ориентири за часовими рамками

Серверний CB з готовими embeddings та API — 1–1,5 тижня. On-device варіант для iOS/Android з локальним індексом — 2–3 тижні. Гібрид з частковою on-device обробкою — 3–4 тижні.