当前位置: 代码迷 >> 综合 >> 【线性代数】python 实现数据降维推荐系统(附Python源码)
  详细解决方案

【线性代数】python 实现数据降维推荐系统(附Python源码)

热度:22   发布时间:2023-11-25 05:15:13.0

众所周知,PCA 的主要目的是降维,同时也可以起到分类的作用。当数据维度很大的时候,如果相信大部分变量之间存在线性关系,那么我们就希望降低维数,用较少的变量来抓住大部分的信息。(一般来讲做PCA 之前要做normalization 使得变量中心为0,而且方差为1.)比较广泛应用于图像识别,文档处理,推荐系统等。

 

PAC原理:https://blog.csdn.net/HHTNAN/article/details/78471645

#如果一个旅游网站里面有100000个注册用户,以及100个注册酒店,网站有用户通过本网站点击酒店页面的
#记录数据信息A=Aij   100000*100  Aij表示第i个用户点击j酒店的次数
#Q1:如何评价酒店之间的相似度
#Q2:给定一个酒店,请找出与它最相似的其他几个酒店
#Q3:如何要给酒店分类,有什么办法?

import pandas as pd
import numpy as np
#prepare data set, suppose there are 5 types of hotels
generatorNum=5
hotelNum=100
customerNum=100000
#10000用户个对五个纬度的侧重点的评分
generators = np.random.randint(5, size=(customerNum, generatorNum))
print(generators)

#酒店在各个纬度为评分
hotelComp=np.random.random(size=(generatorNum, hotelNum)) - 0.5 # 0.5出现负值
print(hotelComp)

构造的模拟数据 

 

#.dot矩阵运算,生成顾客对酒店评分
hotelRating = pd.DataFrame(generators.dot(hotelComp),index=['c%.6d'%i for i in range(100000)],columns = ['hotel_%.3d'%j for j in range(100)]).astype(int)
#data z-score公式
def normalize(s):if s.std()>1e-6:#**乘方,就散标准分数z-score,用来算离数据中心的偏差的,https://www.zhihu.com/question/21600637return (s-s.mean())*s.std()**(-1)else:return (s-s.mean())

 

#如何评价酒店之间的相似度?
#data to z-score
hotelRating_norm = hotelRating.apply(normalize)
print('hotelRating_norm\n{}'.format(hotelRating_norm))

 

#计算协方差
hotelRating_norm_corr = hotelRating_norm.cov()

 

#SVD,即奇异值分解
u,s,v = np.linalg.svd(hotelRating_norm_corr)
#碎石图确定分类,测试时是5
import matplotlib.pyplot as plt
plt.plot(s,'o')
plt.title("singular value spectrum")
plt.show()

奇异值谱 

 

#截取SVD纬度
u_short = u[:,:5]
v_short = v[:5,:]
s_short = s[:5]print('u,s,v,short{}'.format(u_short,v_short,s_short))

 

#numpy.diag()创建一个对角矩阵
hotelRating_norm_corr_rebuild = pd.DataFrame(u_short.dot(np.diag(s_short).dot(v_short)),index=hotelRating_norm_corr.index,columns=hotelRating_norm_corr.keys())
#get the top components ,np.power数组的元素分别求n次方
top_components = hotelRating_norm.dot(u_short).dot(np.diag(np.power(s_short,-0.5)))
#classfication of each hotel
hotel_ind = 30
rating = hotelRating_norm.loc[:,'hotel_%.3d'%hotel_ind]
print ("classification of the %dth hotel"%hotel_ind,top_components.T.dot(rating)/customerNum)