티스토리 뷰

laravel

추천 알리고리즘

서니짱 2025. 10. 13. 11:03
반응형

1) 회원가입 시 및 운영 중 추가로 수집할 데이터 (필수 + 권장)

목적: 개인 성향 파악, 콜드스타트 해소, 모델 입력(특성) 확보

필수(最低)

  • 회원 기본정보
    • user_id (PK), 가입일, 지역(도시 단위), 언어, 연령대(또는 생년월일), 성별(선택)
  • 초기 관심사(onboarding)
    • 카테고리 체크박스(예: 기술 / 문화 / 취미 / 뉴스 / 게임 / 유머 등)
    • 선호 포맷(글/이미지/동영상/짧은글 등)
  • 뷰 로그 (event stream) — 중요
    • event_id, user_id, content_id, event_type (view, click, upvote, comment, share, dwell/read_time, scroll_depth), timestamp, device, session_id, referrer (추천·검색·홈 등)
  • 콘텐츠 메타
    • content_id, author_id, title, body_text, tags, category, created_at, language, media_type, length(글자수/재생시간), popularity_score (like_count, comment_count), explicit_flag(노골적/광고)

권장(성능 개선에 유용)

  • 사용자 행태 추가
    • 시간대 선호 (주간/야간), 세션 길이, 반복 방문 패턴
  • 소셜/관계
    • 팔로우/친구 관계, 좋아요한 사용자 목록(익명 집계)
  • 콘텐츠 임베딩
    • 텍스트 임베딩(BERT/TF-IDF), 이미지 임베딩, 오디오/비디오 특징벡터
  • 저작권/품질 지표
    • 신고/블락 여부, 리뷰 품질(스팸 점수)
  • 노출·피드백 로그
    • 어떤 추천 슬롯에 어떤 content_id를 노출했는지(노출 로그: impression), 노출후 행동(click, view 등)

2) 추천 시스템 전체 아키텍처(핵심 파이프라인)

유튜브 스타일은 크게 (A) 후보 생성(Candidate Generation)(B) 랭킹(Ranking)(C) 리랭킹 / 개인화 후처리(Re-ranking / Re-Rank) 로 구성됩니다.

A. 후보 생성 (대량 → 소량 축소)

목적: 전체 콘텐츠(수백만~수억)에서 수백~수천개 후보만 뽑아오도록 효율화

방법(혼합 전략 권장)

  1. 사용자 기반 후보
    • 최근 본/좋아요한 콘텐츠의 유사 아이템 (item-item nearest neighbors via embedding or co-watch)
    • 예: item2vec 또는 content embedding cosine top-K
  2. 협업필터링 기반
    • Matrix Factorization (ALS), 또는 최근엔 근거리 임베딩 기반(특히 two-tower) 에서 사용자 임베딩과 아이템 임베딩 유사도 상위 K
  3. 세션·순차 기반 후보
    • 마지막 N개 콘텐츠와 연관성이 높은 다음 아이템(서열 모델: GRU4Rec, SASRec)
  4. 인기·신규·트렌드
    • 전체·지역별 인기 콘텐츠, 최근 상승중인 콘텐츠 (real-time trending)
  5. 탐색용(serendipity)
    • 랜덤 / diversity pool (탐사 비율 5~15%)
  6. 스팟라이트 / 광고 / 스폰서
    • 비즈니스 정책에 따른 후보 추가

출력: user_id → 후보 리스트 (보통 200~2000개) 를 생성


B. 랭킹 (모델로 최종 점수 계산, Top-K 반환)

목적: 후보 중 최종 Top-N(예: 10~20)을 골라 UI로 노출

