donlnz / nonconformist

Python implementation of the conformal prediction framework.
MIT License
425 stars 94 forks source link

Problem working with myregressoradaptor #12

Open behnamprime opened 6 years ago

behnamprime commented 6 years ago

Hello there, Thank you for the library and I'm enjoying using it. I have a problem using myregressoradaptor with a simple linear regressor that is not sklearn. let's say I have a very simple linear regressor from np. import numpy as np class lin_reg: def init(self): self.x=0 self.y=0 self.m=0 self.c=0 self.predictions=0 self.x_test=0

def fit(self,x,y):
    self.x=np.array(x)
    self.y=np.array(y)
    self.A=np.vstack((self.x, np.ones(len(self.x)))).T
    self.Model=np.linalg.lstsq(self.A, self.y)
    self.m, self.c = self.Model[0]
    print("m,c",self.m,self.c)
    return
def predict(self,x_test):
    self.x_test=x_test
    #print("x_test inside",self.x_test.shape)
    #print(self.x_test)
    self.predictions=np.zeros((x_test.shape[0],1))
    print("pred shape",self.predictions.shape)
    for i in range(len(x_test)):
        #print("i is",i)
        self.predictions[i,:]=(self.m*(x_test[i,:])+self.c)
    print("finished")
    return self.predictions

then I define myregressoradaptor as:

class MyRegressorAdapter(RegressorAdapter): def init(self, model, fit_params=None): super(MyRegressorAdapter, self).init(model, fit_params)

def fit(self, x, y):
    '''
        x is a numpy.array of shape (n_train, n_features)
        y is a numpy.array of shape (n_train)

        Here, do what is necessary to train the underlying model
        using the supplied training data
    '''
    self.model.fit(x, y)
    print("here")
    return

def predict(self, x):
    '''
        Obtain predictions from the underlying model

        Make sure this function returns an output that is compatible with
        the nonconformity function used. For default nonconformity functions,
        output from this function should be predicted real values in a
        numpy.array of shape (n_test)
    '''
    return self.model.predict(x)

and run it by: x = [x for x in range(100)] y = [y+1 for y in x ]

x_cal=np.array([x for x in range(100,200)]) x_cal=np.reshape(x_cal,(len(x_cal),1)) y_cal=np.array([y+1 for y in x_cal]) x_test=np.array([200,201,203]) x_test=x_test.reshape((x_test.shape[0],1)) my_regressor = lin_reg() # Initialize an object of your regressor's type model = MyRegressorAdapter(my_regressor) nc = RegressorNc(model) icp = IcpRegressor(nc) # Create an inductive conformal regressor

# Fit the ICP using the proper training set

icp.fit(x,y)

Calibrate the ICP using the calibration set

icp.calibrate(np.array(x_cal), np.array(y_cal)) test_predictions=icp.predict(x_test,significance=0.05) print(test_predictions)

so the prediction on calibration happens properly, then prediction on test data starts and finishes, and then there is this error:

Traceback (most recent call last): File "/home/behnam/.local/share/JetBrains/Toolbox/apps/PyCharm-C/ch-0/173.2696.9/helpers/pydev/pydevd.py", line 1640, in globals = debugger.run(setup['file'], None, None, is_module) File "/home/behnam/.local/share/JetBrains/Toolbox/apps/PyCharm-C/ch-0/173.2696.9/helpers/pydev/pydevd.py", line 1067, in run pydev_imports.execfile(file, globals, locals) # execute the script File "/home/behnam/.local/share/JetBrains/Toolbox/apps/PyCharm-C/ch-0/173.2696.9/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile exec(compile(contents+"\n", file, 'exec'), glob, loc) File "/home/behnam/repos/conformal/python/dev/nonconformist/1.py", line 217, in test_predictions=icp.predict(x_test,significance=0.05) File "/home/behnam/repos/conformal/python/dev/nonconformist/nonconformist/icp.py", line 400, in predict significance) File "/home/behnam/repos/conformal/python/dev/nonconformist/nonconformist/nc.py", line 503, in predict err_dist = self.err_func.apply_inverse(nc, significance) File "/home/behnam/repos/conformal/python/dev/nonconformist/nonconformist/nc.py", line 165, in apply_inverse return np.vstack([nc[border], nc[border]]) IndexError: index 499 is out of bounds for axis 0 with size 100

donlnz commented 6 years ago

Thanks for showing interest in Nonconformist!

What's happening here is that Nonconformist expects y-values to be supplied as one-dimensional numpy.arrays (i.e., row vectors rather than column vectors) for regression problems. The fix is quite simple: MyRegressorAdapter needs to return its predictions as a one-dimensional numpy.array, and y_cal supplied to IcpRegressor.calibrate() must also be a one-dimensional numpy.array.

I created a gist from your example---the only modifications I've made are on rows 61 and 68: https://gist.github.com/donlnz/aa8791fbb5e05d77a48db8e0e88376a2