机器学习之路(五)协同过滤及SVD算法

     基本概念:

     协同过滤(Collabortive Filtering),通过用户和产品以及用户的偏好信息产生推荐产品的策略。基本的有两种:一是找到相同喜好的人所钟爱的产品,即基于用户的推荐。另一种是根据一个人喜欢的产品推荐类似的产品,即基于产品的推荐。利用用户以及物品的信息来预测用户的喜好,并且发觉用户可能会喜欢的类似产品或者是喜欢产品的相关产品,这就是推荐系统的核心思想。

    模型及算法:

  •     数据预处理与UI矩阵  
  •     推荐模型:UserCF 和ItemCF
  •     KMeans计算相关性
  •     SVD计算相似性

1. 数据预处理

      在收集完数据,数据预处理是极其必要的,最常用的方法就是减噪和归一化,减噪是通过过滤算法去除数据中存在的噪声,一般是聚类过程中产生的离散点。归一化是平衡不同特征数据的差异,比如体重和年龄之间数值差异较大,为了统一量化,使不同的特征数据都集中在相同的取值范围内,使得模型训练更加准确。

      聚类时常用的算法是KMeans,这是一种典型的基于距离的排他的划分方法。对于给定的训练集,可以对数据集进行k维划分,每一个划分就是一簇,也就是一个类别。同时还要满足,每个组至少包含一个对象,每个对象必须且仅属于一个组。

      UI(User Item)用户偏好矩阵

      使用sklearn的KMeans聚类算法:

      

import numpy as np
from Recommond_Lib import *
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

k = 4
dataMat = loadSet("testData/trainSet.txt")
#dataMat要转换为矩阵形式
kmeans = KMeans(init='k-means++',n_clusters=4)
kmeans.fit(dataMat)
#绘制图形
drawScatter(dataMat,size=20,color='b',mrkr='.')
drawScatter(kmeans,cluster_centers_,size=60,color='red',mrkr='D')
plt.show()

 具体参数介绍:

n_clusters:缺省值8 【生成的聚类数,即产生的质心(centroids)数。】 
max_iter:缺省值300 
执行一次k-means算法所进行的最大迭代数。 
n_init:缺省值10 
用不同的质心初始化值运行算法的次数,最终解是在inertia意义下选出的最优结果。 
init:有三个可选值:’k-means++’, ‘random’,或者传递一个ndarray向量。 
此参数指定初始化方法,默认值为 ‘k-means++’。 
(1)‘k-means++’ 用一种特殊的方法选定初始质心从而能加速迭代过程的收敛(即上文中的k-means++介绍) 
(2)‘random’ 随机从训练数据中选取初始质心。 
(3)如果传递的是一个ndarray,则应该形如 (n_clusters, n_features) 并给出初始质心。 
precompute_distances:三个可选值,‘auto’,True 或者 False。 
预计算距离,计算速度更快但占用更多内存。 
(1)‘auto’:如果 样本数乘以聚类数大于 12million 的话则不预计算距离。This corresponds to about 100MB overhead per job using double precision. 
(2)True:总是预先计算距离。 
(3)False:永远不预先计算距离。 
tol:float形,默认值= 1e-4 与inertia结合来确定收敛条件。 
n_jobs:指定计算所用的进程数。内部原理是同时进行n_init指定次数的计算。 
(1)若值为 -1,则用所有的CPU进行运算。若值为1,则不进行并行运算,这样的话方便调试。 
(2)若值小于-1,则用到的CPU数为(n_cpus + 1 + n_jobs)。因此如果 n_jobs值为-2,则用到的CPU数为总CPU数减1。 
random_state:整形或 numpy.RandomState 类型,可选 
用于初始化质心的生成器(generator)。如果值为一个整数,则确定一个seed。此参数默认值为numpy的随机数生成器。 
copy_x:默认值=True 
当我们precomputing distances时,将数据中心化会得到更准确的结果。如果把此参数值设为True,则原始数据不会被改变。如果是False,则会直接在原始数据 
上做修改并在函数返回值时将其还原。但是在计算过程中由于有对数据均值的加减运算,所以数据返回后,原始数据和计算前可能会有细小差别。

