Skip to content

Commit

Permalink
Merge pull request #36 from UDST/fix-runtime-overflow
Browse files Browse the repository at this point in the history
Improve MNL estimation reliability
  • Loading branch information
smmaurer authored Aug 6, 2018
2 parents 809ed5e + e7ec8a1 commit b3cb2b9
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 19 deletions.
6 changes: 6 additions & 0 deletions choicemodels/mnl.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,9 @@ def mnl_probs(data, beta, numalts):
raise Exception("Number of alternatives is zero")
utilities.reshape(numalts, utilities.size() // numalts)

# https://stats.stackexchange.com/questions/304758/softmax-overflow
utilities = utilities.subtract(utilities.max(0))

exponentiated_utility = utilities.exp(inplace=True)
if clamp:
exponentiated_utility.inftoval(1e20)
Expand Down Expand Up @@ -721,6 +724,9 @@ def mnl_estimate(data, chosen, numalts, GPU=False, coeffrange=(-1000, 1000),
bounds=bounds)
logger.debug('finish: scipy optimization for MNL fit')

if bfgs_result[2]['warnflag'] > 0:
logger.warn("mnl did not converge correctly: %s", bfgs_result)

beta = bfgs_result[0]
stderr = mnl_loglik(
beta, data, chosen, numalts, weights, stderr=1, lcgrad=lcgrad)
Expand Down
6 changes: 6 additions & 0 deletions choicemodels/tools/pmat.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ def cumsum(self, axis):
# elif self.typ == 'cuda':
# return PMAT(misc.cumsum(self.mat,axis=axis))

def max(self, axis):
if self.typ == 'numpy':
return PMAT(np.max(self.mat, axis=axis))
elif self.typ == 'cuda':
return PMAT(self.mat.max(axis=axis))

def argmax(self, axis):
if self.typ == 'numpy':
return PMAT(np.argmax(self.mat, axis=axis))
Expand Down
28 changes: 10 additions & 18 deletions notebooks/MNL-prediction-demo-02.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -207,25 +207,17 @@
"Method: Maximum Likelihood Df Model: \n",
"Date: Pseudo R-squ.: \n",
"Time: Pseudo R-bar-squ.: \n",
"AIC: Log-Likelihood: -4,502.369\n",
"AIC: Log-Likelihood: -4,506.216\n",
"BIC: LL-Null: -4,605.170\n",
"===================================================================\n",
" coef std err z P>|z| Conf. Int.\n",
"-------------------------------------------------------------------\n",
"home_density 0.0117 0.002 6.250 \n",
"work_density 0.0123 0.001 15.292 \n",
"school_density 0.0075 0.004 2.087 \n",
"home_density 0.0113 0.002 6.051 \n",
"work_density 0.0119 0.001 14.909 \n",
"school_density 0.0069 0.004 1.916 \n",
"===================================================================\n",
"CPU times: user 546 ms, sys: 102 ms, total: 648 ms\n",
"Wall time: 245 ms\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/maurer/Dropbox/Git-imac/udst/choicemodels/choicemodels/tools/pmat.py:48: RuntimeWarning: overflow encountered in exp\n",
" return PMAT(np.exp(self.mat))\n"
"CPU times: user 96.6 ms, sys: 55.7 ms, total: 152 ms\n",
"Wall time: 145 ms\n"
]
}
],
Expand Down Expand Up @@ -271,9 +263,9 @@
"name": "stdout",
"output_type": "stream",
"text": [
"0 0.011688\n",
"1 0.012314\n",
"2 0.007539\n",
"0 0.011321\n",
"1 0.011928\n",
"2 0.006929\n",
"Name: Coefficient, dtype: float64\n"
]
}
Expand Down Expand Up @@ -766,7 +758,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.0"
"version": "3.6.4"
}
},
"nbformat": 4,
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

setup(
name='choicemodels',
version='0.1.1',
version='0.2.dev1',
description='Tools for discrete choice estimation',
long_description=long_description,
author='UDST',
Expand Down

0 comments on commit b3cb2b9

Please sign in to comment.