天天看點

拓端tecdat|Python使用矩陣分解法找到類似的音樂加載資料矩陣分解潛在語義分析LSA 隐含的交替最小二乘法

原文連結:http://tecdat.cn/?p=6054

這篇文章是如何使用幾種不同的矩陣分解算法計算相關藝術家。代碼用Python編寫,以互動方式可視化結果。

加載資料

這可以使用Pandas加載到稀疏矩陣中:

# read in triples of user/artist/playcount from the input datasetdata = pandas.read_table("usersha1-artmbid-artname-plays.tsv",

                        usecols=[0, 2, 3],

                        names=['user', 'artist', 'plays'])# map each artist and user to a unique numeric valuedata['user'] = data['user'].astype("category")data['artist'] = data['artist'].astype("category")# create a sparse matrix of all the artist/user/play triplesplays = coo_matrix((data['plays'].astype(float),

                  (data['artist'].cat.codes,

                    data['user'].cat.codes)))
           

這裡傳回的矩陣有300,000名藝術家和360,000名使用者,總共有大約1700萬條目。每個條目都是使用者播放藝術家的次數,其中的資料是從2008年的Last.fm API收集的。

矩陣分解

通常用于此問題的一種技術是将使用者 - 藝術家 - 戲劇的矩陣投影到低等級近似中,然後計算該空間中的距離。

我們的想法是采用原始的播放計數矩陣,然後将其減少到兩個小得多的矩陣,這些矩陣在乘以時接近原始矩陣:

拓端tecdat|Python使用矩陣分解法找到類似的音樂加載資料矩陣分解潛在語義分析LSA 隐含的交替最小二乘法

Artist/User/Play CountsArtist FactorsUser Factors=×

代替将每個藝術家表示為所有360,000個可能使用者的遊戲計數的稀疏向量,在對矩陣進行因式分解之後,每個藝術家将由50維密集向量表示。

通過減少這樣的資料的維數,我們實際上将輸入矩陣壓縮為兩個小得多的矩陣。

潛在語義分析

出于本文的目的,我們隻需要知道SVD生成輸入矩陣的低秩近似。

像這樣使用SVD稱為潛在語義分析(LSA)。所有真正涉及的是在這個分解空間中通過餘弦距離獲得最相關的藝術家:

class TopRelated(object): def __init__(self, artist_factors): # fully normalize artist_factors, so can compare with only the dot product norms = numpy.linalg.norm(artist_factors, axis=-1) self.factors = artist_factors / norms[:, numpy.newaxis] def get_related(self, artistid, N=10): scores = self.factors.dot(self.factors[artistid]) best = numpy.argpartition(scores, -N)[-N:] return sorted(zip(best, scores[best]), key=lambda x: -x[1])
           

潛在語義分析之是以得名,是因為在對矩陣進行分解之後,可以輸入資料中潛在的隐藏結構 - 這可以被認為是揭示輸入資料的語義。

拓端tecdat|Python使用矩陣分解法找到類似的音樂加載資料矩陣分解潛在語義分析LSA 隐含的交替最小二乘法

LSA 

類似于LSA的'Arcade Fire':

拓端tecdat|Python使用矩陣分解法找到類似的音樂加載資料矩陣分解潛在語義分析LSA 隐含的交替最小二乘法

 雖然LSA成功地概括了我們資料的某些方面,但這裡的結果并不是那麼好。 

隐含的交替最小二乘法

已發現這些模型在推薦項目時效果很好,并且可以很容易地重複用于計算相關藝術家。

推薦系統中使用的許多MF模型都采用了明确的資料,使用者使用類似5星級評定标準評估了他們喜歡和不喜歡的内容。

第一個挑戰是有效地進行這種因式分解:通過将未知數視為負數,天真的實作将檢視輸入矩陣中的每個條目。由于此處的次元大約為360K乘300K - 總共有超過1000億條目要考慮,而隻有1700萬非零條目。

第二個問題是我們不能确定沒有聽藝術家的使用者實際上意味着他們不喜歡它。可能還有其他原因導緻藝術家沒有被收聽,特别是考慮到我們在資料集中每個使用者隻有最多50位藝術家。

 使用二進制偏好的不同置信水準來學習分解矩陣表示:看不見的項目被視為負面且置信度低,其中目前項目被視為正面更高的信心。

那麼目标是通過最小化平方誤差損失函數的置信權重和來學習使用者因子X u和藝術家因子Y i:

def alternating_least_squares(Cui, factors, regularization, iterations=20): users, items = Cui.shape

    X = np.random.rand(users, factors) * 0.01    Y = np.random.rand(items, factors) * 0.01    Ciu = Cui.T.tocsr()    for iteration in range(iterations):        least_squares(Cui, X, Y, regularization)        least_squares(Ciu, Y, X, regularization)    return X, Ydef least_squares(Cui, X, Y, regularization):    users, factors = X.shape

    YtY = Y.T.dot(Y)    for u in range(users):        # accumulate YtCuY + regularization * I in A        A = YtY + regularization * np.eye(factors)        # accumulate YtCuPu in b        b = np.zeros(factors)        for i, confidence in nonzeros(Cui, u):            factor = Y[i]            A += (confidence - 1) * np.outer(factor, factor)            b += confidence * factor

        # Xu = (YtCuY + regularization * I)^-1 (YtCuPu)        X[u] = np.linalg.solve(A, b)
           

為了調用它,我使用與LSA中使用的置信矩陣相同的權重,然後以相同的方式計算相關的藝術家:

artist_factors ,user_factors = alternating_least_squares (bm25_weight (plays ),50 )

與僅使用LSA相比,該方法可以産生明顯更好的結果。 比較Bob Dylan的結果作為一個例子: