ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [scikit-surprise] SVD 모델 생성하기
    AI-ML 2024. 5. 18. 07:45
    728x90
    반응형

    - 목차

     

    키워드.

    • scikit-surprise
    • SVD
    • Matrix Factorization

     

     

    들어가며.

    SVD 에 대해서 설명하는 이전 글과 이어지는 내용입니다.

     

    https://westlife0615.tistory.com/844

     

    [scikit-surprise] SVD Model 알아보기 ( Singular Value Decomposition )

    - 목차 키워드.scikit-surpriseMatrix FactorizationSVDLatent Space 함께 보면 좋은 글.https://westlife0615.tistory.com/851 [scikit-surprise] Dataset 이해하기- 목차 키워드.scikit-surpriseCollaborative FilteringRecommender Systemmoviele

    westlife0615.tistory.com

     

    scikit-surprise 의 SVD 모듈의 구체적인 사용법에 대해서 알아보도록 하겠습니다.

     

    SVD Model 사용하기.

    간단한 사용법은 아래와 같습니다.

    먼저 Dataset 과 Trainset, 그리고 Testset 을 생성합니다.

    from surprise import Dataset, Reader, accuracy, SVD
    from surprise.model_selection import train_test_split
    
    dataset = Dataset.load_builtin("ml-100k")
    trainset, testset = train_test_split(dataset, train_size=0.8, shuffle=True, random_state=41)

     

    그리고 SVD 모델을 생성한 후, Train 과 Test 를 수행합니다.

    algo = SVD(n_factors=200, n_epochs=100, biased=False, reg_all=0, verbose=True)
    model = algo.fit(trainset)
    predictions = model.test(testset, verbose=True)
    print(accuracy.rmse(predictions))
    RMSE: 0.9440
    0.9440423149643782

     

    n_factors.

    위의 설명에서 Matrix Factorization 을 수행한 결과 K Dimensionality 에 해당하는 Latent Space 가 생성된다고 말씀드렸습니다.

    분해된 행렬은 User Matrix 와 Item Matrix 는 N x K, K x M 인 크기의 행렬이 됩니다.

    여기서 K 가 n_factors 에 해당합니다.

    즉, SVD 알고리즘으로 분해할 Latent Factor 의 크기를 n_factors 인자로써 지정합니다.

    n_factors 는 최적의 값이 존재하지 않으며, Parameter Tuning 을 통해서 적절한 값을 도출해야 합니다.

     

    아래의 예시는 100 부터 2900까지 n_factors 를 변경하며 RMSE 값을 계산합니다.

    이러한 반복을 통해서 최적의 n_factors 값에 접근할 수 있습니다.

    for n_factor in range(100, 3000, 100):
        algo = SVD(n_factors=n_factor, n_epochs=100, biased=True, reg_all=0.02, verbose=False)
        model = algo.fit(trainset)
        predictions = model.test(testset, verbose=False)
        print(n_factor, accuracy.rmse(predictions))

     

    n_factors 와 RMSE 의 관계는 위와 같은 결과를 보입니다.

    n_factors 의 값이 크다고 RMSE 가 감소하진 않습니다.

    경험적으로 판단할 때에 n_factors 의 값은 User 또는 Item Matrix 의 크기보다 작게 설정하는 것이 정확도가 좋았고,

    n_factors < n_users, n_items 인 범위 내에서 Parameter Tuning 을 수행하곤 합니다.

     

     

    reg_all.

    일반적인 SVD 는 아래와 같은 공식을 취합니다.

    $ R = U \cdot I $

    R 은 Rating Matrix 이고 user 와 item 을 두 축으로 삼습니다.

     

    아래의 표현은 "a" 라는 User"b" 라는 Item 에 대한 Rating 을 계산하는 방식입니다.

    User Matrix 의 "a" Vector 와 Item Matrix 의 "b" Vector 를 계산하여 Rating 을 예측할 수 있습니다.

    $$ \widehat{r}_{a,b} = U_{a} \cdot I_{b}^{T} $$

     

    하지만 User 과 Item 의 관계는 Sparse 한 관계를 가집니다.

    모든 사용자와 모든 상품 간의 상호작용이 존재하지는 않죠.

    그래서 일부 사용자가 일부 상품에 부여한 평점을 기준으로 User, Item Latent Matrix 를 분해할 수 있고,

    이 과정에서 Overfitting 이 발생할 수 있습니다.

     

    그래서 Regularlization 을 적용하였고, 이러한 표현은 아래와 같습니다.

     

    위 표현식은 Optimization 을 수행하기 위해서 실제 값인 $r_{ui}$ 와 예측 값인 $\widehat{r}_{ui}$ 의 RMSE 를 계산합니다.

    그리고 위 RMSE 의 Gradient Descent 를 통해서 User & Item 의 Latent Matrix 를 최적화시킬 수 있습니다.

    하지만 Overfitting 을 방지하기 위해서 $ \lambda(b_{i}^{2} + b_{u}^{2} + \left\|q_{i}\right\|^{2} + \left\|p_{u}\right\|^{2}) $

    Regularization Term 을 추가합니다.

     

    $ \lambda $ 는 SVD 모델의 인자로써 설정이 가능한 Parameter 입니다.

    일반적으로 0.02 를 기본적으로 사용합니다.

    (reg_all – The regularization term for all parameters. Default is 0.02.)

     

    $\left\|q_{i}\right\|$ 는 Item Latent Vector 의 크기를 의미합니다.

    다차원 벡터이기 때문에 벡터의 모든 값을 제곱합한 후에 Root 를 취합니다.

    마찬가지로 $\left\|p_{u}\right\|$ 는 User Latent Vector 의 크기를 의미합니다.

     

    그래서 reg_all 설정을 통해서 Overfitting 을 방지할 수 있습니다.

    rmse_list = []
    reg_alls = [0.001, 0.002, 0.02, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7]
    for reg_all in reg_alls:
        algo = SVD(n_factors=200, n_epochs=100, biased=True, reg_all=reg_all, verbose=False)
        model = algo.fit(trainset)
        predictions = model.test(testset, verbose=False)
        print(reg_all, accuracy.rmse(predictions, verbose=False))
        rmse_list.append(accuracy.rmse(predictions, verbose=False))

    biased.

    일반적인 SVD 는 아래와 같은 공식을 취합니다.

     

    $$ \widehat{r}_{ab} = \mu + userbias_{a} + itembias_{b} + u_{a}i_{b}^{T} $$

     

    $ \widehat{r}_{ab} $ 은 "User a""Item b" 에 대한 예측 선호도를 의미하구요.

    $u_{a} \cdot i_{b}^{T}$ 는 "User a" 의 Latent Vector, "Item b" 의 Latent Vector 의 Dot Product 를 의미합니다.

    여기에서 Bias Term 이 추가됩니다.

     

    Bias Term 이 필요한 이유는 사용자 개개인의 평점에 대한 기준이 다를 수 있구요.

    후하게 점수를 주는 사람이 있을 수 있고, 짜게 점수를 매기는 사람이 존재할 수도 있죠.

    그리고 과대평가되는 상품과 그렇지 않은 상품이 있을 수도 있습니다.

    그래서 개별적인 User 에 대한 $userbias$ Vector 과 개별적인 Item 에 대한 $itembias$ 두어 개별적인 Bias 를 계산합니다.

     

    ( 참고로 "a User" 의 Bias 는 $userbias_{a}$ 로,  "b Item" 의 Bias $itembias_{b}$ 로 표현됩니다. )

     

    Bias 를 계산하는 방식은 아래와 같습니다.

     

    위와 같은 계산식이 도출된 이유는 아래의 식을 $b_{u}$ 와 $b_{i}$ 관점에서 미분을 취하고,

    learing_rate 와 합산하여 최적화를 수행합니다.

     

     

    biased 옵션은 Bias 를 사용할지 말지를 결정하는 Boolean 타입의 인자입니다.

    일반적으로 Bias 를 적용하는 것이 정확도가 더 높습니다.

     

    rmse_list = []
    biased_false_rmse_list = []
    reg_alls = [0.001, 0.002, 0.02, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7]
    for reg_all in reg_alls:
        algo = SVD(n_factors=200, n_epochs=100, biased=False, reg_all=reg_all, verbose=False)
        model = algo.fit(trainset)
        predictions = model.test(testset, verbose=False)
        print(reg_all, accuracy.rmse(predictions, verbose=False))
        biased_false_rmse_list.append(accuracy.rmse(predictions, verbose=False))
    
        algo = SVD(n_factors=200, n_epochs=100, biased=True, reg_all=reg_all, verbose=False)
        model = algo.fit(trainset)
        predictions = model.test(testset, verbose=False)
        print(reg_all, accuracy.rmse(predictions, verbose=False))
        rmse_list.append(accuracy.rmse(predictions, verbose=False))

     

     

    위 그래프에서 주황색의 X 선이 Bias 을 적용하지 않은 상태이고, 파란색 O 선은 Bias 를 적용한 상태의 RMSE 그래프입니다.

    Biased 를 적용하는 것이 좀 더 좋은 성능을 보입니다.

     

    n_epochs.

    n_epochs 인자는 이름 그대로 Training 을 반복하는 횟수를 설정합니다.

     

     

    마치며.

    이번 글에서는 SVD 의 구체적의 사용법에 대해서 알아보았습니다.

    Regularization, Biased 와 같이 SVD 와 직접적인 관련은 없더라도 머신러닝의 퍼포먼스를 위해 사용되는 개념들도 함께 다루어 보았습니다.

    혹신나 틀린 내용이 있거나 이해가 어려우신 내용이 있다면 피드백주시면 좋을 것 같아요.

     

     

    반응형
Designed by Tistory.