추천시스템 라이브러리 Recbole Deep Dive

RecBole은 파이토치(PyTorch) 기반의 오픈 소스 추천 시스템 라이브러리입니다. 이 프레임워크는 연구자와 개발자들이 최신 추천 알고리즘을 쉽게 구현하고 실험할 수 있도록 설계되었으며, 다양한 추천 시스템 모델을 통합하고, 표준화된 방식으로 이들을 평가하고 비교할 수 있는 플랫폼을 제공합니다.

최근 추천 시스템 개발에서는 다양한 접근 방식과 알고리즘을 실험하고 비교하는 것이 필수적입니다. RecBole은 이러한 요구사항을 충족시키기 위해 개발되었다고 할 수 있으며, 학계와 산업계 모두에서 널리 사용되고 있습니다.

RecBole: 추천 시스템 구축을 위한 종합 가이드

1. RecBole 소개

RecBole 개요

RecBole은 파이토치(PyTorch) 기반의 오픈 소스 추천 시스템 라이브러리입니다. 이 프레임워크는 연구자와 개발자들이 최신 추천 알고리즘을 쉽게 구현하고 실험할 수 있도록 설계되었으며, 다양한 추천 시스템 모델을 통합하고, 표준화된 방식으로 이들을 평가하고 비교할 수 있는 플랫폼을 제공합니다.

최근 추천 시스템 개발에서는 다양한 접근 방식과 알고리즘을 실험하고 비교하는 것이 필수적입니다. RecBole은 이러한 요구사항을 충족시키기 위해 개발되었다고 할 수 있으며, 학계와 산업계 모두에서 널리 사용되고 있습니다.

왜 RecBole을 추천 시스템에 사용할까?

RecBole은 여러 가지 독특한 장점을 제공합니다. 첫째, 광범위한 알고리즘 라이브러리를 제공하여 사용자가 다양한 추천 접근 방식을 쉽게 실험할 수 있습니다. 일반적인 협업 필터링부터 최신 딥러닝 기반 모델까지, RecBole은 폭넓은 알고리즘을 지원합니다.

둘째, RecBole은 표준화된 데이터 처리 파이프라인을 제공합니다. 이는 데이터 전처리, 모델 학습, 평가에 이르는 전체 과정을 일관된 방식으로 처리할 수 있게 해줍니다. 이러한 표준화는 실험의 재현성을 높이고, 다른 연구자들과의 결과 비교를 용이하게 합니다.

마지막으로, RecBole은 다양한 확장성을 제공합니다. 대규모 데이터셋에서도 효율적으로 동작하며, 사용자 정의 모델과 평가 메트릭을 쉽게 추가할 수 있습니다.

RecBole의 주요 기능과 장점

RecBole의 핵심 기능은 크게 네 가지 범주로 나눌 수 있습니다:

  1. 통합된 데이터 처리:
from recbole.data import create_dataset, data_preparation
# 데이터셋 생성
dataset = create_dataset('ml-100k')
# 데이터 준비
train_data, valid_data, test_data = data_preparation(dataset)
  1. 다양한 모델 지원:
from recbole.model.general_recommender import BPR
# BPR 모델 초기화
model = BPR(config, dataset)
  1. 유연한 학습 프로세스:
from recbole.trainer import Trainer
# 트레이너 초기화 및 학습
trainer = Trainer(config, model)
trainer.fit(train_data)

2. 설치 및 환경 설정

시스템 요구사항

RecBole을 설치하기 전에 다음과 같은 기본 요구사항을 확인해야 합니다:

  • Python 3.7 이상
  • PyTorch 1.7.0 이상
  • CUDA 지원 (GPU 사용 시)
  • 최소 8GB RAM (데이터셋 크기에 따라 다름)

이러한 요구사항은 다음 코드로 확인할 수 있습니다:

import sys
import torch

print(f"Python 버전: {sys.version}")
print(f"PyTorch 버전: {torch.__version__}")
print(f"CUDA 사용 가능: {torch.cuda.is_available()}")
pip을 통한 RecBole 설치

RecBole은 pip를 통해 쉽게 설치할 수 있습니다:

pip install recbole
<참고> 개발 환경 설정하기

개발 환경을 효율적으로 설정하기 위해서는 가상 환경을 사용하는 것이 좋습니다.

# 가상환경 생성
python -m venv recbole-env

# 가상환경 활성화 (Windows)
recbole-env\Scripts\activate

# 가상환경 활성화 (Linux/Mac)
source recbole-env/bin/activate

# 필요한 패키지 설치
pip install recbole torch numpy pandas scikit-learn

권장 프로젝트 구조:

recbole-project/
├── data/
│ ├── raw/
│ └── processed/
├── models/
│ └── saved/
├── configs/
│ └── model_config.yaml
├── src/
│ ├── train.py
│ └── evaluate.py
└── requirements.txt
설치 확인 및 자주 발생하는 문제 해결

설치가 정상적으로 완료되었는지 확인하기 위해 다음 테스트 코드를 실행해볼 수 있습니다:

import recbole
from recbole.quick_start import run_recbole

# 설치 버전 확인
print(f"RecBole 버전: {recbole.__version__}")

# 간단한 모델 실행 테스트
try:
    run_recbole(model='BPR', dataset='ml-100k')
    print("RecBole 설치 및 실행 성공!")
except Exception as e:
    print(f"오류 발생: {str(e)}")

3. RecBole 프레임워크 이해하기

RecBole의 핵심 아키텍처

RecBole은 모듈화된 설계를 통해 확장성과 유연성을 제공합니다. 주요 컴포넌트는 다음과 같습니다:

  1. 데이터 레이어: 데이터 로딩, 전처리, 샘플링을 담당
  2. 모델 레이어: 다양한 추천 알고리즘 구현
  3. 트레이닝 레이어: 모델 학습 및 검증 프로세스 관리
  4. 평가 레이어: 다양한 평가 메트릭 계산
import torch
from recbole.data import create_dataset, data_preparation
from recbole.model.general_recommender import BPR
from recbole.trainer import Trainer
from recbole.config import Config

# 설정 파일 로드 및 데이터셋 설정
config = Config(model='BPR', dataset='ml-100k')

# GPU 사용 여부를 확인하여 장치를 설정합니다.
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
config['device'] = device  # RecBole 설정에 장치를 명시적으로 지정합니다.

# 데이터셋을 생성합니다.
dataset = create_dataset(config)

# 데이터셋의 기본 정보와 interaction features 출력 (데이터가 제대로 로드되었는지 확인)
print("Dataset Info:")
print(dataset)

# interaction features의 첫 5개 데이터 확인
print("\nInteraction Features (First 5 rows):")
print(dataset.inter_feat.head())

# 데이터셋을 학습/검증/테스트 데이터로 나눕니다.
train_data, valid_data, test_data = data_preparation(config, dataset)

# 모델 초기화 및 장치로 이동
model = BPR(config, train_data.dataset).to(device)

# 트레이너 초기화
trainer = Trainer(config, model)

# 학습 및 평가
trainer.fit(train_data, valid_data)

지원되는 모델 및 알고리즘

RecBole은 다양한 일반 추천 모델을 지원합니다:

from recbole.model.general_recommender import (
    BPR,  # Bayesian Personalized Ranking
    LightGCN,  # Light Graph Convolution Network
    EASE,  # Embarrassingly Shallow AutoEncoder
)

# BPR 모델 예제
config['model'] = 'BPR'
bpr_model = BPR(config, dataset)

# NCF 모델 예제
config['model'] = 'NNCF'
ncf_model = NCF(config, dataset)
1. ADMMSLIM (Alternating Direction Method of Multipliers for SLIM)
  • SLIM(Sparse Linear Method) 모델의 확장판으로, ADMMSLIM은 추천 행렬의 희소성(sparsity)을 최적화하는 방법으로 ADM(Alternating Direction Method)을 사용하여 추천 성능을 개선합니다.
2. BPR (Bayesian Personalized Ranking)
  • 사용자-아이템 상호작용 데이터를 순위 학습 방식으로 최적화하는 모델로, 사용자에게 선호될 가능성이 높은 아이템을 랭킹하도록 학습합니다. 협업 필터링에 최적화된 방식입니다.
3. CDAE (Collaborative Denoising AutoEncoder)
  • Denoising AutoEncoder를 기반으로 하는 협업 필터링 모델로, 입력 데이터의 노이즈를 제거하여 사용자와 아이템 간의 관계를 학습합니다.
4. ConvNCF (Convolutional Neural Collaborative Filtering)
  • 협업 필터링에 CNN(Convolutional Neural Network)을 결합하여, 사용자와 아이템의 잠재 표현을 더 깊이 있게 학습하는 모델입니다.
5. DGCF (Disentangled Graph Collaborative Filtering)
  • 그래프 기반 협업 필터링으로, 사용자와 아이템 간의 관계를 다양한 측면으로 나누어 학습해 더 정교한 추천을 수행합니다.
6. DMF (Deep Matrix Factorization)
  • Deep Learning을 활용한 Matrix Factorization 모델로, 사용자와 아이템의 잠재 표현을 깊이 있게 학습하여 협업 필터링 성능을 향상시킵니다.
7. DiffRec (Differentiable Recommendation)
  • 추천 시스템의 차분 가능성을 활용하여, 더 효과적으로 추천 행렬을 최적화하는 모델입니다.
8. EASE (Embarrassingly Shallow AutoEncoder)
  • 매우 단순한 구조의 선형 오토인코더 기반 모델로, 높은 계산 효율성과 간결함을 추구하면서도 뛰어난 성능을 보입니다.
