Skip to content

Commit

Permalink
tree
Browse files Browse the repository at this point in the history
  • Loading branch information
jpn-- committed Feb 11, 2022
1 parent 0705dbd commit cc1e3fa
Show file tree
Hide file tree
Showing 11 changed files with 472 additions and 48 deletions.
3 changes: 2 additions & 1 deletion book/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ parts:
- file: api/dataset
- file: api/datatree
- file: api/dataframes
- file: api/linear
- file: api/~models
sections:
- file: api/model
- file: api/linear
- file: api/nesting

- caption: Examples
chapters:
Expand Down
23 changes: 23 additions & 0 deletions book/api/nesting.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
===========
NestingTree
===========

.. currentmodule:: larch.model.tree


.. autosummary::
:toctree: generated/

NestingTree

Methods
=======

.. autosummary::
:toctree: generated/

NestingTree.new_node
NestingTree.add_node
NestingTree.remove_node
NestingTree.add_edge
NestingTree.remove_edge
60 changes: 48 additions & 12 deletions book/example/001_mnl.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,7 @@
{
"cell_type": "markdown",
"id": "f58c8dfd",
"metadata": {
"ExecuteTime": {
"end_time": "2021-11-26T20:04:55.484918Z",
"start_time": "2021-11-26T20:04:55.481729Z"
}
},
"metadata": {},
"source": [
"This example is a mode choice model built using the MTC example dataset.\n",
"First we create the Dataset and Model objects:"
Expand Down Expand Up @@ -166,13 +161,55 @@
},
{
"cell_type": "markdown",
"id": "414b6db9",
"id": "1023ba6d",
"metadata": {},
"source": [
"We can view a summary of the choices and alternative \n",
"availabilities to make sure the model is set up \n",
"correctly."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a1ae2a3a",
"metadata": {},
"outputs": [],
"source": [
"m.choice_avail_summary()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "12391385",
"metadata": {
"ExecuteTime": {
"end_time": "2021-11-26T20:10:59.990767Z",
"start_time": "2021-11-26T20:10:59.987376Z"
}
"tags": [
"remove_cell"
]
},
"outputs": [],
"source": [
"# TEST\n",
"s = ''' name chosen available\n",
"altid \n",
"1 DA 3637 4755\n",
"2 SR2 517 5029\n",
"3 SR3+ 161 5029\n",
"4 Transit 498 4003\n",
"5 Bike 50 1738\n",
"6 Walk 166 1479\n",
"< Total All Alternatives > 5029 \n",
"'''\n",
"import re\n",
"mash = lambda x: re.sub('\\s+', ' ', x).strip()\n",
"assert mash(s) == mash(str(m.choice_avail_summary()))"
]
},
{
"cell_type": "markdown",
"id": "414b6db9",
"metadata": {},
"source": [
"Having created this model, we can then estimate it:"
]
Expand Down Expand Up @@ -374,7 +411,6 @@
}
],
"metadata": {
"celltoolbar": "Tags",
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
Expand Down
18 changes: 9 additions & 9 deletions book/example/201_exville_mode_choice.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -355,15 +355,15 @@
"assert (summary.to_markdown()) == '''\n",
"| | name | chosen | available | availability condition |\n",
"|:---------------------------|:---------|---------:|:------------|:-------------------------|\n",
"| 1 | DA | 810 | 7564 | AGE >= 16 |\n",
"| 2 | SR | 196 | 4179 | 1 |\n",
"| 3 | Walk | 72 | 7564 | WALK_TIME < 60 |\n",
"| 4 | Bike | 434 | 4199 | BIKE_TIME < 60 |\n",
"| 5 | Transit | 6862 | 7564 | TRANSIT_FARE>0 |\n",
"| 6 | Car | 268 | 7564 | |\n",
"| 7 | NonMotor | 7296 | 7564 | |\n",
"| 8 | Motor | 7564 | 7564 | |\n",
"| < Total All Alternatives > | | 6052 | | |\n",
"| 1 | DA | 6052 | 7564 | AGE >= 16 |\n",
"| 2 | SR | 810 | 7564 | 1 |\n",
"| 3 | Walk | 196 | 4179 | WALK_TIME < 60 |\n",
"| 4 | Bike | 72 | 7564 | BIKE_TIME < 60 |\n",
"| 5 | Transit | 434 | 4199 | TRANSIT_FARE>0 |\n",
"| 6 | Car | 6862 | 7564 | |\n",
"| 7 | NonMotor | 268 | 7564 | |\n",
"| 8 | Motor | 7296 | 7564 | |\n",
"| < Total All Alternatives > | | 7564 | | |\n",
"'''[1:-1]"
]
},
Expand Down
6 changes: 1 addition & 5 deletions book/example/202_exville_mc_logsums.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@
},
"outputs": [],
"source": [
"\n",
"Mode = Dict(\n",
" DA = 1,\n",
" SR = 2,\n",
Expand Down Expand Up @@ -197,15 +196,12 @@
"outputs": [],
"source": [
"for i,dtaz in enumerate(logsums.TAZ_ID):\n",
" \n",
" m.datatree = dt.replace_datasets(\n",
" tour=dt.root_dataset.assign(\n",
" DTAZ=xr.full_like(dt['DTAZ'], dtaz)\n",
" ),\n",
" )\n",
" logsums.loc[dict(TAZ_ID=dtaz)] = m.logsums()\n",
"\n",
" "
" logsums.loc[dict(TAZ_ID=dtaz)] = m.logsums()"
]
},
{
Expand Down
176 changes: 173 additions & 3 deletions book/user-guide/choice-models.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -483,8 +483,9 @@
"\n",
"[`m.datatree`](larch.numba.Model.datatree) \n",
": A `DataTree` that holds the raw data used for the model. This can\n",
"consist of just a single `Dataset`, or multiple related datasets \n",
"linked together using the `sharrow` library.\n",
"consist of just a single `Dataset`, (which is automatically converted\n",
"into a one-node tree when you assign it to this attribute) or multiple \n",
"related datasets linked together using the `sharrow` library. \n",
"\n",
"[`m.dataset`](larch.numba.Model.dataset) \n",
": The assembled arrays actually used in calculation, stored\n",
Expand Down Expand Up @@ -519,6 +520,170 @@
"m.dataset"
]
},
{
"cell_type": "markdown",
"id": "8568735b",
"metadata": {},
"source": [
"## Nesting Structures\n",
"\n",
"By default, a model in Larch is assumed to be a simple multinomial \n",
"logit model, unless a nesting structure is defined. That structure\n",
"is defined in a model's [`graph`](larch.numba.Model.graph)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "25ec7446",
"metadata": {},
"outputs": [],
"source": [
"m.graph"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ad6b2350",
"metadata": {
"tags": [
"remove_cell"
]
},
"outputs": [],
"source": [
"# TEST\n",
"assert sorted(m.graph.nodes) == [0, 1, 2, 3]\n",
"assert sorted(m.graph.edges) == [(0, 1), (0, 2), (0, 3)]\n",
"assert m.graph.standard_sort_names == ['Car', 'Bus', 'Walk', '_root_']\n",
"assert m.graph.standard_sort == (1, 2, 3, 0)"
]
},
{
"cell_type": "markdown",
"id": "0ce31f75",
"metadata": {},
"source": [
"Adding a nest can be accomplished the the [`new_node`](larch.model.tree.NestingTree.new_node) method,\n",
"which allows you to give a nesting node's child codes, a name, and attach a logsum parameter."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "836fc0d3",
"metadata": {},
"outputs": [],
"source": [
"z = m.graph.new_node(parameter='Mu_Motorized', children=[1,2], name='Motorized')\n",
"m.graph"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1bf7f1b2",
"metadata": {
"tags": [
"remove_cell"
]
},
"outputs": [],
"source": [
"# TEST\n",
"assert sorted(m.graph.nodes) == [0, 1, 2, 3, 4]\n",
"assert sorted(m.graph.edges) == [(0, 3), (0, 4), (4, 1), (4, 2)]\n",
"assert m.graph.standard_sort_names == ['Car', 'Bus', 'Walk', 'Motorized', '_root_']\n",
"assert m.graph.standard_sort == (1, 2, 3, 4, 0)"
]
},
{
"cell_type": "markdown",
"id": "f94b23ad",
"metadata": {},
"source": [
"The return value of [`new_node`](larch.model.tree.NestingTree.new_node)\n",
"is the code number of the new nest. This is assigned automatically so \n",
"as to not overlap with any other alternatives or nests. We can use this\n",
"to develop multi-level nesting structures, by putting that new code \n",
"number as the child for yet another new nest."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "637439d3",
"metadata": {},
"outputs": [],
"source": [
"m.graph.new_node(parameter='Mu_Omni', children=[z, 3], name='Omni')\n",
"m.graph"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "90a41d3c",
"metadata": {
"tags": [
"remove_cell"
]
},
"outputs": [],
"source": [
"# TEST\n",
"assert sorted(m.graph.nodes) == [0, 1, 2, 3, 4, 5]\n",
"assert sorted(m.graph.edges) == [(0, 5), (4, 1), (4, 2), (5, 3), (5, 4)]\n",
"assert m.graph.standard_sort_names == [\n",
" 'Car', 'Bus', 'Walk', 'Motorized', 'Omni', '_root_'\n",
"]\n",
"assert m.graph.standard_sort == (1, 2, 3, 4, 5, 0)"
]
},
{
"cell_type": "markdown",
"id": "9824be61",
"metadata": {},
"source": [
"Nothing in Larch prevents you from overloading the nesting structure with\n",
"degenerate nests, as shown above. You may have difficult with estimating\n",
"parameters if you are not careful with such complex structures. If you\n",
"need to [`remove_node`](larch.model.tree.NestingTree.remove_node), you \n",
"can do so by giving its code--but you'll likely find you'll be much better off\n",
"just fixing your code and starting over, as node removal can have some odd\n",
"side effects for complex structures."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "435b99b3",
"metadata": {},
"outputs": [],
"source": [
"m.graph.remove_node(5)\n",
"m.graph"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ac114d76",
"metadata": {
"tags": [
"remove_cell"
]
},
"outputs": [],
"source": [
"# TEST\n",
"assert sorted(m.graph.nodes) == [0, 1, 2, 3, 4]\n",
"assert sorted(m.graph.edges) == [(0, 3), (0, 4), (4, 1), (4, 2)]\n",
"assert m.graph.standard_sort_names == ['Car', 'Bus', 'Walk', 'Motorized', '_root_']\n",
"assert m.graph.standard_sort == (1, 2, 3, 4, 0)"
]
},
{
"cell_type": "markdown",
"id": "1910c935",
Expand Down Expand Up @@ -737,7 +902,12 @@
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {},
"toc_position": {
"height": "calc(100% - 180px)",
"left": "10px",
"top": "150px",
"width": "299.2px"
},
"toc_section_display": true,
"toc_window_display": true
}
Expand Down
1 change: 0 additions & 1 deletion book/user-guide/machine-learning.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"(machine-learning)=\n",
"# Machine Learning"
]
},
Expand Down
Loading

0 comments on commit cc1e3fa

Please sign in to comment.