모델 구성 (추천)

  • 1차(대중적) Baseline: LightGBM/ XGBoost로 CTR 예측 (feature-rich)
  • 2차(고성능) Neural: Two-tower (user tower / item tower) + Ranking head (dot / MLP)
    또는 Sequence-aware 모델 (SASRec/GRU4Rec)로 시퀀스 특성 반영
  • CTR/Engagement 멀티태스크: 클릭확률(CTR) + 체류시간(WatchTime) + 좋아요 확률을 동시에 예측 (multi-task learning)
  • Loss: binary cross-entropy (CTR), regression loss for watch_time (MSE) or poisson, 또는 pairwise loss (BPR) for ranking

입력 피처 예시

  • 사용자 측(고정): user_id 임베딩, age_group, region, preferred_categories (one-hot), long-term interests(embedding)
  • 사용자 측(세션): last_N_contents embeddings, session_length, time_of_day
  • 콘텐츠 측: content_id embedding, category, tags, text_embedding(BERT), author_popularity, length
  • 상호작용 측: time_since_last_view_of_same_tag, frequency_of_tag_in_past_7d, impression_count_last_24h
  • 노출·문맥: slot_position, source (추천/검색)

출력

  • 예측 점수(s): 결합 점수 = α·CTR + β·WatchTimeNormalized + γ·DiversityPenalty + business_boost
  • 상위 N을 UI로 보냄

C. 리랭킹 / 후처리 (비즈니스 룰 + 다양성 + 필터)

  • 컷오프 필터: 이미 본 콘텐츠 재노출 정책(기간 기준)
  • 다양성 엔진: 동일 카테고리 연속 노출 방지, 저자 과도편중 방지
  • 신선도/유해콘텐츠 룰: 신고 많거나 정책 위반 의심은 노출 감소
  • 탐색 vs 개인화 비율 제어: e-greedy 또는 UCB/bandit으로 탐험 비율 조정
  • 스왑/블렌드: 유료·스폰서 콘텐츠를 일정 비율 삽입

3) 구체적 구현 예시(데이터 스키마 + 샘플 쿼리 + 모델 입출력 예)

DB 테이블(간단)

 
-- users CREATE TABLE users ( user_id BIGINT PRIMARY KEY, created_at TIMESTAMP, age_group VARCHAR, region VARCHAR, onboarding_interest JSONB ); -- contents CREATE TABLE contents ( content_id BIGINT PRIMARY KEY, author_id BIGINT, title TEXT, body TEXT, tags TEXT[], category VARCHAR, created_at TIMESTAMP, duration_seconds INT, popularity_score FLOAT ); -- events (stream) CREATE TABLE events ( event_id BIGSERIAL PRIMARY KEY, user_id BIGINT, content_id BIGINT, event_type VARCHAR, -- view, click, like, comment, share dwell_ms BIGINT, timestamp TIMESTAMP, session_id TEXT, ref VARCHAR );

후보 생성 — 예: item2vec 유사도 조회 (의사코드)

  • item2vec로 content_embedding 생성(128-d)
  • 후보: 최근 본 10개 콘텐츠 임베딩 평균 → cosine 유사도 상위 K
 
-- 의사쿼리: embedding store에서 cosine 유사도 top K SELECT content_id, cosine_sim(embedding, user_recent_embedding) AS sim FROM content_embeddings ORDER BY sim DESC LIMIT 100;

Two-tower 입력 예 (Python pseudocode)

 
# user_vector = concat(user_emb, avg_recent_item_emb, time_of_day, ...) # item_vector = concat(item_emb, content_meta_features) score = dot(user_vector, item_vector) # 또는 MLP([user, item, user*item, ...]) prob = sigmoid(score)

4) 학습·평가 지표 / 오프라인 실험

핵심 지표

  • CTR (Click-through rate) — 클릭 전환율
  • WatchTime / Dwell time — 평균 체류시간(우선순위 중요)
  • NDCG@k, MRR, Precision@k — 랭킹 품질
  • Recall@k (Candidate generation 평가) — 후보 생성의 커버리지
  • DAU/Retention — 장기적 지표