9. ENMF (Explicit Non-negative Matrix Factorization)
  • 명시적인 비음수 제약을 추가하여 사용자와 아이템 간의 관계를 학습하는 Matrix Factorization 모델입니다.
10. FISM (Factored Item Similarity Models)
  • 아이템 기반 협업 필터링 모델로, 각 아이템의 유사성을 학습하여 사용자에게 관련된 아이템을 추천합니다.
11. GCMC (Graph Convolutional Matrix Completion)
  • 그래프 신경망(GCN)을 사용하여 사용자와 아이템 간의 관계를 그래프 구조로 학습하고 이를 통해 추천을 수행하는 모델입니다.
12. ItemKNN (Item-based k-Nearest Neighbors)
  • 아이템 간의 유사성을 기반으로 추천하는 모델로, 각 사용자에게 가장 유사한 아이템을 추천합니다. 단순하면서도 효과적인 방식입니다.
13. DiffRec (Differentiable Recommendation)
  • 연속적 미분 가능성을 기반으로 추천 행렬을 최적화하는 모델로, 높은 표현력을 갖춘 추천 시스템입니다.
14. LightGCN (Light Graph Convolutional Networks)
  • GCN 기반 협업 필터링의 경량화 버전으로, 더 단순한 그래프 구조를 사용하여 효율성을 높인 모델입니다.
15. LINE (Large-scale Information Network Embedding)
  • 대규모 그래프 데이터를 효율적으로 학습하기 위해 설계된 모델로, 사용자와 아이템 간의 관계를 그래프 임베딩으로 표현합니다.
16. MacridVAE (Macroscopic Regularized VAE)
  • 사용자 그룹 수준의 정보와 개별 사용자 정보를 동시에 학습하여 정밀한 추천을 수행하는 변분 오토인코더(VAE) 기반 모델입니다.
17. MultiDAE (Denoising AutoEncoder for Multimodal Data)
  • 변분 오토인코더 구조를 사용해 사용자-아이템 상호작용 데이터의 노이즈를 제거하여 더 정교한 추천을 가능하게 합니다.
18. MultiVAE (Variational Autoencoder for Collaborative Filtering)
  • VAE를 사용하여 사용자와 아이템 간의 복잡한 분포를 학습하며, 추천 성능을 높이는 변분 오토인코더 기반 모델입니다.
19. NAIS (Neural Attentive Item Similarity Model)
  • 사용자와 아이템 간의 유사도를 Neural Attention 메커니즘을 사용해 학습하는 모델로, 협업 필터링의 성능을 향상시킵니다.
20. NCE-PLRec (Noise Contrastive Estimation Personalized Ranking)
  • 노이즈 대조 추정(NCE)을 활용해 사용자에게 맞춤화된 아이템 순위를 예측하는 모델입니다.
21. NCL (Neural Collaborative Learning)
  • 협업 필터링과 신경망 구조를 결합하여 사용자와 아이템 간의 비선형 상호작용을 학습하는 모델입니다.
22. NeuMF (Neural Matrix Factorization)
  • MF와 MLP(Multi-Layer Perceptron)를 결합하여 선형과 비선형 상호작용을 모두 학습하는 신경망 기반의 협업 필터링 모델입니다.
23. NGCF (Neural Graph Collaborative Filtering)
  • GCN을 활용해 사용자와 아이템 간의 관계를 학습하며, 사용자-아이템 그래프 구조를 통해 더욱 정교한 추천을 수행하는 모델입니다.
24. NNCF (Neural Network Collaborative Filtering)
  • 신경망 기반의 협업 필터링 모델로, 사용자와 아이템 간의 상호작용을 심층 신경망을 통해 학습합니다.
25. Pop (Popularity-based Recommendation)
  • 가장 인기가 많은 아이템을 추천하는 단순한 모델로, 추가적인 학습 없이 아이템의 인기도를 기반으로 추천을 수행합니다.
26. RaCT (Ranking-based Collaborative Training)
  • 순위 기반 학습 방식을 사용하여 추천 행렬을 최적화하는 모델로, 사용자 선호도에 맞춘 랭킹 학습에 최적화되어 있습니다.
27. Random (Random Recommendation)
  • 임의의 아이템을 사용자에게 추천하는 모델로, 성능은 낮지만 기본 베이스라인 모델로 사용될 수 있습니다.
28. RecVAE (Recommender Variational AutoEncoder)
  • 변분 오토인코더를 사용하여 추천 시스템을 최적화하는 모델로, 사용자와 아이템 간의 상호작용의 복잡한 분포를 학습합니다.
29. SGL (Self-supervised Graph Learning for Recommendation)
  • 자가 지도 학습과 그래프 신경망을 결합하여 그래프 기반 추천을 수행하며, 일반화 성능을 높이는 모델입니다.
30. SimpleX (Simple and Explainable Model)
  • 단순하고 해석 가능한 추천 모델로, 가벼운 계산량과 해석 가능성을 갖추고 있습니다.
31. SLIMElastic (Sparse Linear Methods with Elastic Net Regularization)
  • SLIM의 확장 모델로, Elastic Net 정규화를 사용하여 희소성(sparsity)과 일반화 성능을 동시에 높이는 모델입니다.
32. SpectralCF (Spectral Collaborative Filtering)
  • 사용자-아이템 그래프의 스펙트럼 정보를 활용해 협업 필터링을 수행하는 모델로, 고유값 분해 등을 통해 그래프의 구조를 학습합니다.
순차 추천 모델

순차적 패턴을 고려하는 모델들도 지원됩니다:

from recbole.model.sequential_recommender import (
    GRU4Rec,  # GRU for Sequential Recommendation
    BERT4Rec,  # BERT for Sequential Recommendation
    SASRec,  # Self-Attention based Sequential Recommendation
)

# 순차 추천 모델 설정
config['model'] = 'GRU4Rec'
sequential_model = GRU4Rec(config, dataset)

BERT4Rec

  • BERT의 Transformer 아키텍처를 사용하여 시퀀스 데이터에서 다음 아이템을 예측하는 모델입니다.

Caser

  • CNN(Convolutional Neural Network)을 사용해 시퀀스 데이터를 학습하며, 사용자의 최근 상호작용을 기반으로 다음 아이템을 예측합니다.

CORE (Contextual Recurrent Model)

  • 시퀀스 데이터에서 컨텍스트 정보를 결합하여 사용자의 행동을 예측하는 모델입니다.

DIN (Deep Interest Network)

  • 사용자의 최근 상호작용을 동적으로 가중치를 부여해 사용자의 관심사를 학습하고, 이를 바탕으로 추천을 수행합니다.

FDSA (Feature Diversified Self-Attention)

  • Self-Attention 메커니즘을 통해 사용자의 다양한 관심사를 반영하는 추천 모델입니다.

FOSSIL (Factored Sequential Prediction Model)

  • Markov Chain과 MF(Matrix Factorization)를 결합하여 시퀀스 기반의 예측을 수행합니다.

FPMC (Factorized Personalized Markov Chains)

  • 사용자-아이템 간의 관계를 Markov Chain과 MF를 결합해 모델링한 시퀀스 추천 모델입니다.

GCSAN (Gated Collaborative Self-Attention Network)

  • Self-Attention과 Gated Mechanism을 결합하여 시퀀스 데이터를 학습하고, 중요도를 반영한 예측을 수행합니다.

GRU4Rec

  • GRU(Recurrent Neural Network)를 사용해 시퀀스 데이터를 학습하며, 사용자의 다음 행동을 예측합니다.

GRU4RecF

  • GRU4Rec의 확장판으로, 추가적인 기능과 정교한 학습 메커니즘을 통해 성능을 개선한 모델입니다.

GRU4RecKG

  • GRU4Rec에 지식 그래프를 결합하여 사용자 행동 예측에 추가적인 컨텍스트 정보를 반영합니다.

HGN (Hierarchical Gating Network)

  • 계층적 게이팅 메커니즘을 통해 사용자의 행동 패턴을 학습하며, 다중 수준의 정보를 활용해 추천을 수행합니다.

HRM (Hierarchical Representation Model)

  • 계층적 표현 학습을 통해 사용자의 행동을 예측하며, 최근 및 장기 상호작용을 동시에 고려합니다.

KSR (Knowledge-enhanced Sequential Recommendation)

  • 시퀀스 기반 추천에 지식 정보를 결합하여, 더 정교한 사용자 행동 예측을 수행합니다.

NARM (Neural Attentive Recommendation Machine)

  • 시퀀스 데이터에 Attention 메커니즘을 적용하여 사용자의 최근 행동에 기반한 추천을 수행합니다.

NextItNet

  • CNN을 기반으로 시퀀스 데이터를 학습하며, 사용자의 다음 행동을 예측하는 구조를 가집니다.

NPE (Neural Personalized Embedding)

  • 사용자의 시퀀스 데이터를 Embedding 방식으로 학습하여, 다음 아이템을 예측합니다.

RepeatNet

  • 사용자의 반복 행동 패턴을 학습하여, 반복된 구매 또는 상호작용을 예측하는 모델입니다.

S3Rec (Self-Supervised Sequential Recommendation)

  • 자가 지도 학습 방식을 사용해 사용자의 행동 시퀀스에서 의미 있는 표현을 학습하는 모델입니다.

SASRec (Self-Attentive Sequential Recommendation)

  • Self-Attention 메커니즘을 통해 사용자의 시퀀스 행동을 학습하여, 다음 행동을 예측하는 모델입니다.

SASRecF

  • SASRec의 확장판으로, 더 많은 기능을 추가해 시퀀스 기반 예측 성능을 개선한 모델입니다.

