Pickle Не сохраняет экземпляр объекта - PullRequest
0 голосов
/ 06 июля 2018

У меня есть пользовательская модельlaborative.py, и она содержит следующий код

import numpy as np 
import pandas as pd 
import pickle

class LatentCollaborativeFiltering():

    def __init__(self, numberOfRecommendations, stepSize, lamda, gamma, K):
        self.ratings_data = pd.read_csv('../data/ratings.csv')
        self.movies_data = pd.read_csv('../data/movies.csv')
        self.numberOfRecommendations = numberOfRecommendations
        self.steps = stepSize
        self.lamda = lamda 
        self.gamma = gamma 
        self.K = K
        self.R = self.read_data()
        self.N = len(self.R.index)
        self.M = len(self.R.columns)
        self.P = pd.DataFrame(np.random.rand(self.N, self.K), index = self.R.index)
        self.Q = pd.DataFrame(np.random.rand(self.M, self.K), index = self.R.columns)
        print("Csv file read successful and R matrix formed")
        self.MatrixFactorization() 

    def read_data(self):
        data = pd.merge(self.ratings_data, self.movies_data, left_on="movieId", right_on="movieId")
        data=pd.DataFrame.sort_values(data,['userId','movieId'],ascending=[0,1])
        R = pd.pivot_table(data, values='rating', index=['userId'], columns = ['movieId'])
        print("User Item Rating Matrix Returned")
        return R

    def MatrixFactorization(self):
        self.R = self.R.iloc[:10, :10]
        for step in range(self.steps):
            for i in self.R.index:
                for j in self.R.columns:
                    if self.R.loc[i,j]>0:
                        # For each rating that exists in the training set 
                        eij=self.R.loc[i,j]-np.dot(self.P.loc[i],self.Q.loc[j])
                        self.P.loc[i]=self.P.loc[i]+self.gamma*(eij*self.Q.loc[j]-self.lamda*self.P.loc[i])
                        self.Q.loc[j]=self.Q.loc[j]+self.gamma*(eij*self.P.loc[i]-self.lamda*self.Q.loc[j])
            e=0
            for i in self.R.index:
                for j in self.R.columns:
                    if self.R.loc[i,j]>0:
                        #Sum of squares of the errors in the rating
                        e= e + pow(self.R.loc[i,j]-np.dot(self.P.loc[i],self.Q.loc[j]),2)+self.lamda*(pow(np.linalg.norm(self.P.loc[i]),2)+pow(np.linalg.norm(self.Q.loc[j]),2))
                        print("Error", e)
            if e<0.001:
                print(e)
                break
            print(step)
        return self.P,self.Q


    def predict(self, activeUser):
        self.predictItemRating=pd.DataFrame(np.dot(self.P.loc[activeUser],self.Q.T),index=self.Q.index,columns=['Rating'])
        self.topRecommendations=pd.DataFrame.sort_values(self.predictItemRating,['Rating'],ascending=[0])[:3]
        self.topRecommendationTitles=self.movies_data.loc[self.movies_data.movieId.isin(self.topRecommendations.index)]
        return list(self.topRecommendationTitles.title)

myobj = LatentCollaborativeFiltering(numberOfRecommendations=10, stepSize=100, lamda=0.02, gamma=0.001, K=2)
#result = myobj.predict(5)
#print(result)

with open('colla.pkl', 'wb') as outfile:
    my_model = pickle.dump(myobj, outfile, pickle.HIGHEST_PROTOCOL)

Я создал объект myobj класса и выгрузил объект как файл pickle. Но когда я загружаю файл pickle, объект не загружается из предыдущего состояния и снова выполняет все вычисления. Я хочу выполнить вычисление только один раз, когда объект инициализируется, а не снова и снова вызывать функцию предиката внутри класса. Любые предложения будут действительно полезны. Мой скрипт для загрузки маринованного объекта:

import pickle 
from collaborative import LatentCollaborativeFiltering

with open('colla.pkl', 'rb') as infile:
    myObj = pickle.load(infile)

print(myObj.predict(5))

Здесь при запуске этого скрипта снова происходит весь процесс факторизации матрицы.

...