오프라인 평가

  • Time-split: train on [T-30, T-7], validate on [T-7, T-1], test on day T
  • Negative sampling: for CTR train, sample negative items that user did NOT interact with in the session (注意: careful sampling bias)
  • Offline metric: Recall@200 (candidate) / NDCG@10 (ranker)
  • Calibration: 로그의 노출 편향(CTR 편향) 보정(IPS, propensity weighting)

5) 온라인 배포·A/B 테스트

  • 실시간 서빙: 모델을 서빙(예: TensorFlow Serving, TorchServe, FastAPI + Redis cache)
  • Latencies: candidate retrieval (100-300ms), ranking (10-50ms per user)
  • A/B 실험: 핵심 KPI (CTR, WatchTime, Retention) 기반으로 실험 (유의수준, 트래픽 분할)
  • 로그 추적: 모든 노출(impression)→행동(click/view)을 이벤트로 남겨서 오프라인 학습 재사용

6) 콜드스타트 전략

  • 신규 사용자
    • 온보딩 질문(카테고리 선호) 강제 수집 + 추천 팩 기반 노출
    • 인기/지역별 인기 + 유사 사용자 군집(popular among similar age/region)
  • 신규 콘텐츠
    • 콘텐츠 임베딩(text/image) 기반 유사도로 빠르게 카테고리 연결
    • 초기 exposure boost(신규 부스트) 후 품질 관찰

7) 탐험(Exploration) vs 착취(Exploitation)

  • Epsilon-greedy: 일정 확률(epsilon=0.05~0.15)로 탐색용 후보 섞기
  • Contextual Bandits: LinUCB, Thompson Sampling 등으로 온라인 보상 최적화 (CTR 기반)
  • Diversity penalties: 유사한 콘텐츠 연속 노출 방지

8) 공정성·안전·프라이버시

  • 필터링: 유해/스팸 확률 높은 콘텐츠는 노출 억제
  • 개인정보: PII 비식별화, 로그 보관기간 정책(예: 90일), GDPR/개인정보보호법 준수
  • 유저 제어: 관심분야 수정, 추천 피드백(싫어요/숨기기) UI 제공

9) 실무 체크리스트(우선순위 로드맵)

  1. 로그 파이프라인 구축 (impression + event + content metadata) — 우선
  2. 간단한 랭킹 baseline (popularity + recency)으로 제품 테스트
  3. 간단한 후보 생성: item2vec 또는 co-watch 통계
  4. LightGBM CTR 랭커 (feature engineering 빠르게 적용)
  5. Two-tower 모델으로 전환(성능 개선)
  6. 세션/순차 모델 추가 (SASRec) — 개인화 향상
  7. 온라인 A/B 실험 루프 구축(모델 교체 및 KPI 검증)
  8. 탐색 전략 / 다양성 / 비즈니스 룰 통합
  9. 모니터링: 품질 저하/데이터 드리프트 알람

10) 구현 팁(구체적인 하이퍼·설정 제안)

  • 임베딩 차원: 64~256 (item/user)
  • 학습률(Neural): 1e-3 ~ 3e-4 (Adam)
  • batch size: 512~8192 (데이터·GPU에 따라)
  • negative samples: 4~10 negatives per positive (pairwise/BPR)
  • candidate pool size: 200~2000 (서비스 규모에 따라)
  • Top-N to UI: 10~20

11) 간단한 시작용 추천 알고리즘 (빠르게 만들어볼 수 있는 3단계)

  1. 로그 수집(1주): impression + click + dwell + content metadata
  2. 베이스라인(1주): (A) 인기+최근성 혼합 → (B) 간단한 item-item 추천 (co-occurrence)
  3. 첫 모델(2~4주): LightGBM 랭커(CTR 예측) + candidate: item2vec top-200
    → 이후 Two-tower, sequence model 단계적으로 교체

12) 예시: 추천 점수(단순 가중 결합)

  • score = 0.5 * CTR_pred + 0.4 * normalized_watch_time_pred + 0.1 * novelty_score
  • novelty_score = (is_new? 1 : 0) or recency function exp(-age_days/7)
반응형
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2026/05   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함
반응형