SHAN (Short-term and Long-term Attention Network)

  • 사용자의 단기 및 장기 행동을 모두 반영하여, 두 가지 수준의 관심사를 통합한 추천을 수행합니다.

SRGNN (Session-based Recommendation with Graph Neural Network)

  • GNN을 사용해 사용자의 세션 데이터에서 그래프 구조를 학습하며, 이를 통해 추천 성능을 향상시킵니다.

STAMP (Short-term Attention/Memory Priority)

  • 사용자 행동 시퀀스에서 단기 메모리와 주의 메커니즘을 사용해 사용자 행동을 예측하는 모델입니다.

TransRec (Translation-based Recommendation)

  • 시퀀스 데이터에서 Translation 메커니즘을 사용해 사용자 행동의 변화와 이동을 모델링합니다.

FEARec (Feature-Enriched Attentive Sequential Recommendation)

  • 시퀀스 데이터에서 Self-Attention과 피처 정보를 결합해 더 풍부한 정보를 활용하여 예측하는 모델입니다.
컨텍스트 기반 및 지식 기반 모델

컨텍스트 정보와 지식 그래프를 활용하는 모델들:

from recbole.model.context_aware_recommender import (
    FM,  # Factorization Machine
    DeepFM,  # Deep Factorization Machine
)

# FM 모델 설정
config['model'] = 'FM'
context_model = FM(config, dataset)

# 지식 그래프 기반 설정
config['model'] = 'KGAT'
kg_model = KGAT(config, dataset)

AFM (Attentional Factorization Machine)

  • Factorization Machine(FM) 기반 모델로, 사용자와 아이템의 상호작용에 대한 중요도를 학습하기 위해 Attention 메커니즘을 도입한 모델입니다.

AutoInt

  • 자동으로 피처 간의 상호작용을 학습하고, Self-Attention 메커니즘을 활용해 다양한 상호작용을 효과적으로 캡처하는 모델입니다.

DCN (Deep & Cross Network)

  • 깊은 신경망과 교차 네트워크 구조를 결합하여, 피처 간의 복잡한 상호작용을 학습하고 효율적인 예측을 가능하게 합니다.

DCN V2

  • DCN의 개선된 버전으로, 더 많은 피처 상호작용을 학습할 수 있도록 구조가 확장된 모델입니다.

DeepFM

  • FM과 심층 신경망을 결합하여, 선형 상호작용과 비선형 상호작용을 동시에 학습하는 추천 모델입니다.

DSSM (Deep Structured Semantic Model)

  • 사용자와 아이템의 특징을 각각 학습하고, 유사도를 계산하여 추천을 수행하는 심층 신경망 기반 모델입니다.

EulerNet

  • 비선형 특성 간의 상호작용을 학습하기 위한 구조로, 더 깊고 복잡한 피처 관계를 캡처하는 모델입니다.

FFM (Field-aware Factorization Machine)

  • FM의 확장 버전으로, 각 피처 필드(field) 간의 관계를 학습하여 더 정교한 예측을 가능하게 합니다.

FiGNN (Field-aware Graph Neural Network)

  • FFM과 GNN(Graph Neural Network)을 결합하여, 피처 필드 간의 관계를 그래프 구조로 학습하는 모델입니다.

FM (Factorization Machine)

  • 피처 간의 2차 상호작용을 학습하여 예측하는 모델로, 간단하면서도 효과적인 성능을 보입니다.

FNN (Factorization-supported Neural Network)

  • FM의 출력을 신경망의 입력으로 사용하여, 선형 및 비선형 상호작용을 동시에 학습하는 구조를 갖춘 모델입니다.

FwFM (Field-weighted Factorization Machine)

  • 각 피처 필드의 중요도를 가중치로 부여하여, 필드 간의 관계를 효과적으로 학습하는 FM 기반 모델입니다.

KD_DAGFM (Knowledge Distillation Directed Acyclic Graph FM)

  • 지식 증류(Knowledge Distillation)와 DAG 구조를 결합하여, FM을 확장하고 예측 성능을 향상시킨 모델입니다.

LR (Logistic Regression)

  • 가장 기본적인 회귀 모델로, 피처와 타겟 간의 관계를 선형 함수로 학습하여 예측합니다.

NFM (Neural Factorization Machine)

  • FM에 신경망 구조를 추가하여, 피처 간의 비선형 상호작용을 학습할 수 있는 확장된 모델입니다.

PNN (Product-based Neural Network)

  • 피처 간의 곱셈(product) 연산을 신경망 구조에 결합하여, 피처 간의 복잡한 관계를 학습합니다.

WideDeep

  • 선형 모델(Wide)과 심층 신경망(Deep)을 결합하여, 선형성과 비선형성을 동시에 학습하는 추천 모델입니다.

xDeepFM

  • DeepFM의 확장 버전으로, 피처 간의 상호작용을 압축된 구조로 학습하여 더 복잡한 관계를 캡처합니다.

4. RecBole을 위한 데이터 준비

지원되는 데이터셋 형식

RecBole은 다양한 형식의 데이터를 지원합니다. 기본적으로 다음과 같은 파일 형식을 처리할 수 있습니다:

  1. Atomic Files: 기본적인 상호작용 데이터
  2. Token-based Files: 토큰화된 시퀀스 데이터
  3. Knowledge-based Files: 지식 그래프 데이터
# 데이터셋 설정 예제
config = {
    'load_col': {
        'inter': ['user_id', 'item_id', 'rating', 'timestamp'],
        'user': ['user_id', 'age', 'gender', 'occupation'],
        'item': ['item_id', 'category', 'title', 'genre']
    },
    'USER_ID_FIELD': 'user_id',
    'ITEM_ID_FIELD': 'item_id',
    'RATING_FIELD': 'rating',
    'TIME_FIELD': 'timestamp'
}

# 데이터셋 생성
dataset = create_dataset('custom_dataset', config=config)
사용자 데이터 준비 및 가져오기

RecBole에서 커스텀 데이터셋을 사용하기 위해서는 적절한 형식으로 데이터를 준비해야 합니다. 일반적으로 다음과 같은 형식이 사용됩니다:

import pandas as pd

# 상호작용 데이터 예시
inter_df = pd.DataFrame({
    'user_id': [1, 1, 2, 2, 3],
    'item_id': [101, 102, 102, 103, 101],
    'rating': [4.0, 3.5, 5.0, 2.0, 3.0],
    'timestamp': [1624243200, 1624329600, 1624416000, 1624502400, 1624588800]
})

# 사용자 정보 데이터 예시
user_df = pd.DataFrame({
    'user_id': [1, 2, 3],
    'age': [25, 30, 35],
    'gender': ['M', 'F', 'M']
})

# 아이템 정보 데이터 예시
item_df = pd.DataFrame({
    'item_id': [101, 102, 103],
    'category': ['electronics', 'books', 'fashion'],
    'price': [199.99, 29.99, 49.99]
})

# CSV 파일로 저장
inter_df.to_csv('data/inter.csv', index=False)
user_df.to_csv('data/user.csv', index=False)
item_df.to_csv('data/item.csv', index=False)
데이터 전처리 기법
결측치 처리

RecBole은 다양한 결측치 처리 방법을 제공합니다:

# 설정 파일에서 결측치 처리 방법 정의
config = {
    'fill_nan': True,
    'numeric_fill_na_strategy': 'mean',  # 수치형 데이터 평균값으로 채우기
    'categorical_fill_na_strategy': 'most_frequent',  # 범주형 데이터 최빈값으로 채우기
    'fill_nan_value': {
        'price': 0,  # 특정 필드 커스텀 값으로 채우기
        'category': 'unknown'
    }
}

# 데이터셋 생성 시 결측치 처리
dataset = create_dataset('custom_dataset', config=config)
범주형 특성 인코딩

범주형 데이터는 자동으로 인코딩됩니다:

# 범주형 특성 인코딩 설정
config = {
    'alias_of_user_id': ['user'],  # user_id의 별칭 설정
    'alias_of_item_id': ['item'],  # item_id의 별칭 설정
    'encoding_field': ['gender', 'category'],  # 인코딩할 필드 지정
    'token_delimiter': ' '  # 토큰 구분자 설정
}

# 인코딩된 데이터 확인
dataset = create_dataset('custom_dataset', config=config)
print(dataset.fields_encoding_map)  # 인코딩 매핑 확인
정규화 및 스케일링

수치형 특성의 정규화와 스케일링:

# 정규화 설정
config = {
    'normalize_field': ['price', 'age'],  # 정규화할 필드
    'normalize_type': 'min-max',  # 정규화 방식 (min-max 또는 z-score)
}

# 데이터 정규화 적용
dataset = create_dataset('custom_dataset', config=config)

Config Parameters

일반 설정 (General Settings)
  • model: 사용하고자 하는 추천 모델의 이름입니다. 예: 'BPR', 'MF', 'LightGCN' 등.
  • dataset: 사용할 데이터셋의 이름입니다. RecBole에서 제공하는 내장 데이터셋 또는 사용자 지정 데이터셋 이름을 지정합니다.
  • data_path: 데이터셋 파일이 위치한 디렉토리의 경로입니다.
  • checkpoint_dir: 모델 체크포인트를 저장할 디렉토리입니다.
  • save_model: 학습된 모델을 저장할지 여부를 결정하는 불리언 값입니다.
  • load_model: 저장된 모델 체크포인트를 로드할지 여부를 결정하는 불리언 값입니다.
  • seed: 재현성을 위한 랜덤 시드 값입니다.
  • device: 학습 및 평가에 사용할 장치입니다. 'cpu' 또는 'cuda'로 설정합니다.

