Search code examples
pythonsavepickleshap

How to save my class to load in another environment


I conceptually want to do something easy: save a python object that I can access from another (different) program later.

But the problem is that is has a wrapper around it (the f(x) below) that is not being referenced in new environments.

After spending a whole 12 hours, I feel even more confused than when I started. I think "pickle"-ing or "dill" etc... is what I am supposed to do. But I am running up against the pickling problem. But reading online is getting me no where. (btw, i tried shap.save but it is having the same realm of problems and uses pickle anyways).

import shap, pickle

model = ... (some tensorflow function)

def f(X):
    ...
    return model.predict(...).flatten()
explainer = shap.KernelExplainer(f, X.iloc[:50, :])

with open(f"/tmp/{file}.pkl", 'wb') as fil:
    # explainer.save(fil)
    pickle.dump(explainer, fil)

This does not work because it "cannot find attribute 'f'". These look like the most promising articles I could find but I could not implement for my scenario.

http://gael-varoquaux.info/programming/decoration-in-python-done-right-decorating-and-pickling.html

Unable to load files using pickle and multiple modules

https://github.com/slundberg/shap/issues/295

Python: Can't pickle type X, attribute lookup failed

*** please provide suggestions on terminology in the comments for me to improve how I ask question because I do not know how to word my prompt.


Solution

  • Usually, in any of programming language, you don't save the object but instead, you save the attributes of an object into a file. Then you should make a function to read the file and fill the value into your object. You can make your object into an installable package and import the package as an object into your program.

    import pickle
    
    class A(Object):
         def __init__(self, var1, var2):
             self.var1 = var1
             sefl.var2 = var2
         def dump_obj(self, fn):
             
             pickle.dump(self, fn, pickle.HIGHEST_PROTOCOL)
    
    

    in a file that you want to load your object and feed the data into your object

    import pickle
    import file_with_object_A
    
    def load_A(fn):
        with open(fn, 'rb') as file:
            new_a = pickle.load(fn)
            # or alternatively, you can load each attribute into a variable and feed it to your object
            var1, var2 = file.readline(fn)
            my_new_A = A(var1, var2)
    

    Remember to import the file that you detail the function f(X) into your new code file, either in a way of the package or keep this file contains f(X) in the same directory with the current working file.

    You can check out this answer Saving an Object (Data persistence)