what is going on with z_Intercept_trans in HDDMRegressor?

381 views
Skip to first unread message

Sam Mathias

unread,
Mar 31, 2016, 7:57:22 PM3/31/16
to hddm-users
I'm running an HDDMRegressor model with stimulus-coded data. As per the documentation, I placed a link function on v, such that when the stimulus is drawn from one category the sign of v is flipped. This is my function:

def v_link_func(x, d=data):
    stim = (np.asarray(dmatrix('0 + C(s, [[-1], [1]])', {'s': d.answer.ix[x.index]})))
return x * stim

Now let's say I have two conditions in the experiment, for which I expect a difference in bias, so I put a linear model on z like so: z ~ C(condition). According to the documentation, I need to put a logit link function on z as well:

{model: 'z ~ C(condition)', 'link_func': lambda z: 1 / (1 + np.exp(-z))}

Is this the right thing to do? I suspect it isn't, because when I look at my posterior for z_Intercept_trans, all the values are below 0. Thus, the maximum possible value of z in my model is 0.5. What is going on here? Either (a) I'm doing something really dumb, (b) is there some intermediate transformation of z going on in the background that I'm unaware of, or (c) the prior on z_Intercept_trans incorrect. Any help much appreciated!

John Clithero

unread,
Mar 31, 2016, 10:55:39 PM3/31/16
to hddm-...@googlegroups.com
Hi Sam,

I had noticed this, too.

I did the following before plugging it back into the link function and it seemed to give sensible results.

Assume "model_group" is the HDDM model:

traces_z_inv = model_group.get_traces()['z_Intercept_trans'] 
traces_z = mc.invlogit(traces_z_inv)

Then, "traces_z" goes into the link function. Hopefully, this is right?

--
You received this message because you are subscribed to the Google Groups "hddm-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hddm-users+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Sam Mathias

unread,
Apr 1, 2016, 8:01:18 AM4/1/16
to hddm-users
Hi John, thanks for your reply. Unfortunately, that's not correct.

Just to clarify, I actually meant to say **inverse** logit (aka logistic) link function in my previous email. So by your instructions you just apply the inverse logit transformation to z_Intercept_trans twice: inverselogit(inverselogit(0)) = 0.622. After transformation, the maximum value of z should be 1.

Samuel Robert Mathias
Postdoctoral Associate
Department of Psychiatry, Yale School of Medicine
Suite 3014, 2 Church Street South
New Haven, CT 06519
http://www.srmathias.com

John Clithero

unread,
Apr 1, 2016, 11:53:22 AM4/1/16
to hddm-...@googlegroups.com
Hi Sam,

OK, so then perhaps I am confused.
The z is bound between 0 and 1.
Your link function is a logit function. Where is the inverse you are talking about?

If you were NOT using hddm regressor and just letting z be a free parameter, you would do

traces_z_inv = model_group.get_traces()['z_trans'] 
traces_z = mc.invlogit(traces_z_inv)

I then noticed the same problem you are stating in HDDMRegression. Using the above, it seemed to give me sensible (between 0 and 1) results.

How are you proposing to fix it? I think what I was proposing was under category (b) in your original email. Either way, I would like to know the correct answer, too!

John

Sam Mathias

unread,
Apr 1, 2016, 12:16:27 PM4/1/16
to hddm-users
Hi John, no, my link function is not logit, 1 / (1 + np.exp(-z)) is the inverse-logit. This was a typo in my first email.

After some playing around with simulated data I'm convinced now that this is the correct link function. The problem I was having was that, in my model, z_Intercept_trans never exceeded 0, even after ~30000 samples. Looking at the posterior histogram it looked like something weird was going on, like for example the prior was improper, forbidding any values of z_Intercept_trans > 0. This doesn't seem to be the case generally, because when I simulated some data I could get values of z_Intercept_trans > 0.

I'm still not sure what exactly is going on, but I don't think its a bug in HDDM. More likely its my data, or some mistake in my syntax.

Samuel Robert Mathias
Postdoctoral Associate
Department of Psychiatry, Yale School of Medicine
Suite 3014, 2 Church Street South
New Haven, CT 06519
http://www.srmathias.com

John Clithero

unread,
Apr 1, 2016, 7:51:20 PM4/1/16
to hddm-...@googlegroups.com
Hi again Sam,

OK, so yeah we're using the same link function.

Here is what I found again, though, just for posterity.

Example:
Using that link function, I plotted the default posterior plots in HDDM. The "z_Intercept.png" looked to have a mean of 0.02796.

When I loaded in the model, I did the following:

In [4]: traces_z_inv = model_group.get_traces()['z_Intercept_trans'] 

In [5]: np.mean(traces_z_inv)

Out[5]: -3.649643423613024

In [6]: traces_z = mc.invlogit(traces_z_inv)

In [7]: np.mean(traces_z)

Out[7]: 0.02795953473947551

In [8]: 1 / (1+np.exp(-np.mean(traces_z)))

Out[8]: 0.50698942836706296

This seems reasonable to me, no?

Xiaoyu Zeng

unread,
Oct 5, 2023, 11:33:59 PM10/5/23
to hddm-users
Hi John,
I noticed you kindof applied twice inverse logit transformation for the z_intercept, once using pymc.invlogit, and once using manual code.
I was wondering, did these two steps serve similar/identical functions?

As recent versions of HDDM have built-in inverse logit for Z in HDDMregressor, the z_trans were already inverse logit transformed right?
My question is, how should I recover the Z_trans to [0, 1]?

Xiaoyu Zeng

unread,
Oct 13, 2023, 3:07:18 AM10/13/23
to hddm-users
Hi all,
In my experience, applying once inverse logit on the z_Trans should recover the z_Trans to the raw z that ranges from 0 to 1. Please correct me if I'm wrong about this. : )

Best,
Xiaoyu

Alexander Fengler

unread,
Oct 22, 2023, 11:00:07 PM10/22/23
to hddm-users
This should be correct yep. 
You can convince yourself we fitting simulated data (where you know the ground truth). 
However, let me also point you to HSSM the successor toolbox to HDDM, currently in alpha release.
HSSM is more transparent in this regard :).

Best,
Alex 

Xiaoyu Zeng

unread,
Oct 24, 2023, 11:35:31 PM10/24/23
to hddm-users
Hi Alex,
Thanks for the reply. Previous posts mentioned that the latest HDDM has built-in inverse logit link function for Z. But what I'm not sure about is, since which version of HDDM should we **stop** adding the inverse logit link function? HDDM0.8?

Best,
Xiaoyu

Alexander Fengler

unread,
Oct 24, 2023, 11:42:31 PM10/24/23
to hddm-users
Hi Xiaoyu,

This change should be closer to version > 0.9.
I don't think it's in HDDM 0.8 yet.

Best,
Alex
Reply all
Reply to author
Forward
0 new messages