데이터 설정 (Data Settings)
  • field_separator: 데이터셋 파일에서 필드를 구분하는 구분자입니다. 예: '\t', ',' 등.
  • seq_separator: 시퀀스 필드에서 아이템을 구분하는 구분자입니다.
  • USER_ID_FIELD: 데이터셋에서 사용자 ID를 나타내는 필드 이름입니다.
  • ITEM_ID_FIELD: 데이터셋에서 아이템 ID를 나타내는 필드 이름입니다.
  • TIME_FIELD: 타임스탬프를 나타내는 필드 이름입니다.
  • RATING_FIELD: 평점 점수를 나타내는 필드 이름입니다.
  • LABEL_FIELD: 레이블을 나타내는 필드 이름입니다. 분류 작업 등에 사용됩니다.
  • NEG_PREFIX: 부정적 샘플의 필드 이름에 사용되는 접두사입니다.
  • LIST_SUFFIX: 리스트 타입 필드의 접미사입니다.
  • MAX_USER_INTER_NUM: 사용자당 최대 상호작용 수입니다. 이 값을 초과하는 상호작용은 잘립니다.
  • MIN_USER_INTER_NUM: 사용자당 최소 상호작용 수입니다. 이 값보다 적은 상호작용을 가진 사용자는 제거됩니다.
  • MAX_ITEM_INTER_NUM: 아이템당 최대 상호작용 수입니다.
  • MIN_ITEM_INTER_NUM: 아이템당 최소 상호작용 수입니다.
  • lowest_val: 평점 데이터셋에서 가능한 최저 평점 값입니다.
  • highest_val: 가능한 최고 평점 값입니다.
  • sparse_features: 희소 특성 필드의 이름 목록입니다.
  • dense_features: 밀집 특성 필드의 이름 목록입니다.
  • interactions_order: 상호작용 데이터를 정렬하는 기준입니다. 'user', 'time' 등으로 설정합니다.

데이터 전처리 설정 (Data Preprocessing Settings)
  • normalize_field: 정규화할 필드의 목록입니다.
  • normalize_all: 모든 밀집 필드를 정규화할지 여부를 결정하는 불리언 값입니다.
  • fill_na: 결측치를 처리하는 방법입니다. 'mean', 'median', 'zero' 등으로 설정합니다.
  • benchmark_filename: 벤치마크 데이터셋의 파일 이름 목록입니다.
  • k_core: 사용자와 아이템이 최소 k개의 상호작용을 가지도록 하는 k-core 전처리를 위한 값입니다.
  • lowest_val: 평점 정규화를 위한 최소 값입니다.
  • highest_val: 평점 정규화를 위한 최대 값입니다.

데이터 분할 설정 (Split Settings)
  • split_ratio: 데이터셋을 분할할 비율입니다. 예: [0.8, 0.1, 0.1]은 학습, 검증, 테스트 세트로 80%, 10%, 10%로 분할합니다.
  • group_by_user: 데이터를 분할할 때 사용자를 기준으로 그룹화할지 여부입니다.
  • leave_one_num: ‘leave-one-out’ 방식으로 각 사용자마다 남겨둘 상호작용 수입니다.
  • split_strategy: 데이터셋을 분할하는 전략입니다. 'loo', 'ratio', 'by_time' 등으로 설정합니다.
  • shuffle: 분할 전에 데이터를 섞을지 여부입니다.
  • user_inter_order: 사용자 상호작용을 정렬하는 순서입니다.

학습 설정 (Training Settings)
  • epochs: 학습할 에포크 수입니다.
  • train_batch_size: 학습 배치 크기입니다.
  • learner: 사용할 옵티마이저의 종류입니다. 'adam', 'sgd', 'adagrad' 등으로 설정합니다.
  • learning_rate: 옵티마이저의 학습률입니다.
  • weight_decay: 가중치 감쇠(L2 정규화) 계수입니다.
  • stopping_step: 개선이 없을 때 조기 종료를 위한 에포크 수입니다.
  • clip_grad_norm: 그래디언트 클리핑을 위한 최대 norm 값입니다.
  • loss_type: 사용할 손실 함수의 유형입니다. 예: 'BPR', 'CrossEntropy', 'MSE' 등.
  • reg_weight: 손실 함수에 대한 정규화 가중치입니다.
  • neg_sampling: 부정적 샘플링 전략입니다. 'uniform', 'adversarial' 등으로 설정합니다.
  • eval_step: 검증 세트에서 평가를 수행할 에포크 간격입니다.
  • optimizer_params: 옵티마이저에 대한 추가 파라미터입니다.

평가 설정 (Evaluation Settings)
  • eval_batch_size: 평가 시의 배치 크기입니다.
  • metrics: 계산할 평가 지표의 목록입니다. 예: ['Recall', 'Precision', 'NDCG', 'MRR'].
  • topk: 상위 K개 평가 지표를 위한 K 값의 목록입니다. 예: [5, 10, 20].
  • eval_args: 평가 설정에 대한 추가 인자입니다.
  • valid_metric: 검증 및 조기 종료에 사용할 평가 지표입니다.
  • eval_setting: 평가 전략입니다. 예: 'RO_RS', 'TO_LS', 'LOO'.
  • group_by_user: 평가 시 데이터를 사용자별로 그룹화할지 여부입니다.
  • metrics_for_early_stop: 조기 종료를 모니터링할 지표입니다.

모델 하이퍼파라미터 (Model Hyperparameters)

모델마다 고유한 하이퍼파라미터가 있을 수 있지만, 일반적인 하이퍼파라미터는 다음과 같습니다:

  • embedding_size: 사용자와 아이템 임베딩 벡터의 크기입니다.
  • hidden_size: 신경망 모델의 은닉층 크기입니다.
  • num_layers: MLP나 GNN과 같은 모델에서의 레이어 수입니다.
  • dropout_prob: 드롭아웃을 위한 확률로, 정규화에 사용됩니다.
  • activation: 활성화 함수입니다. 'relu', 'tanh', 'sigmoid' 등으로 설정합니다.
  • num_heads: 어텐션 메커니즘을 사용하는 모델에서의 헤드 수입니다.
  • layers: 심층 신경망 모델에서 각 레이어의 크기를 지정하는 리스트입니다.
  • weight_initializer: 모델 가중치를 초기화하는 방법입니다.
  • bias_initializer: 모델 편향을 초기화하는 방법입니다.

로깅 및 체크포인트 (Logging and Checkpointing)
  • log_wandb: Weights & Biases에 실험을 로깅할지 여부입니다.
  • wandb_project: Weights & Biases에서의 프로젝트 이름입니다.
  • wandb_entity: Weights & Biases에서의 사용자 이름 또는 팀 이름입니다.
  • log_interval: 로깅 메시지 사이의 이터레이션 수입니다.
  • checkpoint_interval: 모델 체크포인트를 저장할 에포크 간격입니다.
  • tensorboard: TensorBoard를 사용하여 로깅할지 여부입니다.
  • log_file: 로그 파일의 경로입니다.

고급 설정 (Advanced Settings)
  • max_seq_length: 입력 시퀀스의 최대 길이입니다. 순차 추천 모델에서 사용됩니다.
  • mask_ratio: BERT4Rec과 같은 모델에서 아이템을 마스킹할 비율입니다.
  • pretrain_path: 사전 학습된 모델 가중치의 경로입니다.
  • use_pretrain: 사전 학습된 가중치를 사용할지 여부입니다.
  • load_col: 데이터셋에서 로드할 컬럼의 목록입니다.
  • unload_col: 데이터셋에서 제외할 컬럼의 목록입니다.
  • repeatable: 데이터셋이 반복 가능한지 여부를 나타내는 불리언 값입니다. 순차 모델에서 사용됩니다.
  • model_type: 모델 아키텍처의 유형입니다. 'general', 'sequential', 'context-aware' 등으로 설정합니다.
  • fast_dev_run: 빠른 디버깅을 위한 불리언 값으로, 학습 및 평가를 한 번의 배치로 실행합니다.
  • kfold: k-폴드 교차 검증을 위한 폴드 수입니다.
  • save_dataset: 전처리된 데이터셋을 저장할지 여부입니다.
  • load_saved_dataset: 이전에 저장된 데이터셋을 로드할지 여부입니다.
  • benchmark_index: 벤치마크 데이터셋의 인덱스입니다.
  • step: 순차 모델에서 슬라이딩 윈도의 스텝 크기입니다.
  • neg_sampling: 부정적 샘플링 전략 구성입니다.
  • metrics_weight: 전체 성능을 계산할 때 각 지표의 가중치입니다.

환경 설정 (Environment Settings)
  • num_workers: 데이터 로딩에 사용할 서브프로세스 수입니다.
  • pin_memory: 데이터 로딩 시 메모리를 고정할지 여부입니다.
  • prefetch_factor: 미리 가져올 배치의 수입니다.
  • persistent_workers: 에포크 사이에 워커를 유지할지 여부입니다.
  • cudnn_benchmark: cuDNN 벤치마크를 활성화할지 여부입니다.

5. RecBole로 첫 추천 모델 만들기

기본 추천 모델 생성 단계별 가이드
  1. 설정 파일 생성:
from recbole.config import Config

config = {
    # 데이터 관련 설정
    'data_path': './data',
    'dataset': 'custom_dataset',
    
    # 모델 관련 설정
    'model': 'BPR',
    'embedding_size': 64,
    'learning_rate': 0.001,
    
    # 학습 관련 설정
    'train_batch_size': 256,
    'eval_batch_size': 256,
    'epochs': 500,
    'eval_step': 1,
    
    # GPU 사용 설정
    'device': 'cuda' if torch.cuda.is_available() else 'cpu'
}

