作者:杰少,炼丹笔记嘉宾
在许多的问题中,例如之前kaggle的KKBox音乐推荐,亦或者是现在的微信推荐大赛,都出现了同样一个问题,用户或者商品的冷启动问题,
处理冷启动问题的策略有非常多,最为常见的有利用side信息等等,本文我们不讲太多其它的操作,直接介绍在KKBox中决定金牌和银牌的一个操作,SVD处理冷启动。
SVD分解的构建思路很简单,其数学上就是矩阵SVD分解,但类比到实际问题中则可以处理非常多的问题。此处我们介绍其构建步骤:
- 构建用户U和商品I的交互矩阵;
- 对稀疏矩阵进行SVD分解,得到用户U和商品I的向量;
- 将用户向量和商品向量作为特征拼接到用户和商品侧。
- 此处我们以KKBox用户听歌为例,我们对用户和歌曲的交互矩阵进行SVD分解。
''' 代码摘自:https://github.com/lystdo/Codes-for-WSDM-CUP-Music-Rec-1st-place-solution/blob/master/input/training/script/svd_process.py ''' import numpy as np import pandas as pd from scipy import sparse from scipy.sparse.linalg import svds concat = tr[['msno', 'song_id']].append(te[['msno', 'song_id']]) member_cnt = concat['msno'].max() + 1 song_cnt = concat['song_id'].max() + 1 ### 1.构建交互稀疏矩阵 data = np.ones(len(concat)) msno = concat['msno'].values song_id = concat['song_id'].values rating = sparse.coo_matrix((data, (msno, song_id))) rating = (rating > 0) * 1.0 ### 2.进行SVD分解 ## svd for user-song pairs n_component = 48 [u, s, vt] = svds(rating, k=n_component) print(s[::-1]) s_song = np.diag(s[::-1]) ### 3.生成SVD特征向量 members_topics = pd.DataFrame(u[:, ::-1]) members_topics.columns = ['member_component_%d'%i for i in range(n_component)] members_topics['msno'] = range(member_cnt) member = member.merge(members_topics, on='msno', how='right') song_topics = pd.DataFrame(vt.transpose()[:, ::-1]) song_topics.columns = ['song_component_%d'%i for i in range(n_component)] song_topics['song_id'] = range(song_cnt) song = song.merge(song_topics, on='song_id', how='right')
涉及到冷启动的问题都可以使用SVD特征进行冷启动尝试,有奇效。