mattjj / pyhsmm

MIT License
545 stars 172 forks source link

UniformInitialState’ object has no attribute ‘copy_sample’ #75

Closed theideasmith closed 7 years ago

theideasmith commented 7 years ago

Hi Matt,

I'm using pyhsmm to model the behavior of C Elegans.

I was hoping you'd be able to comment on why, when I try to copy a m.ARWeakLimitStickyHDPHMM I get the error UniformInitialState’ object has no attribute ‘copy_sample’?

If it helps, I am using Scott's method:

def get_empirical_ar_params(train_datas, params):
    """
    Estimate the parameters of an AR observation model
    by fitting a single AR model to the entire dataset.
    """
    assert isinstance(train_datas, list) and len(train_datas) > 0
    datadimension = train_datas[0].shape[1]
    assert params["nu_0"] > datadimension + 1

    # Initialize the observation parameters
    obs_params = dict(nu_0=params["nu_0"],
                      S_0=params['S_0'],
                      M_0=params['M_0'],
                      K_0=params['K_0'],
                      affine=params['affine'])

    # Fit an AR model to the entire dataset
    obs_distn = d.AutoRegression(**obs_params)
    obs_distn.max_likelihood(train_datas)

    # Use the inferred noise covariance as the prior mean
    # E_{IW}[S] = S_0 / (nu_0 - datadimension - 1)
    obs_params["S_0"] = obs_distn.sigma * (params["nu_0"] - datadimension - 1)
    obs_params["M_0"] = obs_distn.A.copy()

    return obs_params

and generating a model using

def genmodel_empirical_estimator(kappa):

    Nmax = 10
    affine = False
    nlags = 3
    D_obs = 3

    prior_ar_params = \
        dict(nu_0=D_obs+2,
             S_0=np.eye(D_obs),
             M_0=np.hstack((np.eye(D_obs), np.zeros((D_obs, D_obs*(nlags-1)+affine)))),
             K_0=np.eye(D_obs*nlags+affine),
             affine=affine)

    prior_ar_params = get_empirical_ar_params([reduced.T], prior_ar_params)

    model = m.ARWeakLimitStickyHDPHMM(
            alpha=4.,
            kappa=kappa,
            gamma=4,
            init_state_distn='uniform',
            obs_distns=[
                d.AutoRegression(**prior_ar_params)
                for state in range(Nmax)],
            )

    # In[5]:

    # data takes T * K
    model.add_data(reduced.T)
    return model

Finally

model = genmodel_empirical_estimator(10**6)
mattjj commented 7 years ago

Hey, sorry for the long delay. You've likely figured this out yourself, but I wasn't able to reproduce the error. I ran this file using the current master branches of pyhsmm (fb19602), pybasicbayes (f2d3d92), and autoregressive (be4791c).

In the future, it will probably be easier to work together on debugging things if you provide a complete runnable script (either inline or in a gist) and the commits of the relevant projects you're using (which you can check with git rev-parse --short HEAD).

By the way, reduced isn't in the argument list to genmodel_empirical_estimator, so your code is likely reading a module-level variable there. It might be preferable to pass that in as an explicit argument to the function.

mattjj commented 7 years ago

Ah, maybe you meant to add a model.copy_sample() at the end. In that case, the answer is just that copy_sample isn't implemented for the UniformInitialState class, which is the default that gets instantiated when no other initial state distribution is specified in the call to the model init method.

I just pushed an attempt at a fix. However, I'm not super familiar with this code anymore, and there was a funny circular dependence between the model and the initial state instance, so maybe double-check this code.