config = Config(config)
  1. 모델 초기화 및 학습:
from recbole.data import create_dataset, data_preparation
from recbole.model.general_recommender import BPR
from recbole.trainer import Trainer

# 데이터셋 생성
dataset = create_dataset(config)
train_data, valid_data, test_data = data_preparation(config, dataset)

# 모델 초기화
model = BPR(config, train_data.dataset)

# 트레이너 초기화 및 학습
trainer = Trainer(config, model)
best_valid_score, best_valid_result = trainer.fit(
    train_data, valid_data, saved=True, show_progress=True
)
  1. 모델 평가 및 예측:
# 테스트 데이터로 평가
test_result = trainer.evaluate(test_data)
print('Test Result:', test_result)

# 특정 사용자에 대한 추천 생성
uid_series = dataset.token2id(config['USER_ID_FIELD'], ['1', '2'])
topk_items = model.predict(uid_series, dataset.item_feat)
print('Recommended items:', dataset.id2token(config['ITEM_ID_FIELD'], topk_items.cpu()))
적절한 모델 선택

RecBole에서 제공하는 다양한 모델 중 사용 사례에 맞는 모델을 선택할 수 있습니다:

# 협업 필터링 모델 (BPR)
from recbole.model.general_recommender import BPR

# 신경망 기반 모델 (NCF)
from recbole.model.general_recommender import NCF

# 순차 추천 모델 (GRU4Rec)
from recbole.model.sequential_recommender import GRU4Rec

# 선택한 모델에 따른 설정 예시
model_config = {
    'BPR': {
        'embedding_size': 64,
        'learning_rate': 0.001
    },
    'NCF': {
        'embedding_size': 64,
        'mlp_hidden_size': [128, 64, 32],
        'learning_rate': 0.001
    },
    'GRU4Rec': {
        'embedding_size': 64,
        'hidden_size': 128,
        'learning_rate': 0.001
    }
}

# 선택한 모델 초기화
selected_model = 'BPR'
config.update(model_config[selected_model])
model = eval(selected_model)(config, train_data.dataset)

6. 고급 기능 및 맞춤 설정

RecBole을 이용한 하이퍼파라미터 튜닝

하이퍼파라미터 최적화는 모델의 성능을 향상시키는 핵심 과정입니다. RecBole은 다양한 하이퍼파라미터 튜닝 방법을 제공합니다:

from recbole.trainer import HyperTuning
from recbole.quick_start import objective_function

# 하이퍼파라미터 탐색 공간 정의
hyper_settings = {
    'learning_rate': [0.0001, 0.001, 0.01],
    'embedding_size': [32, 64, 128],
    'n_layers': [1, 2, 3],
    'dropout_prob': [0.0, 0.1, 0.2]
}

# HyperTuning 설정
hp = HyperTuning(
    objective_function=objective_function,
    params_file='model.yaml',
    fixed_config_file_list=['dataset.yaml'],
    hyper_config_dict=hyper_settings
)

# 그리드 서치 실행
hp.run()
print('최적의 하이퍼파라미터:', hp.best_params)
print('최고 성능:', hp.best_score)
모델 튜닝 도구 사용
그리드 서치 구현
def grid_search_tuning(config, dataset):
    best_score = float('-inf')
    best_params = None
    
    # 그리드 서치를 위한 파라미터 조합 생성
    param_combinations = [
        {'learning_rate': lr, 'embedding_size': es}
        for lr in [0.0001, 0.001, 0.01]
        for es in [32, 64, 128]
    ]
    
    for params in param_combinations:
        # 현재 파라미터로 설정 업데이트
        current_config = config.copy()
        current_config.update(params)
        
        # 모델 학습 및 평가
        model = BPR(current_config, dataset)
        trainer = Trainer(current_config, model)
        _, valid_score = trainer.fit(dataset)
        
        # 최고 성능 업데이트
        if valid_score > best_score:
            best_score = valid_score
            best_params = params
    
    return best_params, best_score
랜덤 서치 구현
import random

def random_search_tuning(config, dataset, n_trials=20):
    best_score = float('-inf')
    best_params = None
    
    for _ in range(n_trials):
        # 랜덤 파라미터 생성
        params = {
            'learning_rate': random.choice([0.0001, 0.001, 0.01]),
            'embedding_size': random.choice([32, 64, 128]),
            'dropout_prob': random.uniform(0.0, 0.5)
        }
        
        # 현재 파라미터로 모델 평가
        current_config = config.copy()
        current_config.update(params)
        
        model = BPR(current_config, dataset)
        trainer = Trainer(current_config, model)
        _, valid_score = trainer.fit(dataset)
        
        if valid_score > best_score:
            best_score = valid_score
            best_params = params
    
    return best_params, best_score
평가를 위한 사용자 정의 메트릭 추가

RecBole은 사용자 정의 평가 메트릭을 추가할 수 있습니다:

from recbole.evaluator.metrics import metrics_dict
from recbole.evaluator.collector import DataStruct

class CustomMetric:
    def __init__(self):
        pass
    
    def calculate_metric(self, dataobject: DataStruct):
        # 예측값과 실제값 가져오기
        pred = dataobject.get_pred().numpy()
        true = dataobject.get_true().numpy()
        
        # 메트릭 계산 로직 구현
        score = custom_calculation(pred, true)
        return score

# 메트릭 등록
metrics_dict['custom_metric'] = CustomMetric()

# 설정에 새로운 메트릭 추가
config['metrics'] = ['Recall', 'NDCG', 'custom_metric']
사용자 정의 손실 함수 구현

특정 요구사항에 맞는 커스텀 손실 함수를 구현할 수 있습니다:

import torch.nn as nn

class CustomLoss(nn.Module):
    def __init__(self, weight=1.0):
        super().__init__()
        self.weight = weight
    
    def forward(self, pred, true):
        # 손실 함수 계산 로직
        basic_loss = nn.BCEWithLogitsLoss()(pred, true)
        custom_penalty = self.calculate_custom_penalty(pred)
        return basic_loss + self.weight * custom_penalty
    
    def calculate_custom_penalty(self, pred):
        # 추가적인 페널티 항 계산
        return torch.mean(torch.abs(pred))

# 모델에 커스텀 손실 함수 적용
class CustomBPR(BPR):
    def __init__(self, config, dataset):
        super().__init__(config, dataset)
        self.loss = CustomLoss(weight=0.1)
    
    def calculate_loss(self, interaction):
        pred = self.forward(interaction)
        true = interaction[self.LABEL]
        return self.loss(pred, true)

7. 다양한 추천 모델 유형 다루기

순차 추천 모델

순차 추천은 사용자의 시간에 따른 행동 패턴을 고려합니다:

from recbole.model.sequential_recommender import GRU4Rec, BERT4Rec

# GRU4Rec 모델 설정
gru_config = {
    'MAX_ITEM_LIST_LENGTH': 50,  # 최대 시퀀스 길이
    'hidden_size': 128,
    'num_layers': 2,
    'dropout_prob': 0.1
}

# BERT4Rec 모델 설정
bert_config = {
    'mask_ratio': 0.2,  # 마스킹 비율
    'n_layers': 2,
    'n_heads': 4,
    'hidden_size': 256
}

# 순차 추천 모델 초기화 및 학습
config.update(gru_config)
sequential_model = GRU4Rec(config, dataset)
trainer = Trainer(config, sequential_model)
trainer.fit(train_data, valid_data)
컨텍스트 기반 및 지식 기반 모델
컨텍스트 특성 통합

컨텍스트 정보를 활용하여 추천의 정확도를 높일 수 있습니다:

from recbole.model.context_aware_recommender import FM, DeepFM, DCN

# 컨텍스트 특성 정의
context_config = {
    'USER_ID_FIELD': 'user_id',
    'ITEM_ID_FIELD': 'item_id',
    'CONTEXT_FIELD': ['time', 'location', 'device'],
    'continuous_feature_columns': ['user_age', 'item_price'],
    'categorical_feature_columns': ['user_gender', 'item_category']
}

# DeepFM 모델 설정
deepfm_config = {
    'embedding_size': 64,
    'mlp_hidden_size': [128, 64, 32],
    'dropout_prob': 0.1,
    'learning_rate': 0.001
}

# 모델 초기화 및 학습
config.update({**context_config, **deepfm_config})
context_model = DeepFM(config, dataset)
trainer = Trainer(config, context_model)
trainer.fit(train_data, valid_data)
지식 그래프 기반 추천 활용

지식 그래프를 통해 아이템 간의 관계를 모델링할 수 있습니다:

from recbole.model.knowledge_aware_recommender import KGAT, KTUP

# 지식 그래프 데이터 준비
kg_config = {
    'entity_field': ['user_id', 'item_id', 'category_id', 'brand_id'],
    'relation_field': ['purchase', 'belong_to', 'produced_by'],
    'kg_embedding_size': 64,
    'layers': [64, 32, 16],
    'aggregator_type': 'bi',
    'reg_weight': 1e-5
}

# 지식 그래프 기반 모델 초기화
config.update(kg_config)
kg_model = KGAT(config, dataset)

# 학습 및 평가
trainer = Trainer(config, kg_model)
trainer.fit(train_data, valid_data)

8. 추천 모델 평가하기

평가 메트릭 이해하기
from recbole.evaluator.metrics import metrics_dict
from recbole.evaluator import Evaluator

