T3、利用SVD简化数据以及简单应用

本文探讨了奇异值分解(SVD)在简化数据、去除噪声和提高算法效果方面的应用,特别是在基于协同过滤的推荐系统中。通过具体实例,如餐馆菜肴推荐引擎,展示了如何利用SVD进行数据预处理和推荐预测。此外,还介绍了SVD在图像压缩领域的实用功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、What ?

SVD:奇异值分解(Singular Value Decomposition,SVD),在线性几何中,SVD是实数和复数矩阵的因式分解。在信号处理和统计学应用较多。

(from wiki) 

2、Why ?

简化数据,去除噪声和冗余信息。 

3、SVD原理:参考文献:A Singularly Valuable Decomposition,http://www-users.math.umn.edu/~lerman/math5467/svd.pdf

 ??

4、机器学习实战:利用python实现SVD

奇异值分解:

  • 优点:简化数据,去除噪声,提高算法的结果
  • 缺点:数据的转换可能难以理解
  • 使用数据类型:数值型数据

5、机器学习实战:基于协同过滤推荐引擎

协同过滤方法(collaborative filtering):通过讲用户的和其他用户的数据进行对比来实现推荐的。

  • 相似度计算:

 (1)欧式距离计算:\left | AB \right | = \sqrt{(x_{i} - x_{j})^{2} + (y_{i} - y_{j})^{2}},“相似度 = 1/(1+距离)”

  (2)  皮尔逊相关系数(Pearson correlation):对用户的评级的量级比较敏感,好于欧式距离。可以通过0.5 + 0.5 * corrcoef()可以规划到(0,1)之间

(3)余弦相似度(cosine similarity):cos\theta = \tfrac{A\cdot B}{\left \| A \right \|\left \| B \right \|}\left \| A \right \| \left \| B \right \| 分别表示A、B的2范数,计算工具linalg.norm()

eg1、示例:餐馆菜肴推荐引擎

推荐系统的工作过程:给定一个用户,系统会为此用户返回N个最好的推荐菜肴。为了实现这一点,则需要我们做到:

a,寻找用户没有评级的菜肴,即在用户-物品矩阵中的0值;

b,在用户没有评级的所有物品中,对每个物品预计一个可能的评级分数。

c,对这些物品的评分从高到低进行排序,返回前N个物品

代码如下:

#实现SVD
def loadExData():
    return [[1, 1, 1, 0, 0],
               [2, 2, 2, 0, 0],
               [1, 1, 1, 0, 0],
               [5, 5, 5, 0, 0],
               [1, 1, 0, 2, 2],
               [0, 0, 0, 3, 3],
               [0, 0, 0, 1, 1]]
#相似度计算
#利用欧式距离
def euclidSim(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):
    """
    arg:
        dataMat 数据集
        user 用户编号
        simMeans 相似度计算方法
        item 物品编号
    """
    n = shape(dataMat)[1]
    simTotal = 0.0; ratSimTotal = 0.0
    for j in range(n):
        userRating = dataMat[user, j]
        if userRating == 0: continue
        #寻找两个用户都做了评价的产品
        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 * userRating
        #根据评分计算比例
        ratSimTotal += similarity * userRating
    if simTotal == 0: 
        return 0
    else: 
        return ratSimTotal/simTotal

#推荐实现:recommeng()产生了最高的N个推荐结果
def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=standEst):
    #寻找用户未评价的产品
    unratedItems = nonzero(dataMat[user, :].A == 0)[1]
    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]

#基于SVD的评分估计
def svdEst(dataMat, user, simMeas, item):
    n = shape(dataMat)[1]
    simTotal = 0.0; ratSimTotal = 0.0
    U, Sigma, VT = la.svd(dataMat)
    Sig4 = mat(eye(4) * Sigma[: 4])
    xformedItems = dataMat.T * U[:, : 4] * Sig4.I#这里xformedItems 这个等式不是很理解???

    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 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)
                    
        
def imgCompress(numSV=3, thresh=0.8):
    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(myMat)
    print("****original matrix******")
    printMat(myMat, thresh)
    U, Sigma, VT = la.svd(myMat)
    SigRecon = mat(zeros((numSV, numSV)))
    for k in range(numSV):
        SigRecon[k, k] = Sigma[k]
    reconMat = U[:, :numSV] * SigRecon*VT[: numSV, :]
    print("****reconstructed matrix using %d singular values******" % numSV)
    print(reconMat, thresh)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值