AI

[AI] 레시피 추천 모델 만들기 8 - Inference (2) user 기반, item 기반 추천 받기

alsruds 2024. 10. 30. 05:49

일단 비슷하게 추천받을 user_id, item_id 모두 하드 코딩해서 넣어줬다. 추후에 입력받은 item_id 값으로 진행할 예정!

 

💡 User 기반 추천 받기

import argparse
import torch
import numpy as np
import pandas as pd

from recbole.quick_start import load_data_and_model

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--model_path', '-m', type=str, default='saved/model.pth', help='name of models')
    # python RecBole-GNN/run_inference.py --model_path=saved/NGCF-Oct-16-2024_19-14-27.pth 로 실행
    # C:\Users\alsrud\Downloads\Babal-Server\Babal-Server\RecBole\saved\NGCF-Oct-16-2024_19-14-27.pth

    args, _ = parser.parse_known_args()

    # model, dataset 불러오기
    config, model, dataset, train_data, valid_data, test_data = load_data_and_model(args.model_path)

    # device 설정
    device = config.final_config_dict['device']

    # user, item id -> token 변환 array
    user_id2token = dataset.field2id_token['user_id']
    item_id2token = dataset.field2id_token['item_id']

    # user-item sparse matrix
    matrix = dataset.inter_matrix(form='csr')

    # user id, predict item id 저장 변수
    pred_list = None
    user_list = None

    model.eval()
    # 여기서 특정 사용자와 아이템을 수동으로 추가
    user_id = 123  # 예측을 원하는 사용자 ID
    item_id = [1, 2, 3, 4, 5]  # 예측할 아이템 ID 세트

    # interaction 객체 생성
    interaction = {
        'user_id': torch.tensor([user_id]).to(device),
        'item_id': torch.tensor(range(len(item_id2token))).to(device)  # 모든 아이템에 대해 예측
    }

    # 모델을 사용해 추론
    score = model.full_sort_predict(interaction)

    # 예측 결과 처리
    rating_pred = score.cpu().data.numpy().copy()

    # 사용자가 상호작용한 아이템 인덱스를 가져옵니다.
    interacted_indices = matrix[user_id].indices
    rating_pred[interacted_indices] = 0  # 상호작용한 아이템의 점수를 0으로 설정합니다.

    # 상위 5개의 예측 아이템 인덱스를 선택합니다.
    ind = np.argpartition(rating_pred, -5)[-5:]
    arr_ind = rating_pred[ind]
    arr_ind_argsort = np.argsort(arr_ind)[::-1]

    # 실제 값들을 정렬된 순서대로 인덱스 배열에 적용
    batch_pred_list = ind[arr_ind_argsort]

    # 예측값 저장
    if pred_list is None:
        pred_list = batch_pred_list
        user_list = np.array([user_id] * len(batch_pred_list))
    else:
        pred_list = np.append(pred_list, batch_pred_list, axis=0)
        user_list = np.append(user_list, np.array([user_id] * len(batch_pred_list)), axis=0)

    # 결과를 DataFrame으로 변환하고 CSV 파일로 저장
    final_result = []
    for user, item in zip(user_list, pred_list):
        # 예측된 아이템이 유효한지 확인합니다.
        if user < len(user_id2token) and item < len(item_id2token):
            original_user_seq = user_id2token[user]
            original_item_seq = item_id2token[item]
            final_result.append((original_user_seq, original_item_seq))
        else:
            print(f"Warning: User ID {user} or Item ID {item} is out of bounds.")

    # 결과를 DataFrame으로 변환하고 CSV 파일로 저장
    final_dataframe = pd.DataFrame(final_result, columns=["user", "item"])
    final_dataframe.sort_values(by='user', inplace=True)
    final_dataframe.to_csv('saved/submission.csv', index=False)
    print('Final mapping done and saved to CSV!')

 

 

💡 Item 기반 추천 받기

import argparse
import torch
import numpy as np
import pandas as pd

from recbole.quick_start import load_data_and_model

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--model_path', '-m', type=str, default='saved/model.pth', help='name of models')
    # python RecBole-GNN/run_inference.py --model_path=saved/NGCF-Oct-16-2024_19-14-27.pth 로 실행
    # C:\Users\alsrud\Downloads\Babal-Server\Babal-Server\RecBole\saved\NGCF-Oct-16-2024_19-14-27.pth

    args, _ = parser.parse_known_args()

    # model, dataset 불러오기
    config, model, dataset, train_data, valid_data, test_data = load_data_and_model(args.model_path)

    # device 설정
    device = config.final_config_dict['device']

    # user, item id -> token 변환 array
    user_id2token = dataset.field2id_token['user_id']
    item_id2token = dataset.field2id_token['item_id']

    # user-item sparse matrix
    matrix = dataset.inter_matrix(form='csr')

    # 특정 사용자의 아이템 ID
    liked_item_id = 1  # 예시: 사용자가 좋아하는 아이템 ID

    # 사용자가 좋아하는 아이템을 좋아하는 사용자 ID 찾기
    users_who_liked_item = matrix[:, liked_item_id].nonzero()[0]

    # 예측할 사용자 ID 및 아이템 ID 설정
    user_ids = users_who_liked_item
    all_item_ids = np.arange(len(item_id2token))  # 모든 아이템 ID

    # 사용자-아이템 상호작용 객체 생성
    interaction = {
        'user_id': torch.tensor(user_ids).to(device),
        'item_id': torch.tensor(all_item_ids).to(device)
    }

    model.eval()
    # 모델을 사용해 추론
    scores = model.full_sort_predict(interaction)

    # 예측 결과 처리
    rating_pred = scores.cpu().data.numpy()  # 1차원 배열로 예상 점수 가져오기

    final_result = []

    # 각 사용자에 대해 상위 N개의 추천 아이템 추출
    top_n = 5
    for user in users_who_liked_item:
        # 사용자의 상호작용한 아이템 인덱스 가져오기
        interacted_indices = matrix[user].indices  # 해당 사용자의 상호작용한 아이템 인덱스
        rating_pred[interacted_indices] = 0  # 이미 좋아하는 아이템의 점수 0으로 설정

        # 상위 N개의 추천 아이템 인덱스 추출
        recommended_item_indices = np.argsort(rating_pred)[-top_n:][::-1]

        for item_index in recommended_item_indices:
            # 추천된 아이템이 유효한지 확인
            if item_index < len(item_id2token):
                # 추천된 아이템의 실제 ID 가져오기
                original_item_seq = item_id2token[item_index]
                final_result.append((user, original_item_seq))

    # 추천 결과를 DataFrame으로 변환하고 CSV 파일로 저장
    final_results = []
    for user, item in final_result:
        original_user_seq = user_id2token[user]
        final_results.append((original_user_seq, item))

    final_dataframe = pd.DataFrame(final_results, columns=["user", "recommended_item"])
    final_dataframe.to_csv('saved/recommendation.csv', index=False)
    print('Recommendations saved to CSV!')