# 다양한 평가 메트릭 설정
eval_config = {
    'metrics': ['Precision', 'Recall', 'NDCG', 'MAP', 'MRR'],
    'topk': [5, 10, 20],
    'valid_metric': 'NDCG@10'
}

# 평가자 초기화
evaluator = Evaluator(config)

# 모델 평가 실행
result = evaluator.evaluate(model, test_data)

# 상세 평가 결과 분석
def analyze_results(result):
    for metric in eval_config['metrics']:
        for k in eval_config['topk']:
            metric_key = f'{metric}@{k}'
            print(f'{metric_key}: {result[metric_key]:.4f}')
            
analyze_results(result)
RecBole에서의 교차 검증 기법
from sklearn.model_selection import KFold
import numpy as np

class CrossValidator:
    def __init__(self, config, dataset, n_splits=5):
        self.config = config
        self.dataset = dataset
        self.n_splits = n_splits
        self.kf = KFold(n_splits=n_splits, shuffle=True)
        
    def run_cross_validation(self):
        results = []
        interaction_data = self.dataset.inter_feat.numpy()
        
        for fold, (train_idx, test_idx) in enumerate(self.kf.split(interaction_data)):
            print(f'Fold {fold + 1}/{self.n_splits}')
            
            # 데이터 분할
            train_data = self.dataset.copy()[train_idx]
            test_data = self.dataset.copy()[test_idx]
            
            # 모델 학습 및 평가
            model = BPR(self.config, train_data)
            trainer = Trainer(self.config, model)
            trainer.fit(train_data, valid_data=test_data)
            
            # 결과 저장
            result = trainer.evaluate(test_data)
            results.append(result)
            
        # 평균 성능 계산
        mean_results = {
            metric: np.mean([r[metric] for r in results])
            for metric in results[0].keys()
        }
        return mean_results

# 교차 검증 실행
cv = CrossValidator(config, dataset)
cv_results = cv.run_cross_validation()
모델 성능 시각화
import matplotlib.pyplot as plt
import seaborn as sns

def visualize_training_progress(trainer):
    # 학습 곡선 시각화
    plt.figure(figsize=(12, 4))
    
    # 손실 함수 그래프
    plt.subplot(1, 2, 1)
    plt.plot(trainer.train_loss_dict['batch_loss'])
    plt.title('Training Loss')
    plt.xlabel('Batch')
    plt.ylabel('Loss')
    
    # 평가 메트릭 그래프
    plt.subplot(1, 2, 2)
    for metric in trainer.eval_results:
        plt.plot(trainer.eval_results[metric], label=metric)
    plt.title('Evaluation Metrics')
    plt.xlabel('Epoch')
    plt.ylabel('Score')
    plt.legend()
    
    plt.tight_layout()
    plt.show()

# 모델 간 성능 비교 시각화
def compare_models(model_results):
    metrics = ['Precision@10', 'Recall@10', 'NDCG@10']
    models = list(model_results.keys())
    
    plt.figure(figsize=(10, 6))
    x = np.arange(len(metrics))
    width = 0.2
    
    for i, model in enumerate(models):
        plt.bar(x + i*width, 
               [model_results[model][m] for m in metrics],
               width,
               label=model)
    
    plt.xlabel('Metrics')
    plt.ylabel('Score')
    plt.title('Model Comparison')
    plt.xticks(x + width, metrics)
    plt.legend()
    plt.show()

9. RecBole 추천 시스템 배포하기

훈련된 모델 내보내기 및 저장하기
import torch
import json
import os

class ModelExporter:
    def __init__(self, model, config, dataset):
        self.model = model
        self.config = config
        self.dataset = dataset
        
    def save_model(self, path):
        # 모델 가중치 저장
        torch.save(self.model.state_dict(), f'{path}/model.pth')
        
        # 모델 설정 저장
        config_dict = self.config._config_dict
        with open(f'{path}/config.json', 'w') as f:
            json.dump(config_dict, f, indent=4)
        
        # 특성 매핑 정보 저장
        mapping_dict = {
            'user_token2id': self.dataset.field2token_id['user_id'],
            'item_token2id': self.dataset.field2token_id['item_id']
        }
        with open(f'{path}/mapping.json', 'w') as f:
            json.dump(mapping_dict, f, indent=4)

    @staticmethod
    def load_model(path, model_class):
        # 설정 로드
        with open(f'{path}/config.json', 'r') as f:
            config_dict = json.load(f)
        config = Config(config_dict)
        
        # 매핑 정보 로드
        with open(f'{path}/mapping.json', 'r') as f:
            mapping_dict = json.load(f)
            
        # 모델 초기화 및 가중치 로드
        model = model_class(config, None)
        model.load_state_dict(torch.load(f'{path}/model.pth'))
        return model, config, mapping_dict

# 모델 저장 예제
exporter = ModelExporter(trained_model, config, dataset)
exporter.save_model('saved_models/bpr_model')
Flask 또는 FastAPI를 이용한 모델 배포
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import torch
import numpy as np

app = FastAPI()

class RecommendRequest(BaseModel):
    user_id: str
    n_items: int = 10

class ModelService:
    def __init__(self, model_path):
        # 저장된 모델 로드
        self.model, self.config, self.mapping = ModelExporter.load_model(
            model_path, BPR
        )
        self.model.eval()
        
    def get_recommendations(self, user_id: str, n_items: int) -> list:
        try:
            # 사용자 ID를 모델 입력 형식으로 변환
            user_idx = self.mapping['user_token2id'][user_id]
            
            # 추천 생성
            with torch.no_grad():
                scores = self.model.full_sort_predict(user_idx)
                topk_items = torch.topk(scores, n_items)[1].tolist()
                
            # 아이템 ID로 변환
            id2token = {v: k for k, v in self.mapping['item_token2id'].items()}
            recommendations = [id2token[idx] for idx in topk_items]
            
            return recommendations
        except Exception as e:
            raise HTTPException(status_code=500, detail=str(e))

# 모델 서비스 초기화
model_service = ModelService('saved_models/bpr_model')

@app.post("/recommend")
async def get_recommendations(request: RecommendRequest):
    recommendations = model_service.get_recommendations(
        request.user_id, request.n_items
    )
    return {"recommendations": recommendations}
웹 애플리케이션과의 추천 시스템 통합
import requests
from typing import List, Dict

class RecommenderClient:
    def __init__(self, api_url: str):
        self.api_url = api_url
        
    def get_recommendations(self, user_id: str, n_items: int = 10) -> List[str]:
        try:
            response = requests.post(
                f"{self.api_url}/recommend",
                json={"user_id": user_id, "n_items": n_items}
            )
            response.raise_for_status()
            return response.json()["recommendations"]
        except requests.exceptions.RequestException as e:
            print(f"추천 요청 실패: {e}")
            return []

