1. 程式人生 > >轉載:資料探勘之_SVD的python實現和分析

轉載:資料探勘之_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