Lightfm:处理用户和项目冷启动

boh*_*ohr 7 python recommendation-engine cold-start matrix-factorization

我记得lightfm的一个优点是模型没有冷启动问题,用户和物品冷启动:lightfm原纸

但是,我仍然不明白如何使用lightfm来解决冷启动问题.我训练了我的模特user-item interaction data.据我所知,我只能对我的数据集上存在的profile_ids进行预测.

def predict(self, user_ids, item_ids, item_features=None,
            user_features=None, num_threads=1):
    """
    Compute the recommendation score for user-item pairs.

    Arguments
    ---------

    user_ids: integer or np.int32 array of shape [n_pairs,]
         single user id or an array containing the user ids for the
         user-item pairs for which a prediction is to be computed
    item_ids: np.int32 array of shape [n_pairs,]
         an array containing the item ids for the user-item pairs for which
         a prediction is to be computed.
    user_features: np.float32 csr_matrix of shape [n_users, n_user_features], optional
         Each row contains that user's weights over features.
    item_features: np.float32 csr_matrix of shape [n_items, n_item_features], optional
         Each row contains that item's weights over features.
    num_threads: int, optional
         Number of parallel computation threads to use. Should
         not be higher than the number of physical cores.

    Returns
    -------

    np.float32 array of shape [n_pairs,]
        Numpy array containing the recommendation scores for pairs defined
        by the inputs.
    """

    self._check_initialized()

    if not isinstance(user_ids, np.ndarray):
        user_ids = np.repeat(np.int32(user_ids), len(item_ids))

    assert len(user_ids) == len(item_ids)

    if user_ids.dtype != np.int32:
        user_ids = user_ids.astype(np.int32)
    if item_ids.dtype != np.int32:
        item_ids = item_ids.astype(np.int32)

    n_users = user_ids.max() + 1
    n_items = item_ids.max() + 1

    (user_features,
     item_features) = self._construct_feature_matrices(n_users,
                                                       n_items,
                                                       user_features,
                                                       item_features)

    lightfm_data = self._get_lightfm_data()

    predictions = np.empty(len(user_ids), dtype=np.float64)

    predict_lightfm(CSRMatrix(item_features),
                    CSRMatrix(user_features),
                    user_ids,
                    item_ids,
                    predictions,
                    lightfm_data,
                    num_threads)

    return predictions
Run Code Online (Sandbox Code Playgroud)

任何建议或指示,以帮助我的理解将真的很感激.谢谢

pet*_*urg 8

这对我有用:

if user_index is not None:
    predictions = model.predict([user_index, ], np.array(target_item_indices))
else:
    predictions = model.predict(0, np.array(target_item_indices), user_features=user_features)
Run Code Online (Sandbox Code Playgroud)

这里user_features是一个稀疏数组,它是根据训练模型时使用的特征集精心组装而成的。

例如,如果我获得了一个新用户,并且该用户的功能类似于user_feature_list = ["id-2837", "Cape Town", "Woodstock", 7700],那么我将按如下方式构建功能数组:

from scipy import sparse

user_feature_map = store_model.user_feature_map  # the feature map was persisted during the previous round of offline training
num_features = len(user_feature_list)
normalised_val = 1.0 / num_features
target_indices = []
for feature in user_feature_list:
    try:
        target_indices.append(user_feature_map[feature])
    except KeyError:
        print("new user feature encountered '{}'".format(feature))
        pass
print("target indices: {}".format(target_indices))
user_features = np.zeros(len(user_feature_map.keys()))
for i in target_indices:
    user_features[i] = normalised_val
user_features = sparse.csr_matrix(user_features)
Run Code Online (Sandbox Code Playgroud)

user_feature_map通过调用LightFM的先前生成的mapping()原始输入数据集法,拟合后:

dataset.fit(
    unique_user_ids,
    unique_item_ids,
    item_features=item_feature_list,
    user_features=user_feature_list
)

user_id_map, user_feature_map, item_id_map, item_feature_map = dataset.mapping()
Run Code Online (Sandbox Code Playgroud)


Mac*_*ula 5

像其他任何推荐算法一样,如果未给LightFM提供有关这些用户的其他信息,则LightFM无法对其做出预测。尝试为新用户提供建议时,技巧是根据算法在训练过程中看到的功能来描述它们。

最好用一个例子来解释。假设您的训练集中有ID在0到10之间的用户,并且您要对新用户ID 11进行预测。如果您拥有的只是新用户的ID,则该算法将无法进行预测:毕竟,它不了解用户11的偏好是什么。但是,假设您具有一些描述用户的功能:也许在注册过程中,每个用户都会选择他们拥有的许多兴趣(例如,恐怖电影或浪漫喜剧)。如果在训练过程中存在这些功能,则该算法可以了解平均而言哪些偏好与这些特征相关联,并且能够为可以使用相同特征描述的任何新用户提供推荐。在这个例子中

在LightFM实现中,所有这些特征都将以特征矩阵的形式进行编码,可能采用一键编码的形式。在为用户11提出建议时,您将为该用户构造一个新的特征矩阵:只要该特征矩阵仅包含训练过程中存在的特征,就可以进行预测。

请注意,具有仅与单个用户相对应的功能通常是有用的-因此,“ Is user 0”功能,“ Is user 1”功能等等。在新用户的情况下,这样的功能是没有用的,因为在训练中没有任何信息可供模型用来了解该功能。

  • @bohr 您好,您愿意分享您的代码来解决如何解决添加新用户的问题吗?我正在尝试自己解决这个问题,但我有点挣扎......谢谢! (3认同)