我正在寻求配置最佳模型来测量隐式反馈给定我的唯一用户的嵌套字典和每个艺术家听过的播放次数。我尝试了一些值,但它们看起来只是装饰性的,而不是可测量的。
示例数据:
users artist plays
0 00001411dc427966b17297bf4d69e7e193135d89 korn 12763
1 00001411dc427966b17297bf4d69e7e193135d89 sting 8192
2 00001411dc427966b17297bf4d69e7e193135d89 nirvana 6413
源代码:
user_artist_dict = user_artist_plays.groupby('users').apply(lambda user_artist_plays: dict(zip(user_artist_plays.artist, user_artist_plays.plays))).to_dict()
如果用户没有听艺术家的话,我想要一个矩阵分解 0
播放,如果他们有它插入播放
。
我最初的意图是将 DictVectorizer 与 sklearn 一起使用,但它给我带来了 artist
字符串的麻烦。
最佳答案
稀疏版本。
当前版本的pandas
对稀疏数据的支持有限,您可以调用pd.get_dummies(sparse=True)
,它会返回一些SparseDataFrame
,但是作为大多数操作的结果,它将被转换回DataFrame
。
unstack
和 pivot_table
的稀疏版本仍在 roadmap 中。
所以我们应该使用其他库来解决它,例如sklearn有LabelBinarizer与 pd.get_dummies 具有相同的功能,但它可以返回 scipy.sparse 矩阵。然后借助代数小技巧我们就可以实现目标。
测试数据样本将有助于检查计算的正确性:
df = pd.DataFrame([
['a1', 11, 'u1'], ['a3', 23, 'u2'], ['a2', 22, 'u2'],
['a3', 33, 'u3'], ['a1', 31, 'u3'], ['a2', 32, 'u3'],
['a5', 45, 'u4'], ['a4', 44, 'u4'], ['a3', 43, 'u4'],
['a2', 42, 'u4']], columns =['artist', 'plays', 'users'])
print(df.pivot_table(values='plays',index='users',
columns='artist',aggfunc='sum',fill_value=0))
输出
artist a1 a2 a3 a4 a5
users
u1 11 0 0 0 0
u2 0 22 23 0 0
u3 31 32 33 0 0
u4 0 42 43 44 45
结果相同但稀疏
from sklearn.preprocessing import LabelBinarizer
from scipy.sparse import diags
lb_artist = LabelBinarizer(sparse_output=True)
lb_user = LabelBinarizer(sparse_output=True)
X = lb_user.fit_transform(df.users).T*(diags(df.plays)*lb_artist.fit_transform(df.artist))
print(type(X),'shape:',X.shape,'values:',X.nnz,'data:')
print(X)
输出。对于测试示例,它应该是 (user,artist) 10*(user+1)+artist+1
<class 'scipy.sparse.csc.csc_matrix'> shape: (4, 5) values: 10 data:
(2, 0) 31.0
(0, 0) 11.0
(3, 1) 42.0
(2, 1) 32.0
(1, 1) 22.0
(3, 2) 43.0
(2, 2) 33.0
(1, 2) 23.0
(3, 3) 44.0
(3, 4) 45.0
lb_user
和 lb_artist
存储可用于恢复原始帧的键的字符串值。
print(
pd.DataFrame(X.todense(),index=lb_user.classes_,columns=lb_artist.classes_)
)
输出:
a1 a2 a3 a4 a5
u1 11.0 0.0 0.0 0.0 0.0
u2 0.0 22.0 23.0 0.0 0.0
u3 31.0 32.0 33.0 0.0 0.0
u4 0.0 42.0 43.0 44.0 45.0
<小时/>
关于使用隐式反馈方法将 python 字典转换为矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48978463/