3

I built my own class to implement an estimation procedure (call it EstimationProcedure). To run the procedure, the user calls method fit. First, this fits a Pooled OLS model using the fit method of the PooledOLS class from the linearmodels package. This returns a PanelResults object which I store in variable model. Second, my fit method estimates, e.g., standard errors, t-statistics, p-values, etc. (using a custom bootstrapping method I wrote) whose results are stored in local variables, e.g., std_errors, tstats, pvalues, etc. My method shall now return a PanelResults object that combines information from the initial estimation and my own estimates (because I want to use linearmodel's capabilities to compare multiple regressions and produce latex output).

To this end, I need to create a new PanelResults object. However, the necessary information is not accessible through attributes of model.

Conceptually, what would I need to do to implement this? Or is there a smarter way to achieve this? I suppose that this is rather a question on OOP which I have no experience with.

The following code illustrates the structure of my class:

from linearmodels.panel import PooledOLS
from linearmodels.panel.results import PanelResults

class EstimationProcedure:
    def __init__(self, data):
        self.data = data
    
    def fit(self):
        # estimate Pooled OLS
        model = PooledOLS(self.data)

        # construct my own results using a bootstrap procedure
        # this requires the result from an initial PooledOLS estimation
        std_errors, tstats, pvalues = self.bootstrap(self.data)
            
        # to create and return a new PanelResults object, I need 
        # to pass a number of results, say `res`, from the initial
        # pooled OLS estimation along with my own results to the
        # constructor. However, `PooledOLS` prepares 
        # estimation results required by `PanelResults`'s
        # constructor internally without making them accessible
        # through attributes. Hence, I cannot "recreate" it.
        res = dict()
        return PanelResults(res)

# data is stored in some dataframe
df = pd.DataFrame()

# usage of my estimation procedure
model = EstimationProcedure(df)
model.fit()
Jhonny
  • 568
  • 1
  • 9
  • 26

2 Answers2

1

You can create a subclass of PanelResults named CustomPanelResults (line 1) and override its constructor to take in your custom results (line 2). Then call the constructor of the parent class with the results from the PooledOLS estimation (line 3) along with your custom results (line 4) to create a new PanelResults object that includes both sets of results.

class CustomPanelResults(PanelResults):              # line 1
    def __init__(self, model, custom_results):       # line 2
        super().__init__(model)                      # line 3
        self.custom_results = custom_results         # line 4

Then modify the fit method of your EstimationProcedure class to create an instance of this subclass and pass in the necessary arguments to its constructor:

def fit(self):
    model = PooledOLS(self.data)
    std_errors, tstats, pvalues = self.bootstrap(self.data)
    res = {'std_errors': std_errors, 'tstats': tstats, 'pvalues': pvalues}
    return CustomPanelResults(model, res)
tmc
  • 389
  • 2
  • 6
0

Not very clean solution, but sometimes its impossible to do otherwise.

  1. Create child class of PooledOLS
class CustomPooledOLS(PooledOLS):
  1. Find where is method (or methods) that computes what you need. I assume PooledOLS calculates something you need and disregards it afterwards.
  2. Overwrite method(s) that compute(s) things you need and change it so it saves what you need in some parameter
def nameOfTheFunction(all, of, the, function, arguments):
    # - here copy all of the original function code
    # - modify it so that it saves in the object what is needed, e.g.
    this.tstats_cache = temp_tstats 
    # later you can use those in EsimationProcedure to feed to PanelResults

I had difficulty understanding all your needs, but hopefully this helps you

dankal444
  • 3,172
  • 1
  • 23
  • 35
  • Thanks. Unfortunately, I don't see how that will expose all results computed within PooledOLS to construct the PanelResults object. – Jhonny Feb 15 '23 at 07:08