2.推荐模型

     User CF

     基于用户的CF的思想:基于用户对产品的偏好划分用户类型,一般是聚类算法,将一个用户对所有物品的偏好作为向量来计算用户之间的相似度。然后找到最邻近用户,可以使用KNN算法。根据邻居的相似度权重以及对物品的喜好,预测当前用户可能喜欢的但是未购买的物品。并将其推荐给当前用户。

    Itme CF

    基于物品的协同过滤算法是购物网站应用最多的算法。类似与基于用户的CF,不同的是在计算时采用物品之间的相似度。就是将所有用户对某个物品的偏好作为向量来计算相似度,得到相似物品后,根据当前用户的喜好预测还未有喜好的物品。

   相似度计算

   在计算User CF或者Item CF的相似性时,存在一些问题:

   1)物品的分类是人为指定的,不同的分类标准对于不同的用户来说有较大的差异性

   2)物品的相似度是消费行为的问题,需要针对不同的用户确定不同的权重

   3)即使权重和分类都能确定,也不能完全肯定用户对某种产品感兴趣

   综上所述,需要一种针对酶类用户的不同消费行为来计算不同物品相似度的算法。相比于传统的相似性计算方法,SVD推荐算法优点在于通过训练集对用户以及物品建模,反映了用户与物品的综合指标,提高了预测的准确率。

3.SVD的原理与介绍

  如果我们有一个方阵,可以通过特征值和特征向量求解矩阵特征

  A=Q\Sigma Q^{-1}

其中Q是n*n维矩阵,而ΣΣ为这n个特征值为主对角线的n*n维矩阵。一般我们会把Q的这nn个特征向量标准化,即满足||wi||^2=1, 此时Q的nn个特征向量为标准正交基,满足Q^TQ=,即Q^T=Q^−1 也就是说Q为酉矩阵。

这样我们的特征分解表达式可以写成

A=Q\Sigma Q^{T}

但是在实际情况中,方阵出现的情况特别少,大多数都不是方阵,当出现这种情况时,又该怎么获得矩阵的重要特征呢。这时就用到了矩阵的奇异值分解,可以用于任意矩阵的分解。

A_{m*n}=U_{m*m}\Sigma _{m*n} V^{T}_{n*n}

其中A为m*n的方阵,U和V^T是n*n的方阵,分别称为左奇异向量和右奇异向量。\Sigma是n*m的矩阵,特点是除了对角线之外的元素都是0,对角线上的元素称为奇异值。U和V都是酉矩阵,即满足U^TU=I,V^TV=I

 下面解释一下奇异值和特征值之间的对应关系:

 1.将矩阵A转置A^T,将会得到一个方阵AA^T,对方阵求特征值可以得到:

AA^{T} v= \lambda v

这里得到的v,就是右奇异向量

2.将矩阵A转置A^T,将会得到一个方阵A^TA,对方阵求特征值可以得到:

A^{T} Au= \lambda u

这里得到的u,就是左奇异值

3.奇异值

A=U\Sigma V^{T} \Rightarrow AV = U\Sigma V^{T}V \Rightarrow AV=U\Sigma \Rightarrow Av = \sigma u

其中\sigma为奇异值,并且减小特别快,前10%甚至1%的奇异值的和就占了全部奇异值之和的99%以上,因此可以用前r个奇异值来近似描述矩阵,PCA的降维思想也来源于此。并且我们还可以看出\sigma^{2} = \lambda,因此奇异值有两种求解方式。

   计算svd

from numpy import *

A =mat([5,5,3,0,5,5],[5,0,4,0,4,4],[0,3,0,5,4,5],[5,4,3,3,5,5])
#numpy的Linalg中svd
U,S,VT=linalg.svd(A)
#手工计算
U = A*A.T
#hu 左奇异值
lamda,hU = linalg.eig(U)
VT=A.T*A
#hv 右奇异值
lamda1,hVT = linalg.eig(VT)
#奇异值
sigma = sqrt(lamda)   

 

你可能感兴趣的:(机器学习)