# React 컴포넌트에서 사용 예제
```jsx
import React, { useState, useEffect } from 'react';

const RecommendationList = ({ userId }) => {
    const [recommendations, setRecommendations] = useState([]);
    const [loading, setLoading] = useState(false);

    useEffect(() => {
        const fetchRecommendations = async () => {
            setLoading(true);
            try {
                const response = await fetch('/api/recommend', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({ user_id: userId, n_items: 10 }),
                });
                const data = await response.json();
                setRecommendations(data.recommendations);
            } catch (error) {
                console.error('추천 로드 실패:', error);
            } finally {
                setLoading(false);
            }
        };

        fetchRecommendations();
    }, [userId]);

    return (
        <div>
            <h2>추천 아이템</h2>
            {loading ? (
                <p>로딩 중...</p>
            ) : (
                <ul>
                    {recommendations.map((item, index) => (
                        <li key={index}>{item}</li>
                    ))}
                </ul>
            )}
        </div>
    );
};
운영 환경에서 모델 모니터링 및 업데이트
import logging
from datetime import datetime
import pandas as pd
from prometheus_client import Counter, Histogram

class ModelMonitor:
    def __init__(self):
        # 메트릭 초기화
        self.recommendation_count = Counter(
            'recommendations_total',
            'Total number of recommendations made'
        )
        self.recommendation_latency = Histogram(
            'recommendation_latency_seconds',
            'Recommendation generation latency'
        )
        self.setup_logging()
        
    def setup_logging(self):
        logging.basicConfig(
            filename=f'logs/recommender_{datetime.now():%Y%m%d}.log',
            level=logging.INFO,
            format='%(asctime)s %(levelname)s: %(message)s'
        )
        
    def log_recommendation(self, user_id, recommendations, latency):
        self.recommendation_count.inc()
        self.recommendation_latency.observe(latency)
        
        logging.info(
            f"User: {user_id}, "
            f"Recommendations: {recommendations}, "
            f"Latency: {latency:.3f}s"
        )
        
    def analyze_performance(self, log_file):
        # 로그 분석
        df = pd.read_csv(log_file)
        
        # 성능 메트릭 계산
        metrics = {
            'avg_latency': df['latency'].mean(),
            'p95_latency': df['latency'].quantile(0.95),
            'success_rate': (df['status'] == 'success').mean(),
            'total_requests': len(df)
        }
        
        return metrics

# 모니터링 통합
class MonitoredModelService(ModelService):
    def __init__(self, model_path):
        super().__init__(model_path)
        self.monitor = ModelMonitor()
        
    def get_recommendations(self, user_id: str, n_items: int) -> list:
        start_time = datetime.now()
        try:
            recommendations = super().get_recommendations(user_id, n_items)
            latency = (datetime.now() - start_time).total_seconds()
            
            self.monitor.log_recommendation(user_id, recommendations, latency)
            return recommendations
        except Exception as e:
            logging.error(f"추천 생성 실패: {str(e)}")
            raise

10. RecBole에서 자주 발생하는 문제 해결

설치 관련 오류 해결
import sys
import torch
import recbole

def check_environment():
    """시스템 환경 진단 함수"""
    environment_info = {
        'Python Version': sys.version,
        'PyTorch Version': torch.__version__,
        'CUDA Available': torch.cuda.is_available(),
        'CUDA Version': torch.version.cuda if torch.cuda.is_available() else 'Not Available',
        'RecBole Version': recbole.__version__
    }
    
    # CUDA 디바이스 정보
    if torch.cuda.is_available():
        for i in range(torch.cuda.device_count()):
            device = torch.cuda.get_device_properties(i)
            environment_info[f'GPU {i}'] = f'{device.name}, {device.total_memory/1024**3:.1f}GB'
    
    return environment_info

def diagnose_installation():
    """설치 문제 진단"""
    try:
        # 기본 모듈 임포트 테스트
        import recbole.data
        import recbole.model
        import recbole.trainer
        
        print("✅ 기본 모듈 임포트 성공")
        
        # 데이터셋 로드 테스트
        from recbole.quick_start import run_recbole
        config = {'dataset': 'ml-100k', 'data_path': './dataset/'}
        try:
            dataset, model, trainer, config = run_recbole('BPR', config)
            print("✅ 샘플 데이터셋 로드 성공")
        except Exception as e:
            print(f"❌ 데이터셋 로드 실패: {str(e)}")
            
    except ImportError as e:
        print(f"❌ 모듈 임포트 실패: {str(e)}")
        print("💡 해결 방법: pip install --upgrade recbole torch")

# 설치 문제 해결을 위한 유틸리티 클래스
class InstallationTroubleshooter:
    @staticmethod
    def fix_cuda_issues():
        """CUDA 관련 문제 해결"""
        if not torch.cuda.is_available():
            print("CUDA를 사용할 수 없습니다. 다음을 확인하세요:")
            print("1. NVIDIA GPU가 설치되어 있는지")
            print("2. CUDA 드라이버가 설치되어 있는지")
            print("3. PyTorch가 CUDA 버전으로 설치되어 있는지")
            
            # PyTorch CUDA 재설치 명령어 생성
            cuda_version = '11.8'  # 사용자 환경에 맞게 수정
            print(f"\n재설치 명령어:")
            print(f"pip install torch --index-url https://download.pytorch.org/whl/cu{cuda_version}")
데이터 관련 문제 해결
import pandas as pd
import numpy as np
from recbole.data.dataset import Dataset

class DataTroubleshooter:
    def __init__(self, dataset):
        self.dataset = dataset
        
    def analyze_data_quality(self):
        """데이터 품질 분석"""
        quality_report = {
            'missing_values': self._check_missing_values(),
            'duplicates': self._check_duplicates(),
            'data_distribution': self._analyze_distribution(),
            'interaction_patterns': self._analyze_interactions()
        }
        return quality_report
    
    def _check_missing_values(self):
        """결측치 검사"""
        missing_stats = {}
        for field in self.dataset.field2type:
            field_data = self.dataset.field2tokens[field]
            if isinstance(field_data, np.ndarray):
                missing_count = np.isnan(field_data).sum()
            else:
                missing_count = field_data.isnull().sum()
            missing_stats[field] = missing_count
        return missing_stats
    
    def _check_duplicates(self):
        """중복 데이터 검사"""
        interaction_data = self.dataset.inter_feat.numpy()
        unique_rows = np.unique(interaction_data, axis=0)
        return {
            'total_interactions': len(interaction_data),
            'unique_interactions': len(unique_rows),
            'duplicate_ratio': 1 - len(unique_rows)/len(interaction_data)
        }
    
    def fix_data_issues(self):
        """데이터 문제 자동 수정"""
        # 결측치 처리
        for field in self.dataset.field2type:
            if field in self.dataset.field2tokens:
                field_data = self.dataset.field2tokens[field]
                if isinstance(field_data, np.ndarray):
                    # 수치형 데이터는 평균값으로 대체
                    field_data[np.isnan(field_data)] = np.nanmean(field_data)
                else:
                    # 범주형 데이터는 최빈값으로 대체
                    field_data.fillna(field_data.mode()[0], inplace=True)
        
        # 중복 제거
        self.dataset.inter_feat = pd.DataFrame(
            np.unique(self.dataset.inter_feat.numpy(), axis=0)
        )
모델 수렴 문제 처리
class ConvergenceTroubleshooter:
    def __init__(self, model, trainer):
        self.model = model
        self.trainer = trainer
        self.convergence_history = []
        
    def monitor_training(self, epoch, loss):
        """학습 과정 모니터링"""
        self.convergence_history.append({
            'epoch': epoch,
            'loss': loss
        })
        
        # 수렴 문제 감지
        if self._detect_convergence_issues():
            self._adjust_training_parameters()
    
    def _detect_convergence_issues(self):
        """수렴 문제 감지"""
        if len(self.convergence_history) < 5:
            return False
            
        recent_losses = [h['loss'] for h in self.convergence_history[-5:]]
        
        # 발산 감지
        if np.mean(recent_losses) > 1e5:
            return 'divergence'
            
        # 느린 수렴 감지
        loss_change = np.abs(np.diff(recent_losses))
        if np.mean(loss_change) < 1e-6:
            return 'slow_convergence'
            
        return False
    
    def _adjust_training_parameters(self, issue_type):
        """학습 파라미터 자동 조정"""
        if issue_type == 'divergence':
            # 학습률 감소
            self.trainer.learning_rate *= 0.5
            print(f"학습률을 {self.trainer.learning_rate}로 조정했습니다.")
            
        elif issue_type == 'slow_convergence':
            # 배치 크기 증가
            self.trainer.batch_size *= 2
            print(f"배치 크기를 {self.trainer.batch_size}로 증가했습니다.")
성능 및 메모리 사용 디버깅
import psutil
import gc
import torch.autograd.profiler as profiler

class PerformanceDebugger:
    def __init__(self):
        self.memory_logs = []
        
    def monitor_memory_usage(self):
        """메모리 사용량 모니터링"""
        process = psutil.Process()
        memory_info = process.memory_info()
        
        self.memory_logs.append({
            'timestamp': datetime.now(),
            'rss': memory_info.rss / 1024**2,  # MB
            'vms': memory_info.vms / 1024**2,  # MB
            'gpu_memory': torch.cuda.memory_allocated() / 1024**2 if torch.cuda.is_available() else 0
        })
        
    def optimize_memory_usage(self, model, dataset):
        """메모리 사용량 최적화"""
        # 불필요한 메모리 해제
        gc.collect()
        torch.cuda.empty_cache()
        
        # 데이터 로더 최적화
        dataset.set_prefetch_strategy('dynamic')
        
        # 모델 최적화
        for param in model.parameters():
            if param.grad is not None:
                param.grad.detach_()
                param.grad.zero_()
                
    def profile_model_performance(self, model, sample_input):
        """모델 성능 프로파일링"""
        with profiler.profile(use_cuda=torch.cuda.is_available()) as prof:
            with profiler.record_function("model_inference"):
                model(sample_input)
                
        print(prof.key_averages().table(sort_by="cpu_time_total"))

11. RecBole 확장: 사용자 정의 모델 개발

RecBole의 모델 개발 프레임워크 소개
from recbole.model.abstract_recommender import GeneralRecommender
import torch
import torch.nn as nn
import torch.nn.functional as F

class CustomRecommenderBase(GeneralRecommender):
    """사용자 정의 추천 모델을 위한 기본 클래스"""
    
    def __init__(self, config, dataset):
        super(CustomRecommenderBase, self).__init__(config, dataset)
        
        # 기본 설정
        self.embedding_size = config['embedding_size']
        self.n_users = dataset.user_num
        self.n_items = dataset.item_num
        
        # 임베딩 레이어 초기화
        self.user_embedding = nn.Embedding(self.n_users, self.embedding_size)
        self.item_embedding = nn.Embedding(self.n_items, self.embedding_size)
        
        # 가중치 초기화
        self.apply(self._init_weights)
        
    def _init_weights(self, module):
        """가중치 초기화 메서드"""
        if isinstance(module, nn.Embedding):
            nn.init.xavier_normal_(module.weight)
            
    def forward(self, user, item):
        raise NotImplementedError
        
    def calculate_loss(self, interaction):
        raise NotImplementedError
        
    def predict(self, interaction):
        raise NotImplementedError
사용자 정의 추천 모델 생성 및 테스트
class HybridAttentionRecommender(CustomRecommenderBase):
    """하이브리드 어텐션 기반 추천 모델"""
    
    def __init__(self, config, dataset):
        super(HybridAttentionRecommender, self).__init__(config, dataset)
        
        # 추가 설정
        self.n_heads = config['n_heads']
        self.dropout = config['dropout']
        
        # 어텐션 레이어
        self.attention = nn.MultiheadAttention(
            self.embedding_size, 
            self.n_heads, 
            dropout=self.dropout
        )
        
        # MLP 레이어
        self.mlp = nn.Sequential(
            nn.Linear(self.embedding_size * 2, self.embedding_size),
            nn.ReLU(),
            nn.Dropout(self.dropout),
            nn.Linear(self.embedding_size, 1)
        )
        
    def forward(self, user, item):
        # 사용자와 아이템 임베딩
        user_emb = self.user_embedding(user)
        item_emb = self.item_embedding(item)
        
        # 어텐션 적용
        attn_output, _ = self.attention(
            user_emb.unsqueeze(0),
            item_emb.unsqueeze(0),
            item_emb.unsqueeze(0)
        )
        
        # 특성 결합
        combined = torch.cat([
            attn_output.squeeze(0), 
            item_emb
        ], dim=1)
        
        # 최종 예측
        return self.mlp(combined)
        
    def calculate_loss(self, interaction):
        user = interaction[self.USER_ID]
        item = interaction[self.ITEM_ID]
        label = interaction[self.LABEL]
        
        output = self.forward(user, item)
        return F.binary_cross_entropy_with_logits(
            output.view(-1), 
            label.float()
        )
        
    def predict(self, interaction):
        user = interaction[self.USER_ID]
        item = interaction[self.ITEM_ID]
        return self.forward(user, item).sigmoid()

# 모델 테스트 유틸리티
class ModelTester:
    def __init__(self, config, dataset):
        self.config = config
        self.dataset = dataset
        
    def test_model_initialization(self, model_class):
        """모델 초기화 테스트"""
        try:
            model = model_class(self.config, self.dataset)
            print("✅ 모델 초기화 성공")
            return model
        except Exception as e:
            print(f"❌ 모델 초기화 실패: {str(e)}")
            return None
            
    def test_forward_pass(self, model):
        """순전파 테스트"""
        try:
            # 샘플 데이터 생성
            batch_size = 32
            user = torch.randint(0, self.dataset.user_num, (batch_size,))
            item = torch.randint(0, self.dataset.item_num, (batch_size,))
            
            # 순전파 실행
            output = model(user, item)
            print(f"✅ 순전파 성공: 출력 형태 {output.shape}")
            return True
        except Exception as e:
            print(f"❌ 순전파 실패: {str(e)}")
            return False
RecBole과 PyTorch를 활용한 고급 커스터마이징
class CustomLossFunction(nn.Module):
    """사용자 정의 손실 함수"""
    
    def __init__(self, alpha=1.0, beta=0.5):
        super(CustomLossFunction, self).__init__()
        self.alpha = alpha
        self.beta = beta
        
    def forward(self, pred, true, user_emb, item_emb):
        # 기본 예측 손실
        pred_loss = F.binary_cross_entropy_with_logits(
            pred.view(-1),
            true.float()
        )
        
        # 정규화 항
        reg_loss = self.alpha * (
            torch.norm(user_emb) + 
            torch.norm(item_emb)
        )
        
        # 대조 손실
        contrast_loss = self.beta * self.contrastive_loss(
            user_emb, 
            item_emb
        )
        
        return pred_loss + reg_loss + contrast_loss
        
    @staticmethod
    def contrastive_loss(user_emb, item_emb):
        """대조 학습 손실"""
        sim_matrix = torch.mm(user_emb, item_emb.t())
        positive_pairs = torch.diag(sim_matrix)
        negative_pairs = sim_matrix.view(-1)
        
        return -torch.log(
            torch.exp(positive_pairs) / 
            torch.exp(negative_pairs).sum()
        ).mean()

class CustomTrainingCallback:
    """사용자 정의 학습 콜백"""
    
    def __init__(self):
        self.best_metric = float('-inf')
        self.patience = 0
        
    def on_epoch_end(self, trainer):
        """에폭 종료 시 호출되는 콜백"""
        current_metric = trainer.eval_collector.collect()['NDCG@10']
        
        # 성능 향상 체크
        if current_metric > self.best_metric:
            self.best_metric = current_metric
            self.patience = 0
            # 모델 저장
            trainer.save_checkpoint('best_model.pth')
        else:
            self.patience += 1
            
        # 조기 종료 체크
        if self.patience >= trainer.config['early_stopping_patience']:
            trainer.stop_training = True

12. RecBole로 추천 시스템 최적화 사례

모델 선택 전략
class ModelSelector:
    """최적의 모델 선택을 위한 유틸리티"""
    
    def __init__(self, dataset, config):
        self.dataset = dataset
        self.config = config
        self.results = {}
        
    def evaluate_models(self, model_list):
        """여러 모델 평가 및 비교"""
        for model_class in model_list:
            try:
                # 모델 초기화 및 학습
                model = model_class(self.config, self.dataset)
                trainer = Trainer(self.config, model)
                best_valid_score, valid_result = trainer.fit(
                    self.dataset,
                    valid_data=None,
                    show_progress=True
                )
                
                # 테스트 결과 저장
                test_result = trainer.evaluate(
                    self.dataset.build_test_dataset()
                )
                
                self.results[model_class.__name__] = {
                    'valid_score': best_valid_score,
                    'test_results': test_result,
                    'model_complexity': self._calculate_complexity(model)
                }
                
            except Exception as e:
                print(f"{model_class.__name__} 평가 실패: {str(e)}")
                
    def _calculate_complexity(self, model):
        """모델 복잡도 계산"""
        num_params = sum(
            p.numel() 
            for p in model.parameters()
        )
        return {
            'num_parameters': num_params,
            'memory_size': num_params * 4 / 1024 / 1024  # MB
        }
        
    def get_recommendation(self, criteria=['accuracy', 'efficiency']):
        """최적 모델 추천"""
        scores = {}
        for model_name, results in self.results.items():
            # 정확도 점수
            accuracy_score = results['test_results']['NDCG@10']
            
            # 효율성 점수 (파라미터 수의 역수)
            efficiency_score = 1 / np.log(
                results['model_complexity']['num_parameters']
            )
            
            # 종합 점수 계산
            scores[model_name] = {
                'accuracy': accuracy_score,
                'efficiency': efficiency_score,
                'overall': np.mean([accuracy_score, efficiency_score])
            }
            
        return scores
특성 엔지니어링 기법
class FeatureEngineer:
    """특성 엔지니어링 도구"""
    
    def __init__(self, dataset):
        self.dataset = dataset
        self.feature_importance = {}
        
    def create_temporal_features(self, timestamp_field):
        """시간적 특성 생성"""
        timestamps = self.dataset.inter_feat[timestamp_field].numpy()
        datetime_array = pd.to_datetime(timestamps, unit='s')
        
        # 시간적 특성 추출
        temporal_features = {
            'hour': datetime_array.hour,
            'day_of_week': datetime_array.dayofweek,
            'month': datetime_array.month,
            'is_weekend': datetime_array.dayofweek >= 5
        }
        
        return temporal_features
        
    def create_interaction_features(self):
        """상호작용 기반 특성 생성"""
        interactions = self.dataset.inter_feat
        
        # 사용자별 통계
        user_stats = {
            'user_interaction_count': interactions.groupby('user_id').size(),
            'user_avg_rating': interactions.groupby('user_id')['rating'].mean(),
            'user_rating_std': interactions.groupby('user_id')['rating'].std()
        }
        
        # 아이템별 통계
        item_stats = {
            'item_interaction_count': interactions.groupby('item_id').size(),
            'item_avg_rating': interactions.groupby('item_id')['rating'].mean(),
            'item_rating_std': interactions.groupby('item_id')['rating'].std()
        }
        
        return user_stats, item_stats
사전 학습된 임베딩을 이용한 성능 향상
class PretrainedEmbeddingEnhancer:
    """사전 학습된 임베딩을 활용한 성능 향상"""
    
    def __init__(self, model, config):
        self.model = model
        self.config = config
        
    def load_pretrained_embeddings(self, embedding_path):
        """사전 학습된 임베딩 로드"""
        pretrained = torch.load(embedding_path)
        
        # 임베딩 크기 확인 및 조정
        if pretrained['embedding_dim'] != self.config['embedding_size']:
            pretrained_embeddings = self._resize_embeddings(
                pretrained['embeddings'],
                self.config['embedding_size']
            )
        else:
            pretrained_embeddings = pretrained['embeddings']
            
        return pretrained_embeddings
        
    def initialize_with_pretrained(self, user_embeddings, item_embeddings):
        """사전 학습된 임베딩으로 초기화"""
        # 사용자 임베딩 초기화
        if hasattr(self.model, 'user_embedding'):
            self.model.user_embedding.weight.data.copy_(user_embeddings)
            
        # 아이템 임베딩 초기화
        if hasattr(self.model, 'item_embedding'):
            self.model.item_embedding.weight.data.copy_(item_embeddings)
지식 그래프 및 외부 데이터 소스 활용
class KnowledgeGraphEnhancer:
    """지식 그래프 통합 도구"""
    
    def __init__(self, dataset):
        self.dataset = dataset
        self.kg_graph = None
        
    def build_knowledge_graph(self, entity_data, relation_data):
        """지식 그래프 구축"""
        import networkx as nx
        
        # 그래프 초기화
        self.kg_graph = nx.DiGraph()
        
        # 엔티티 추가
        for entity in entity_data:
            self.kg_graph.add_node(
                entity['id'],
                type=entity['type'],
                attributes=entity['attributes']
            )
            
        # 관계 추가
        for relation in relation_data:
            self.kg_graph.add_edge(
                relation['head'],
                relation['tail'],
                type=relation['type'],
                weight=relation.get('weight', 1.0)
            )
            
    def generate_graph_features(self):
        """그래프 기반 특성 생성"""
        if self.kg_graph is None:
            raise ValueError("지식 그래프가 초기화되지 않았습니다.")
            
        # 중심성 계산
        centrality_features = {
            'degree': nx.degree_centrality(self.kg_graph),
            'betweenness': nx.betweenness_centrality(self.kg_graph),
            'pagerank': nx.pagerank(self.kg_graph)
        }
        
        return centrality_features

이것으로 RecBole 추천 시스템 구축을 위한 종합 가이드를 마무리합니다. 이 가이드를 통해 RecBole을 활용한 추천 시스템 개발의 전체 과정을 상세히 살펴보았습니다.

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다