import pandas as pd
import numpy as np
def jaccard(data=None):
'''
构建物品相似度矩阵(杰卡德相似系数)
:param data: 用户物品矩阵,0-1矩阵;行为用户,列为物品
:return: jaccard相似系数矩阵
'''
te = -(data-1) # 将用户物品矩阵的值反转
dot1 = np.dot(data.T, data) # 任意两网址同时被浏览次数
dot2 = np.dot(te.T, data) # 任意两个网址中只有一个被浏览的次数(上三角表示前一个被浏览,下三角表示后一个被浏览)
dot3 = dot2.T+dot2 # 任意两个网址中随意一个被浏览的次数
cor = dot1/(dot1+dot3) # 杰卡德相似系数公式
for i in range(len(cor)): # 将对角线值处理为零
cor[i, i] = 0
return cor
data_train = a1[0:800000]
data_train = data_train.reset_index(drop=True)
data_test = a1[800000:857525].sample(n=5000)
data_test = data_test.reset_index(drop=True)
data_test1 = a1[800000:857525]
data_test1 = data_test1.reset_index(drop=True)
print(data_test)
# data_train.info()
data_train['phone_no'] = data_train['phone_no'].astype('str') # 将用户id转为字符串类型
data_test['phone_no'] = data_test['phone_no'].astype('str') # 将用户id转为字符串类型
data_test1['phone_no'] = data_test1['phone_no'].astype('str')
user_test = data_test['phone_no'].unique().tolist() # 测试集用户ID
data_train['value'] = 2+test["score"][0:800000]+test["score1"][0:800000]
te = pd.pivot_table(data_train,values='value',index='phone_no',
columns='program_title',fill_value=0) # 构建用户物品矩阵
# te
print(data_train['value'].sort_index(ascending=True))
corr = jaccard(te)
corr.shape# 调用自定义函数,计算物品相似度矩阵
corr = pd.DataFrame(corr, index=te.columns, columns=te.columns)
corr
data_train['value'] = 2+test["score"][0:800000]+test["score1"][0:800000]
data_train['value'] = 1
在data_train['value']赋予dataframe和赋值数字,会在jaccard()运算过程中有巨大的差异,前者cpu运行占比较高,内存占用变化明显80w条数据十多二十秒就搞定了,而后者会cpu运行占比低,内存拉高比较慢,速度明显慢。
通过一个个输出测试
问题出在
dot1 = np.dot(data.T, data)
dot2 = np.dot(te.T, data)
问题出在np.dot上,因为慢的赋值是整数,而且快的是非整数浮点类型,所以有可能是数据格式的问题
Numpy 中似乎有针对 浮点数的优化点运算
int和float类型的Numpy数组dot运算效率比较_sunnyyan的博客-CSDN博客
帖子:
在stackoverflow的一个帖子里找到了原因:
“When Numpy is built with an accelerated BLAS like ATLAS, these functions are replaced to make use of the faster implementations. The faster implementations only affect float32, float64, complex64, and complex128 arrays. Furthermore, the BLAS API only includes matrix-matrix, matrix-vector, and vector-vector products. Products of arrays with larger dimensionalities use the built in functions and are not accelerated.“
原来为了实现更快的计算,Numpy采用了一个类似ATLAS的BLAS(Basic Linear Algebra Subprograms, 基础线性代数子程序)。但这些实现只能影响类型为float32, float64, complex64和complex128的数组。另外,BLAS API只包含矩阵和矩阵,矩阵和向量以及向量和向量的乘法。因此,更高维的数组乘法并不能被加速。