轉載:資料探勘之_SVD的python實現和分析
作者:NumX
來源:CSDN
原文:https://blog.csdn.net/baidu_36316735/article/details/53760479?utm_source=copy
前言
今日實現第一個推薦演算法,在”機器學習實戰“一書中找到了SVD方法一章練習。這裡總結下筆記經驗,與大家分享 。
簡介
對於一個簡單的推薦系統,例如電影推薦,我們知道N個使用者對M個電影的評分。這時候對於一個新的使用者,我們應該如何給他推薦新的電影呢?一個最簡單的方法,根據使用者已看的電影,找出與他相似的使用者,然後推薦其他未看的高得分的電影。SVD提供了一個更加準確的解決方案。其基本思想是,降維!
對於電影,一般的推薦演算法是將每個電影的評分作為一個維度,對於Xi使用者,就有一個矩陣行 Xi = [xi1,xi2,xi3....xij]。 但是電影如此之多,每個人又不可能看過所有的電影,這將造成矩陣非常巨大,然後非常稀疏。SVD的具體思想是提取電影的引數Q1, ..., Qj。這個引數可以表達為電影的動作,搞笑,恐怖等程度的描述。因此後面的推薦演算法中,我們不需要對每個電影的口味進行分析,當給定新使用者的時候直接推薦適合他口味,即基於電影引數Qj的一個評分相符,的電影即可。
實現
實現SVD,只需要python中的numpy,其中有一個線性代數工具箱linalg。
import numpy as np data = [[1,2,3],[2,2,3],[3,3,3]] U,S,V = np.linalg.svd(data) >>> U array([[-0.48273945, 0.76567677, 0.42509024], [-0.54696309, 0.11548497, -0.82915294], [-0.68395468, -0.63277351, 0.36304778]]) >>> S array([ 7.51653849, 1.17761678, 0.33892171]) >>> V array([[-0.48273945, -0.54696309, -0.68395468], [-0.76567677, -0.11548497, 0.63277351], [-0.42509024, 0.82915294, -0.36304778]])
其中S向量只儲存了對角元素的成分,可以大大節省儲存空間。接下來我們就需要保留部分奇異值,對於保留的數量,一個典型的方法就是保留矩陣中90%的能量資訊。能量資訊為奇異值的平和總和。
看到這裡是否想起了PCA分析,同樣的分解矩陣,同樣的計算能量資訊。下面討論章節我會進行一些個人總結。
那麼演算法實現了,具體應用到推薦中該如何做呢?對於使用者沒有看過的電影,我們只需要計算與使用者看過的電影中的高評分電影的相似度,然後推薦相似度高的電影即可。你或許聽過協同過濾(collaborative filtering),沒聽過沒關係,我們要做得就是協同過濾。也就是基於使用者與其他使用者的資料進行對比來實現精確推薦。另外還有可以基於內容的推薦,不在本文考慮範圍。
計算相似度的集中方法,有:
歐式距離,資料差的的平方和
相關係數,一般為皮爾遜相關係數(Pearson correlation)
餘弦相似性,兩個向量的餘弦夾角的大小
注意,計算相似度後,最好把資料歸一化,一般歸一化到0-1的範圍。計算相似度中我們一般考慮使用基於物品的相似度的分析。原因是由實際考慮的。設想你有一個商店,商品種類可能不太會變動,但是使用者不斷進進出出,那麼計算那個方便呢! 對,由於物品的穩定性更高,計算量小,那麼就基於物品的推薦即可。
事例
假設你有一家餐館,然後有資料(自己想想資料是什麼吧)。怎麼給使用者推薦他沒有嘗試過的菜品呢。一般我們看到是直接上我們的特色菜,這個就沒有針對性了。我們試試基於SVD的推薦演算法。具體步驟為:
(1)收集資料!
(2)建立使用者評價矩陣
(3)針對特定使用者,找到其沒有評價的物品,計算其評分
(4)將預測的物品評分從大到小排序,然後推薦給使用者。
結合最後的程式,執行下面的推薦命令,即可完成給使用者0推薦3個產品的任務
user = 0
dataMat = mat(loadExData2())
# 直接實現
rec1 = recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=standEst)
# 採用SVD方法實現
rec2 = recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=svdEst)
(Pdb) rec1
[(0, 5.0), (1, 5.0), (2, 5.0)]
(Pdb) rec2
[(7, 4.5148349067003304), (8, 4.514365463123859), (0, 4.5142831096323039)]
討論
(1)SVD全程為Singular Value Decomposition, 即奇異值分解。假設原始資料為m*n的矩陣,SVD會將矩陣分解為三個矩陣的乘積,中間的矩陣為一個對角不為零其餘元素為0的矩陣。那些部位0的對角元素即為奇異值。
(2)SVD其實是一種矩陣分解技術,不同的矩陣分解技術可能適合不同的應用。其他技術,例如PCA。同樣可以用於影象壓縮等其他應用。
(3)其他推薦演算法。
試想另外一種情形,假設一個商家想看怎麼捆綁銷售可以獲得利益最大化怎麼辦。這時候要考慮在所有銷售商品中,哪兩種或幾種商品銷售趨勢很一致。這其實也是一種推薦過程。這個過程中使用者的評價暫時忽略,我們嘗試找銷售量相似的產品。這裡提供一下大致的思路。
a, 計算兩兩產品的相關係數
b, 對某一產品,按照相關係數排序
c, 對排序結果,挑選相關係數最大的物品做捆綁銷售。
(4)SVD演算法其實會消耗大量的網路資源。因此實際操作的時候考慮到效率問題,大規模計算一般會是在離線情況下一天計算一次相似性,並且儲存相似性得分。加入網站剛開始建立,資料量不足(冷啟動問題),可以考慮用搜索問題來解決推薦。
理論上有很多推薦的演算法,按內容推薦, 協同過濾(包括item-based, user-based, SVD分解等),上下文推薦,Constraint-based推薦,圖關係挖掘等。很多比較牛的單個演算法, 就能在某個指標上取得較好效果, 例如MAE,RMSE。。。不過有自己的優點, 每種演算法也有自己的缺點, 例如按內容推薦主要推薦和使用者歷史結果相似的item,一般的item-based容易推薦熱門item(被更多人投票過)。。。。 所以在工業界,例如各網際網路公司, 都會使用多種演算法進行互相配合, 取長補短, 配合產品提升效果。而且在完整的推薦系統中,不僅有傳統的Rating推薦, 還需要輔以非常多的挖掘, Ranking來達到預期效果。
圖片來自引用參考2
#!/usr/bin/env python
# -*- coding: UTF-8
from numpy import *
from numpy import linalg as la
import numpy as np
def loadExData2():
return[[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5],
[0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],
[0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0],
[3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0],
[5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0],
[0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0],
[4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1],
[0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4],
[0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2],
[0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0],
[1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]]
def ecludSim(inA,inB):
return 1.0/(1.0 + la.norm(inA - inB))
def pearsSim(inA,inB):
if len(inA) < 3 : return 1.0
return 0.5+0.5*corrcoef(inA, inB, rowvar = 0)[0][1]
def cosSim(inA,inB):
num = float(inA.T*inB)
denom = la.norm(inA)*la.norm(inB)
return 0.5+0.5*(num/denom)
def standEst(dataMat, user, simMeas, item):
'''
計算相似性
資料矩陣,使用者ID, 相似度方法, 物品ID
simMeas: ecludSim, pearsSim, cosSim
'''
n = shape(dataMat)[1]
simTotal = 0.0; ratSimTotal = 0.0
# 不同的物品
for j in range(n):
userRating = dataMat[user,j]
if userRating == 0: continue
# 對兩個物品,item和j,考慮都有評價的部分
overLap = nonzero(logical_and(dataMat[:,item].A>0, \
dataMat[:,j].A>0))[0]
if len(overLap) == 0:
similarity = 0
else:
similarity = simMeas(dataMat[overLap,item], \
dataMat[overLap,j])
print 'the %d and %d similarity is: %f' % (item, j, similarity)
simTotal += similarity
ratSimTotal += similarity * userRating
# 返回歸一化的結果
if simTotal == 0:
return 0
else:
return ratSimTotal/simTotal
def svdEst(dataMat, user, simMeas, item):
'''
基於SVD的相似性計算
'''
n = shape(dataMat)[1]
simTotal = 0.0; ratSimTotal = 0.0
U,Sigma,VT = la.svd(dataMat)
# 只考慮前四個元素,轉化成矩陣形式
Sig4 = mat(eye(4)*Sigma[:4]) #arrange Sig4 into a diagonal matrix
# 將資料降維轉化
xformedItems = dataMat.T * U[:,:4] * Sig4.I #create transformed items
for j in range(n):
userRating = dataMat[user,j]
if userRating == 0 or j==item: continue
similarity = simMeas(xformedItems[item,:].T,\
xformedItems[j,:].T)
print 'the %d and %d similarity is: %f' % (item, j, similarity)
simTotal += similarity
ratSimTotal += similarity * userRating
if simTotal == 0: return 0
else: return ratSimTotal/simTotal
def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=standEst):
'''
針對某一使用者,user,進行推薦。返回dictionary
N : 推薦物品個數
simMeas : 相似性計算方法
estMethod : 針對某一使用者的某一物品,計算相似性的程式,返回向量。
'''
unratedItems = nonzero(dataMat[user,:].A==0)[1]#find unrated items
if len(unratedItems) == 0: return 'you rated everything'
itemScores = []
for item in unratedItems:
estimatedScore = estMethod(dataMat, user, simMeas, item)
itemScores.append((item, estimatedScore))
return sorted(itemScores, key=lambda jj: jj[1], reverse=True)[:N]
def printMat(inMat, thresh=0.8):
for i in range(32):
for k in range(32):
if float(inMat[i,k]) > thresh:
print 1,
else: print 0,
print ''
def imgCompress(numSV=3, thresh=0.8):
# 用svd方法進行影象壓縮
myl = []
for line in open('0_5.txt').readlines():
newRow = []
for i in range(32):
newRow.append(int(line[i]))
myl.append(newRow)
myMat = mat(myl)
print "****original matrix******"
printMat(myMat, thresh)
U,Sigma,VT = la.svd(myMat) # svd
SigRecon = mat(zeros((numSV, numSV)))
for k in range(numSV):#construct diagonal matrix from vector
SigRecon[k,k] = Sigma[k]
# reconstruct with the first numSV feature
reconMat = U[:,:numSV]*SigRecon*VT[:numSV,:]
print "****reconstructed matrix using %d singular values******" % numSV
printMat(reconMat, thresh)
相關推薦
轉載:資料探勘之_SVD的python實現和分析
作者:NumX 來源:CSDN 原文:https://blog.csdn.net/baidu_36316735/article/details/53760479?utm_source=copy 前言 今日實現第一個推薦演算法,在”機器學習實戰“一書中找到了SVD方法一
資料探勘之頻繁項集分析
頻繁項集最經典和常用的應用就是超市的購物籃分析。每個購物籃裡有很多商品,每個商品都是一項元素,每個購物籃都是一個集合,所有購物籃就形成了一個系列集合。 分析哪些商品經常一起頻繁出現在購物籃內,即找到頻繁項集,然後,再分析其他商品與頻繁項集的關係,即關聯規則。 1. 什麼是
資料探勘之FP_Tree演算法實現
轉自http://www.cnblogs.com/zhangchaoyang/articles/2198946.html (格式複製之後有變化,建議直接點連結去部落格園看原文) python程式碼見https://github.com/yantijin/Lean_DataMining F
資料探勘之關聯規則挖掘之Apriori演算法實現
演算法細節見論文:Fast Algorithm for Mining Association Rules 控制檯版本C++程式碼如下: #include <iostream> #include <sstream> #include <fs
資料探勘之推薦分析--python實現
# # FILTERINGDATA.py # # Code file for the book Programmer's Guide to Data Mining # http://guidetodatamining.com # Ron Zacharski # #
資料探勘之曼哈頓距離、歐幾裡距離、明氏距離、皮爾遜相關係數、餘弦相似度Python實現程式碼
# -*- coding:utf8 -*- from math import sqrt users = {"Angelica": {"Blues Traveler": 3.5, "Broken Bells": 2.0, "Norah Jones": 4.5, "Phoeni
R語言學習系列(資料探勘之決策樹演算法實現--ID3程式碼篇)
轉載自:http://blog.csdn.net/hawksoft/article/details/7760868 1、輔助類,用於計算過程和結果儲存 [csharp] view plaincopyprint? /// &
Thinking in SQL系列之六:資料探勘Apriori關聯分析再現啤酒尿布神話
原創: 牛超 2017-03-19 Mail:[email protected] 說起資料探勘機器學習,印象中很早就聽說過關於啤酒尿布的神話,這個問題經常出現在資料倉庫相關的文章中,由此可見啤酒尿布問題對資料探勘領域影響的深遠端度。先看看它的成因:“啤酒
Thinking in SQL系列之五:資料探勘K均值聚類演算法與城市分級
原創: 牛超 2017-02-21 Mail:[email protected] 引言:前一篇文章開始不再介紹簡單演算法,而是轉到資料探勘之旅。感謝CSDN將我前一篇機器學習C4.5決策樹演算法的博文推送到了首頁,也非常榮幸能夠得到雲和恩墨的蓋老師的
資料探勘之_SVD的python實現和分析pin
前言 今日實現第一個推薦演算法,在”機器學習實戰“一書中找到了SVD方法一章練習。這裡總結下筆記經驗,與大家分享 。 簡介 對於一個簡單的推薦系統,例如電影推薦,我們知道N個使用者對M個電影的評分。這時候對於一個新的使用者,我們應該如何給他推薦新的電影呢?一個最簡單的方法,
Thinking in SQL系列之四:資料探勘C4.5決策樹演算法
原創: 牛超 2017-02-11 Mail:[email protected] C4.5是一系列用在機器學習和資料探勘的分類問題中的演算法。它的目標是監督學習:給定一個數據集,其中的每一個元組都能用一組屬性值來描述,每一個元組屬於一個互斥的類別中的某一
資料探勘之售房資料分析1
最近再做一批關於售房的資料,感覺自己陷入一個死衚衕裡: 該批資料是儲存再postgresql裡面,是從某售房網站上爬下來的,以資料庫中的一列欄位作為儲存資料,該列欄位是以json的資料形式儲存的,這裡跟我打開了一個新大門,資料庫能儲存json資料格式的資料,而且postgresql還有一套專門的
資料探勘之十大經典演算法
國際權威的學術組織the IEEE International Conference on Data Mining (ICDM) 2006年12月評選出了資料探勘領域的十大經典演算法:C4.5, k-Means, SVM, Apriori, EM, PageRank, AdaBoost, k
資料探勘之AdaBoost裝袋提升演算法
python3程式碼實現在https://github.com/yantijin/Lean_DataMining上,時間匆忙,敬請之處錯誤之處,謝謝! 以下內容轉自:https://blog.csdn.net/androidlushangderen/article/details/4363511
資料探勘之關聯規則Apriori演算法
一、Aoriori原始演算法: 頻繁挖掘模式與關聯規則 關聯規則兩個基本的指標(假設有事務A和事務B) 1、支援度(suport):計算公式如下 2、置信度(confidence): 關聯規則的挖掘過程: 1、設定最小支援度閾值,找出所有的頻繁項集且每個出現的次數要
零基礎入門大資料探勘之spark中的幾種map
今天再來說一下spark裡面的幾種map方法。前面的文章介紹過單純的map,但是spark還有幾種map值得對比一下,主要是下面幾種: map:普通的map flatMap:在普通map的基礎上多了一個操作,扁平化操作; mapPartitions:相對於分割槽P
零基礎入門大資料探勘之spark的rdd
本節簡單介紹一下spark下的基本資料結構RDD,方便理解後續的更多操作。 那麼第一個問題,什麼是rdd。我們知道,大資料一般儲存在分散式叢集裡面,那麼你在對其進行處理的時候總得把它讀出來吧,讀出來後總得把它存成某種格式的檔案吧,就好比程式語言裡面的,這個資料是陣列,那麼你可以以陣列
零基礎入門大資料探勘之reduce方法
上節介紹過大資料裡面(以spark為例)最為基礎典型的操作:map方法,map方法直白的理解就是一個分散式接受處理函式的方法,形式如map(fun),map方法本身不做處理,沒有map方法,裡面的函式fun就是一個單機的處理函式,有了map,相當於就把這個函式複製到多臺機器上,每臺機器同
資料倉庫與資料探勘之Apriori演算法例項
最近剛上了資料探勘這門課,老師講了兩個演算法,即Apriori演算法和FP-growth演算法,然後佈置了上機作業,挖掘一個有8萬行的記錄的retail.dat,需要從中找出強規則,即同時滿足最小支援度和最小置信度的規則。 Apriori演算法 在這裡給出一個實現找出所有頻繁模式集的
資料探勘之Apriori演算法
python3程式碼如下: #coding = utf-8 import numpy #from python_util import fileread """ 程式所需部分: 建立初始的候選集 根據Lk產生Lk+1