机器学习实战学习笔记4——奇异值分解(SVD)

1.SVD算法概述


1.1 SVD算法介绍


奇异值分解(Singular Value Decomposition)算法,可以将数据映射到低维空间,常用于从有噪声数据中抽取相关特征。

1.2 SVD算法原理


(1)先利用SVD从数据中构建一个主题空间;
(2)然后在该空间下计算相似度;

1.3 SVD算法优缺点


(1)优点:简化数据,去除噪声,提高算法的结果
(2)缺点:数据的转换可能难以理解
(3)应用:最优化问题、特征值问题、最小乘方问题、广义逆矩阵问题、信息检索、图像压缩等。

2.基于协同过滤的推荐引擎


协同过滤是通过将用户和其他用户的数据进行对比来实现推荐。当知道两个用户或两个物品之间的相似度时,就可以利用已有数据预测未知用户的喜好。协同过滤不关心物品的描述属性,而是按照许多用户的观点来计算相似度。
相似度的计算主要有两种方法:基于物品(item-based)的相似度和基于用户(user-based)的相似度。具体选择哪一种,取决于用户或物品的数量。当用户数量远大于物品种类时(如电商网站推荐、电影推荐),更倾向于使用基于物品相似度的计算方法。
常见的相似度计算方法有三种:
(1)欧氏距离计算相似度:
(2)Pearson相关系数计算相似度:
(3)余弦计算相似度:

3.SVD算法实现——餐馆菜肴推荐


现在构建一个推荐引擎,该推荐引擎关注的是餐馆食物的推荐。当一个人外出吃饭时,如果不能确定该到哪儿吃饭,该点什么菜。我们的推荐系统就可以给他提供一个个性化推荐。
构建餐馆菜肴推荐系统时,主要分两个阶段:
第一阶段,先构建一个基本的推荐系统,能够寻找用户没有尝过的菜肴。
第二阶段,通过SVD来减少特征空间并提高推荐的效果。

3.1 推荐未尝过的菜肴


推荐系统的过程流程是:给定一个用户,系统会为此用户返回N个最好的推荐菜。为了实现这一点,我们需要做到:
(1)寻找用户没有评级的菜肴,即用户—物品矩阵中的0值;
(2)在用户没有评级的所有物品中,对每个物品预计一个可能的评级分数。
(3)对这些物品的评分从高到低进行排序,返回前N个物品。
基本推荐系统的代码如下所示:

# -*- coding: utf-8 -*-
"""
Created on Thu Dec 15 11:02:00 2016

@author: Administrator
"""

from numpy import *
from numpy import linalg as la

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]]

#相似度计算

#1.使用欧氏距离计算相似度
def eulidSim(inA,inB):
    return 1.0/(1.0 + la.norm(inA - inB))

#2.使用Pearson相关系数计算相似度
def pearsonSim(inA,inB):
    if len(inA) < 3 :
        return 1.0
    return 0.5 + 0.5 * corrcoef(inA,inB,rowvar = 0)[0][1]

#3.使用余弦相似度计算相似度
def cosineSim(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):
    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])
        #
        simTotal += similarity
        ratSimTotal += similarity * userRating
    if simTotal == 0 : 
        return 0
    else:
        return ratSimTotal / simTotal

#
def recommend(dataMat,user,N=3,simMeas=cosineSim,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]

3.2 利用SVD提高推荐效果


你可能感兴趣的:(python学习笔记,机器学习)