├── LICENSE ├── README.md ├── hw1 ├── 388E_ps1_2018.pdf ├── data1.dat ├── data2.dat ├── data3.dat ├── drawsml.dat ├── question1.ipynb ├── question2.ipynb └── question3.ipynb ├── hw1_io ├── data.csv ├── logit.ipynb └── nest_logit.ipynb ├── hw2 ├── 388E_ps2_2018.pdf ├── ps2.dat ├── question1.ipynb ├── question2.ipynb ├── question3.ipynb └── sim3.dat ├── hw2_io ├── BLP.ipynb ├── BLP_counterfactuals.ipynb ├── Problem Set 2 2018.pdf ├── data.csv ├── logit.ipynb ├── nest_logit.ipynb ├── simulations.csv └── xi.csv ├── hw3 ├── Rust.ipynb └── data.asc ├── hw3_io ├── Pakes.ipynb ├── coef.csv └── schedule.csv ├── hw4_io ├── Assignment_Rust.pdf ├── Rust.ipynb ├── bus1234.csv └── bus1234.dat ├── hw5_io ├── ascending_data.dat ├── auctions.ipynb └── fpa.dat └── hw6_io ├── Submission.ipynb ├── chile.dta └── production.R /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Eric Schulman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UTexas Structural Econometrics and Industrial Organization 2 | 3 | The following repositiory has solutions to the problems sets for Industrial Organization (ECO384K) and Structural Econometrics (ECO388E) at the University of Texas written in python written by Eric Schulman. 4 | 5 | Below are the topics covered by the various assignments. Generally, I branched the repository based on the assignments I was working on concurrently. The folders labeled `_io` contain the code relevant to the industrial organization class. 6 | 7 | ## Homework 1 8 | 1. IO HW1 - Demand estimation using Nested Logit, and Logit 9 | 2. Structural HW1 - Integrating out and introductory models 10 | 11 | ## Homework 2 12 | 3. IO HW2 - Demand estimation using Berry Levinsohn Pakes (1995) 13 | 4. Structural HW2 - Discrete choice and state dependence 14 | 15 | ## Homework 3 16 | 5. IO HW3 - Pakes (1986), Value function calculation and backward recursion 17 | 6. Structural HW3 - Rust (1987), Aguirregabiria Mira, and Dynamics 18 | 19 | ## Homework 4 20 | 7. IO HW4 - Hotz Miller and Aguirregabiria Mira 21 | 22 | -------------------------------------------------------------------------------- /hw1/388E_ps1_2018.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ericschulman/struct/260ee95ac8e364bc49d9bb54b484f138759ba904/hw1/388E_ps1_2018.pdf -------------------------------------------------------------------------------- /hw1/data1.dat: -------------------------------------------------------------------------------- 1 | -1.6326641486 -1.6095925319 2 | -1.1235920789 -1.1216696906 3 | 0.2650375896 1.0012193537 4 | -0.3032515150 -0.5888643258 5 | -0.7811132421 -1.6081031142 6 | 0.2968232040 -0.4214778521 7 | -0.2379631943 -0.1228598889 8 | 0.4603915371 -0.1395812451 9 | 0.4788118346 0.2455634350 10 | 1.6111005012 0.9942101432 11 | 2.2165074408 1.5387029339 12 | 1.1935413505 1.1475197781 13 | -0.7385884923 -0.2975402740 14 | 0.7682814123 0.2238373979 15 | 0.8814427279 0.4884782266 16 | -0.4155940328 -0.7369007028 17 | 0.1963034006 0.7117517380 18 | -1.1514231951 -1.3269562048 19 | -0.1577644418 0.3296038348 20 | -0.1028488556 -0.5082285003 21 | 0.8950391171 1.0855286565 22 | 0.5145557540 -0.6841990056 23 | -0.1430277754 -0.5616570449 24 | 2.0444891648 2.3138263821 25 | 0.9626637085 0.2399000630 26 | -0.5688391041 0.2210335892 27 | -0.2206515810 -0.3874779044 28 | 0.3766908860 0.1641491613 29 | 0.2433351008 0.9486579445 30 | 0.1271228749 -0.8241093032 31 | -2.5770542525 -1.8063185455 32 | 1.3217560549 0.5838359383 33 | 1.7920659731 1.8178585362 34 | -0.5680646597 -0.5307524526 35 | -0.5726026537 -0.0117576534 36 | -0.0002461682 0.1128837368 37 | -1.3662788970 -0.6839129385 38 | 0.7951967193 1.1689821329 39 | -0.8375743857 -0.6984724201 40 | -0.3398005002 -0.2490437351 41 | -0.6866374550 -1.1920551436 42 | -0.8274784997 -0.8991632176 43 | -0.3337828082 -1.0615035408 44 | -0.0764036114 0.0991506336 45 | -1.2110712402 -1.3106905195 46 | -0.7751996543 -1.0526309860 47 | -1.5745042736 -0.9343293832 48 | -1.3583349324 -0.9951357271 49 | 2.6036296506 2.1640079786 50 | 0.4824395396 -0.3165361094 51 | -0.6775316293 -0.8338321425 52 | -0.0548726646 -0.3575023270 53 | 2.3149311365 0.8868059990 54 | 0.8895228132 1.3698033143 55 | 1.4867817372 1.3919473193 56 | 1.3249172082 0.8700286245 57 | 0.1003571324 -0.3957437261 58 | -0.7824743189 -0.0175050911 59 | 0.0206397499 0.1176050148 60 | -1.2686438182 -1.5607360134 61 | -0.5785345346 -0.7426971474 62 | 0.1060571025 0.7033604318 63 | -1.6513453447 -0.9035245258 64 | 0.0399262692 0.3861196599 65 | 0.0488436847 0.3706409687 66 | 0.0955083605 0.3270959977 67 | -0.4536707979 -0.0095583332 68 | -1.4491799619 -1.4389115785 69 | 0.2942228608 1.1730358433 70 | -2.8802431961 -2.0453486817 71 | 0.3028708516 -0.7461453830 72 | -0.6393377089 -0.9490179724 73 | -0.0320043824 -0.5133726440 74 | -0.1761255535 -0.3199823990 75 | -0.8227094583 -0.5530229051 76 | -1.0395184168 -1.1955585058 77 | -3.0323482421 -2.2473385494 78 | 1.2024412647 1.1413857783 79 | -0.3353006200 -0.3200021886 80 | -1.9570481741 -1.8704865911 81 | 0.5205814567 0.7281267916 82 | 1.2909969662 1.5532562597 83 | -0.3788793977 0.1185960517 84 | 0.5577236633 0.1980595674 85 | -1.6045417073 -0.3996355315 86 | -1.6588155372 -1.2715099627 87 | -0.8665386633 -0.3673158115 88 | -0.0357910482 -0.1142249313 89 | 0.4579492568 0.0001294883 90 | -0.0279705409 -0.3146770196 91 | 0.3350258159 -0.4957366140 92 | -2.8209898813 -2.5384812758 93 | -3.2442682273 -2.7528646513 94 | 0.8319422934 0.7666463442 95 | 1.2382871350 0.9130600689 96 | -0.0477646825 -0.2202002057 97 | -0.7017106855 -1.4115863390 98 | 0.6450280027 0.4318582402 99 | 0.3931642147 0.0165466273 100 | 1.9553712593 1.4505689470 101 | 0.4676816770 -0.0915657316 102 | 1.5639170262 1.3007791004 103 | 0.4958704260 0.2816197176 104 | 0.0397551150 -0.2328277194 105 | -1.0457578147 -1.3310713939 106 | -0.3593965457 -0.1754208041 107 | -0.7452995732 -0.8666879085 108 | 0.1706786984 0.7542686200 109 | -1.8035848358 -1.1430704658 110 | 0.6263287940 1.2000530657 111 | 1.6257161631 1.5392694309 112 | -0.3061113338 -0.6561611989 113 | -0.2948442363 -0.0899818181 114 | -2.0003039365 -1.4947613477 115 | -1.6864553969 -1.2102022976 116 | -0.0645518456 -0.4680459920 117 | 0.8879094852 0.3336776295 118 | 0.5394377911 1.4364634720 119 | -2.4368187739 -2.2985310846 120 | -0.9521370853 -0.2921324196 121 | -1.5904547714 -1.1526411090 122 | -0.7266013947 -0.0989894361 123 | 0.0906200350 0.5179149470 124 | 2.5760443117 2.9890092264 125 | 0.3412033460 0.5235400822 126 | 0.0540614645 -0.2781491507 127 | -0.2114083990 0.2409328180 128 | 0.8503120540 0.1808731584 129 | -0.8707201401 -0.7551925024 130 | 0.9841926193 -0.6078532086 131 | 1.6086697355 1.5675065352 132 | 0.8212073291 0.0827800760 133 | 1.5672229182 1.2565554062 134 | -1.3207642487 -1.5530777203 135 | 1.3571263938 0.9210634902 136 | -1.1061237905 -1.2644107723 137 | -0.0424954232 0.2163769177 138 | 2.7012822690 2.9203229028 139 | 0.6962513179 0.6212300635 140 | 1.1389447260 0.7793200885 141 | -0.7986059864 -0.2613300151 142 | -2.6461502486 -1.7484835583 143 | -0.8688636676 -1.1243578123 144 | 0.3422044703 0.7341772861 145 | 0.4922474132 0.1396819811 146 | -1.1861969752 -0.9220197494 147 | 0.7734301560 0.6933761073 148 | -0.5892463493 -0.2453451450 149 | -0.4644536488 -1.1176797798 150 | -0.9695748779 -1.3550939615 151 | -0.1004969935 0.0472339322 152 | -1.0512152294 -1.1262075558 153 | -2.7218225088 -2.5539301719 154 | -1.5268778035 -2.1303227712 155 | -0.1990110399 -0.9031927488 156 | -0.8178424798 -0.1515020274 157 | 0.5035323475 -0.0005587059 158 | -0.4304095637 -1.2764046294 159 | 0.5003003504 0.1825366237 160 | -0.8608013617 -0.5494182422 161 | 1.1454181154 0.4006374831 162 | 0.1620708675 -0.2781911120 163 | -1.0536587137 -0.4449143626 164 | 1.0218555784 1.3110661821 165 | -0.9555646124 -0.1580862476 166 | 1.2176421399 0.3917323890 167 | -0.0434073746 -0.0077076739 168 | -0.3141134373 -1.2478748759 169 | 0.0710256241 1.5531364583 170 | -1.4990364476 -1.1585457021 171 | -1.1755859225 -0.8650738630 172 | 0.5666211913 0.5673093899 173 | -0.6719970822 0.1449403537 174 | 1.0773293323 1.6147376651 175 | -1.2009536513 -0.6315342608 176 | 0.0052676988 0.2048605331 177 | 0.5881057638 0.2344514156 178 | 1.0738112896 0.5735302987 179 | -0.8507405846 -0.1181950859 180 | 0.9901773433 0.7614293248 181 | -0.6075760058 -0.5439236591 182 | -0.2179586549 0.3415383814 183 | -0.4914666295 -0.6777079395 184 | 1.6275406444 1.1571492797 185 | -0.4098065878 0.0989912159 186 | 0.4917216478 0.1767351767 187 | -0.1277410074 -0.0430926341 188 | 0.7185312528 0.2488195269 189 | 0.2366133608 0.4329360296 190 | -0.6820886993 -0.5345699877 191 | 0.7081855625 0.6660352960 192 | 0.5677362316 0.9564066543 193 | 0.1427023033 -0.2550740181 194 | -1.2125064181 -1.4659112369 195 | -1.8106381585 -1.7316848489 196 | -0.4099382026 -0.8824801452 197 | 1.2212957473 1.6594447806 198 | -1.8115727996 -1.6875691763 199 | 0.5911906860 0.4895457045 200 | 0.6986190315 0.8968338994 201 | -0.5617384093 -0.6469037172 202 | -0.5958092805 -0.3540292110 203 | 0.4721836899 0.4896510576 204 | 0.4827060695 0.7227458335 205 | 0.4071445419 0.5442198408 206 | -2.2533883053 -1.7587921592 207 | -1.5868053933 -1.0651977215 208 | -0.9519501517 -1.3097577861 209 | 0.1859190506 -0.4338269818 210 | 0.2645047704 0.2950725014 211 | -1.6110321333 -1.4899184370 212 | 1.2469980888 1.7384878016 213 | 0.6178326837 0.6402995792 214 | -2.3387442219 -1.5323368522 215 | -1.4653353135 -1.5544000607 216 | -1.5308686874 -1.8226731890 217 | 1.8478419184 0.9475952354 218 | 0.7483571737 0.1449268489 219 | 0.9637013513 0.3181368684 220 | 1.4779790828 0.4152753515 221 | -2.5337796435 -1.8010751320 222 | 1.0391808626 0.8229713005 223 | -1.8267673799 -1.1735362602 224 | -0.0493413514 -0.6759562261 225 | -2.0810383020 -0.2790534045 226 | -1.0969117322 -1.5028282934 227 | 0.8782443058 1.4849439282 228 | 0.7846476970 -0.0639288702 229 | 0.7967705589 0.9394822122 230 | 0.5277892995 0.5258045135 231 | 0.6297916610 0.3683996451 232 | 0.3246368980 -0.9082365627 233 | 1.2310162742 0.7117070128 234 | 0.2753498588 0.6055084686 235 | -0.5650874536 -0.6658719130 236 | -0.4664108929 0.2024513994 237 | -1.5127872968 -0.3831214196 238 | 0.1007963927 0.5113649820 239 | -1.3355141168 -0.5191226409 240 | 0.1396473300 0.0734719878 241 | 1.0694543298 0.8430773715 242 | 1.3131361644 0.2218175087 243 | -0.3520011801 -0.5892645773 244 | 1.5494346137 1.0737108992 245 | 0.6551094845 -0.2848368709 246 | 1.7444431375 1.1928799086 247 | 0.4241995350 0.2407886041 248 | 0.0290471376 -0.3687387085 249 | -0.7486517128 -0.9783186375 250 | -2.5780349316 -2.8718865758 251 | -0.9724535146 -0.7491574793 252 | 1.3440370099 1.0808854875 253 | -1.9651000122 -1.2086709478 254 | -1.7439152652 -1.2354544604 255 | -1.2106131267 -1.3928921457 256 | 1.7857538083 1.7267116984 257 | 0.3098083962 0.1835349292 258 | -3.1411561229 -2.2677407081 259 | -0.6379801286 -0.3173899797 260 | -0.6250412900 -0.4305250600 261 | -0.7461293743 -0.1865196433 262 | 1.3463813955 1.1975258798 263 | 1.1523378950 1.3723564938 264 | -1.2134676179 -1.4575527175 265 | -0.0986716676 -0.8449774057 266 | -0.1264788511 0.2439116473 267 | -0.7536531306 -0.9751196304 268 | -1.9730681620 -1.4025366674 269 | 0.8811002254 0.5831990586 270 | 0.2605565626 0.6634264712 271 | -0.6366799817 -0.9579526744 272 | -0.0359473007 -1.0012346415 273 | -2.6878536814 -1.6659565158 274 | 1.2222594740 1.4761692450 275 | 0.0198966682 -0.0260363912 276 | -0.0262595645 0.3787240678 277 | -0.5873550159 -1.0227880771 278 | 1.4246886526 0.6703316621 279 | 1.0233440486 0.1750926867 280 | -2.4498998868 -2.0160626944 281 | -0.7858242348 -0.9555096366 282 | 1.0571036681 0.6642039647 283 | 0.9307210198 0.9608035434 284 | 0.7207899010 1.0001082196 285 | -0.2750018518 0.0479197328 286 | -0.7304972873 -1.1145936441 287 | 0.0937374705 0.5226923083 288 | 0.3236528721 1.0267971797 289 | -0.1359990147 -0.2733108320 290 | 2.1151448525 1.0561880439 291 | -1.6433415160 -1.6835068883 292 | -0.1165270146 0.2350298937 293 | 1.6577109485 1.9302319525 294 | -0.4397857824 -0.5597254325 295 | -1.2984298150 -0.8384439323 296 | 0.8933287600 0.6792813991 297 | 1.5654386209 1.5153624464 298 | 0.3582130082 -0.3177314458 299 | 0.0039177923 0.2085025634 300 | 0.0203262311 -0.5804914101 301 | -0.1694820112 -0.2552664258 302 | -2.1966162477 -1.9169359645 303 | -0.3602785635 -0.2348219511 304 | 0.2436828214 0.1611406198 305 | -0.2780500260 -0.1584024105 306 | -1.0644295673 -1.5216980035 307 | -0.8250414411 -1.0932340446 308 | -0.1510480753 -0.4117594948 309 | -0.6753205975 -1.1109775206 310 | -1.1784421094 -0.6952602296 311 | -1.1796101407 -0.6783461402 312 | 1.9311925725 2.0214882185 313 | 3.2741472532 2.4815208720 314 | -1.0624608074 -1.2181800753 315 | -0.0956684250 -0.7359305139 316 | -0.2431741284 -0.0988394797 317 | 2.0432893756 1.3595682943 318 | 1.0209508425 1.1440517370 319 | 1.5284925756 1.0923088232 320 | -1.0420830480 -0.3182253187 321 | 1.8468665211 0.6314469178 322 | -1.8322470169 -1.4137396210 323 | 0.8166505170 0.7307886164 324 | -2.8642821823 -2.4202506828 325 | -1.8332671725 -1.0280328397 326 | -1.6094017510 -1.2485831701 327 | 0.8583114615 0.1764218780 328 | -0.2991909061 -0.3608697622 329 | 0.7738072289 1.2340214646 330 | -2.4199352762 -2.0404376967 331 | -1.7927035017 -1.2417198325 332 | 1.2451968290 0.6718070473 333 | 0.2151461991 0.2813676696 334 | 1.9658663530 1.6091294382 335 | -0.5181183835 0.5213568215 336 | 0.1926924249 -0.2418450231 337 | 1.9359079555 1.4928052367 338 | 0.4607249896 1.3437317521 339 | 0.4519268685 0.7195188544 340 | 0.4991278577 -0.3892979275 341 | 0.5733805377 0.8847909247 342 | -1.7322171654 -1.1438726067 343 | 0.4235208031 0.4460919083 344 | 0.7828149926 1.1822919897 345 | 0.0573408666 -0.7234965995 346 | -0.4463076021 -0.6517272675 347 | 1.5848842629 1.4811601482 348 | -0.8299330861 -1.0226582039 349 | 2.1639545862 1.6926234095 350 | 0.7952684216 -0.1347600826 351 | -0.5607185594 -1.1970778186 352 | 1.4039181138 1.4244410065 353 | 0.4790855389 0.1045017794 354 | -0.2781980224 0.1414642995 355 | -0.1938056187 -0.0764044460 356 | -0.2648769846 -0.1826450021 357 | -1.3798780936 -1.0698317073 358 | -0.2531927013 -0.0833203424 359 | -1.2251667246 -0.9644471862 360 | -0.0971862455 0.0820088477 361 | 0.1367802536 -0.3530001848 362 | -1.7917396351 -1.0880335680 363 | 1.0684069297 0.9404456277 364 | -2.2885521952 -1.2786128149 365 | -0.4558891719 -0.3306306619 366 | 0.4552401502 0.1213996634 367 | -0.4762439255 -0.7721129952 368 | -1.2239144801 -1.8116192253 369 | 0.4885276104 0.5240326525 370 | 0.9538175585 0.2897781059 371 | -0.6738672864 -0.5298548877 372 | 0.6562864978 0.6248846615 373 | -0.9488237374 -1.3746682578 374 | 0.3610428013 0.0833017693 375 | -1.2771316971 -0.8731880380 376 | -0.1859485343 -0.3805233352 377 | -0.2015466549 0.2427907394 378 | -1.2244874443 -1.3096819405 379 | 0.2644731890 0.5165335265 380 | 1.3841466606 0.7632263151 381 | -0.4644829484 -0.2302846804 382 | -0.0388570821 0.6896240916 383 | 0.2163161368 0.3332173825 384 | -0.0420622790 -0.2538651967 385 | 0.2421540574 0.9974772363 386 | 0.2680428984 -0.1217453309 387 | -0.8458834976 -0.4423568297 388 | 2.5811338741 1.6669739541 389 | 1.6041037120 1.7469902913 390 | -1.2815520133 -0.9603450005 391 | -1.6347291868 -0.6227176685 392 | 0.5453149141 0.7727653160 393 | 0.8600033943 0.8597128336 394 | -0.4953640848 0.0924089386 395 | -1.1331120601 -0.1931416395 396 | 1.1565682785 1.1890918683 397 | -1.6393858284 -1.7241109760 398 | 0.5975559604 1.3734340817 399 | 0.7500853474 0.6586747518 400 | -1.3357074157 -1.4807829926 401 | -1.4657110667 -1.1312242088 402 | 0.2400908347 0.3135528718 403 | -2.1135756060 -1.2724702990 404 | 0.3868214671 0.6131683981 405 | 1.2984103607 0.9793858698 406 | 0.4902379432 0.1333207220 407 | -1.4324280130 -0.5296398466 408 | -0.5307119808 -0.2887777904 409 | -0.0196284400 0.4359452958 410 | -1.0326196418 -1.5296669196 411 | 0.8352216039 0.7431364133 412 | -1.2979078590 -0.8466847847 413 | 0.4349631886 -0.2199796942 414 | -3.6308463684 -3.1025677609 415 | 0.9890607983 1.6267438490 416 | 1.2831163507 1.2459772937 417 | -0.7856116443 -0.9452026419 418 | 0.5610379435 0.3513721475 419 | 0.1978008173 0.1477743483 420 | 1.8774517490 1.4748631708 421 | -0.1492809363 -0.0352767500 422 | -0.7300367514 -0.9802683833 423 | 0.2038489257 0.0048200723 424 | 0.8052046164 0.3761390071 425 | -0.6863941172 -0.0030426356 426 | -0.3447173909 -0.7184023707 427 | 0.5191186858 0.9282030627 428 | 0.7502854848 0.4303737275 429 | -1.3156615943 -0.2305343908 430 | -0.5738627011 -0.5562041636 431 | -0.4652951763 -0.2190899528 432 | -0.8500307266 -0.1351939029 433 | -1.2314753492 -0.4129685103 434 | -0.4829018003 -0.3283105820 435 | 0.2100856972 0.4875035550 436 | 0.1950628633 0.0621474086 437 | -0.1831565106 -0.8209735685 438 | -0.7933123086 -0.3806525348 439 | 0.3148809024 -0.3656740174 440 | -0.8425254290 -0.7839614435 441 | 0.0203137700 -0.2448074996 442 | 1.2008711687 0.7651830111 443 | 0.0720172993 0.2039476894 444 | 0.7837132045 1.2536843492 445 | 1.3402527419 0.9454528689 446 | 0.0953855081 0.0776860698 447 | 0.0597534185 -0.0152541222 448 | 1.0326569854 0.4630203001 449 | 0.0532244304 0.4785434815 450 | 0.2446901664 0.0554788831 451 | 0.1508041298 0.5458652440 452 | -0.1596701844 -0.5963919680 453 | 0.3142634324 -0.5258207456 454 | -0.7110341302 -1.5562702201 455 | 0.6160707341 1.1746939825 456 | -0.3279552101 -0.0022950713 457 | -0.2889432698 -0.0264589519 458 | 0.1410229589 0.6619611256 459 | -0.6309106220 0.2093635211 460 | -0.1268505272 0.0398573293 461 | -0.0778580414 0.2685774977 462 | -0.8031577606 -0.7220191979 463 | 0.6995347867 0.6217001517 464 | 0.6118137767 -0.2336378915 465 | -0.6693940390 -0.4140429742 466 | -0.9100264434 -1.2127604046 467 | -0.0925577362 0.0648442936 468 | 1.0826627746 0.8514498108 469 | 1.1755153991 0.9620520957 470 | -0.9428174063 -0.7650280227 471 | -0.7685788973 -0.0955868702 472 | -2.2349997085 -2.2145931653 473 | 0.6429065622 0.4140750000 474 | 0.6107762966 -0.1581857693 475 | -0.2918230411 0.1060871784 476 | 0.8986887663 1.2180057117 477 | -0.2472549700 -1.3088836227 478 | 1.8894262414 1.5587194554 479 | 0.6780413033 0.6252107611 480 | 1.4711693527 1.5592923356 481 | 0.5674920001 0.0613828628 482 | -1.7677681137 -1.9375672072 483 | 1.0437332280 0.6037435623 484 | 0.3120177203 0.5471968051 485 | -0.2239121107 -0.5296699712 486 | 0.1400015834 0.2746183315 487 | 1.8503683337 1.2063268653 488 | 0.2431501871 -0.0089171350 489 | -0.0482959344 0.3867515469 490 | -0.6563433512 -0.5544415949 491 | 0.9999053664 0.6061637392 492 | 0.4678062911 0.0478923620 493 | 1.8137004667 1.2386961547 494 | 0.5383420589 0.3952850025 495 | -0.2555796708 0.0481247447 496 | -1.3013095094 -0.7234192330 497 | -2.0200814568 -1.2138278373 498 | 0.9632066550 0.2226607133 499 | 0.0676037720 0.2442757093 500 | 0.0030669259 0.3187440108 501 | -------------------------------------------------------------------------------- /hw1/data2.dat: -------------------------------------------------------------------------------- 1 | 210.9226746568 1.8276463302 2 | 365.6200287031 1.2438970609 3 | 248.1194733742 1.9913020793 4 | 22.7306050632 1.3295953120 5 | 79.0116604783 1.8727922451 6 | 326.7900204872 1.7478791252 7 | 400.5589966432 1.7369046507 8 | 85.9289740328 1.4497640026 9 | 531.2932418861 1.6624627730 10 | 78.5732495113 1.0833529728 11 | 219.4282996376 1.3430402360 12 | 61.1830170117 1.2849609344 13 | 256.0706192345 1.8354444683 14 | 94.3480593414 1.4396756459 15 | 135.6093106706 1.3405642526 16 | 203.4808017418 1.9485868053 17 | 96.9575933943 1.6880899558 18 | 356.0831369407 1.1697974792 19 | 64.1876880261 1.3850917916 20 | 107.9113560965 1.1505274507 21 | 113.2694244946 1.9409805287 22 | 153.1509859172 1.8506258689 23 | 114.3247673676 1.2604766225 24 | 12.4350112296 1.0861308952 25 | 18.1458281115 1.2643778084 26 | 1751.6646281907 1.7076468552 27 | 13.2184281529 1.1176417589 28 | 169.6392521691 1.8847547150 29 | 62.7217703594 1.5780894675 30 | 114.6984650490 1.6069295164 31 | 277.3111525509 1.5893865877 32 | 161.2384060248 1.9460087144 33 | 70.3664886461 1.3913740146 34 | 36.1908964062 1.0676381765 35 | 94.0959450789 1.6717955607 36 | 20.1110928111 1.7418179135 37 | 84.1869282591 1.6985096422 38 | 62.1126617231 1.9981774241 39 | 146.6552584836 1.5128734482 40 | 45.4199304704 1.9124308494 41 | 68.5187089948 1.1956521368 42 | 171.4181946173 1.1090949448 43 | 188.2479764322 1.4990321554 44 | 67.8485760858 1.7344981893 45 | 57.2507028348 1.8346068517 46 | 128.7236120398 1.2058671657 47 | 59.8104056796 1.2800541015 48 | 85.3937807483 1.2893466563 49 | 178.1525366591 1.9791397417 50 | 61.5609219859 1.8146927124 51 | 395.1619169684 1.6231571611 52 | 82.3037681395 1.9095732677 53 | 63.2574306098 1.6794524614 54 | 126.6630333764 1.8444186784 55 | 315.4106213853 1.2367861678 56 | 146.3134951673 1.7320848857 57 | 79.6276255862 1.8304465248 58 | 17.6204954582 1.2377247075 59 | 34.9941595697 1.9547559812 60 | 20.6141065072 1.4357080809 61 | 27.0663759582 1.2294015281 62 | 514.5620347389 1.8146898877 63 | 699.2489931653 1.9213711151 64 | 36.0549551973 1.4914943078 65 | 651.2967034535 1.7986924353 66 | 98.7645610597 1.7618674589 67 | 446.9046722080 1.6681469295 68 | 35.5529677191 1.5038453932 69 | 12.2745740331 1.4891709250 70 | 81.4832447910 1.4699923322 71 | 55.9389312918 1.2227573839 72 | 190.5159704675 1.4705843371 73 | 14.2856752171 1.6298358014 74 | 90.8985003244 1.6734464215 75 | 437.5686930574 1.6408343546 76 | 23.2622524557 1.0400964259 77 | 26.7115392898 1.7394174666 78 | 141.4779480981 1.0946067888 79 | 148.1600616247 1.6012435125 80 | 98.0334487512 1.0936656580 81 | 81.6296682590 1.0655014555 82 | 119.3286452000 1.0462016007 83 | 50.8795663108 1.9554617654 84 | 229.1253374137 1.2311314824 85 | 23.3078576226 1.3668160338 86 | 277.7538654045 1.6947988980 87 | 248.3684331782 1.3716812616 88 | 175.7530492578 1.9879908492 89 | 165.5072936762 1.7043088584 90 | 172.8570874362 1.9385531778 91 | 96.5636823989 1.4642649561 92 | 256.5628901057 1.8620705730 93 | 276.4213990092 1.2566376992 94 | 15.3348163196 1.1023347881 95 | 35.6250636943 1.0491787398 96 | 24.4071471036 1.4778950089 97 | 164.9850606444 1.4257002252 98 | 182.4868490153 1.9033671347 99 | 145.1051255755 1.4160251308 100 | 265.7218323136 1.4668740402 -------------------------------------------------------------------------------- /hw1/data3.dat: -------------------------------------------------------------------------------- 1 | 34.8368677937 -0.1406852133 -0.1436989235 2 | 35.2118366127 -0.0006035257 0.0247908893 3 | 35.1741178534 0.0277969538 0.0392302910 4 | 35.1726105328 -0.0080377602 -0.1661137203 5 | 35.2545672239 -0.1316427305 0.1011897883 6 | 35.0724286924 -0.1776428930 0.0233466031 7 | 35.1504280830 0.0866787348 0.0356454466 8 | 35.3029832674 0.1841174463 0.0673054373 9 | 35.0854498948 0.0364686463 -0.1219003354 10 | 35.2866647466 -0.0482191322 -0.0511709919 11 | 35.3297576605 0.0356260481 0.0216771733 12 | 35.2831283424 -0.0419848080 0.0558053515 13 | 35.4027136193 -0.0354289811 0.0960105367 14 | 35.1024340677 -0.1447068031 0.0013303609 15 | 34.8350986248 0.0044392149 -0.0864788164 16 | 35.1018550271 -0.0122110594 0.0687540857 17 | 35.0369963833 -0.0200807989 0.0019862808 18 | 35.1557129224 -0.0153856304 -0.0324272847 19 | 34.9528833432 -0.1277348469 0.1321134964 20 | 35.4777747793 -0.1134502033 0.2577786830 21 | 35.1520521650 -0.0666078752 0.0733787533 22 | 35.0304339088 -0.1788929303 -0.0010199462 23 | 35.2003823308 0.0713730870 0.0138027990 24 | 35.0916403367 0.0431984645 0.0434300589 25 | 34.9713913337 -0.0159459084 0.0156440246 26 | 35.1633611977 -0.0882358655 0.0899185469 27 | 35.2764808786 0.0270785657 0.0716225911 28 | 35.4645859388 0.1362338394 0.1584717420 29 | 34.9734120290 0.0034539139 -0.0955138309 30 | 35.4957830360 -0.0319353627 0.1596071735 31 | 35.3027230195 0.1440676805 -0.1143570776 32 | 34.8001094717 -0.1747767307 -0.1454081722 33 | 35.1615648473 -0.0704090343 0.0040420076 34 | 35.0603522917 -0.0795037334 -0.1319550119 35 | 34.8781027527 -0.1339981670 -0.0596877686 36 | 35.4415611150 0.1538474321 0.1042288005 37 | 35.0775580096 -0.2099131536 0.0453459952 38 | 35.0994181008 0.1219821681 0.0824077730 39 | 35.2743429914 0.0811342858 -0.0065779993 40 | 35.0940362786 -0.0151422613 0.0806848346 41 | 35.5185466451 -0.0186002965 0.1239438908 42 | 35.1072592910 0.0475327247 -0.1741100317 43 | 35.1306849281 -0.0997684723 0.0397220466 44 | 35.3776539496 0.2128526307 0.1005966157 45 | 35.3052762466 0.1344046118 -0.1136356330 46 | 35.5844735461 -0.1347823718 0.3414859642 47 | 35.0169130605 -0.0629576665 0.0292824455 48 | 34.7248191375 -0.1971034277 -0.1835559596 49 | 35.2553616603 -0.0254912133 0.1059128202 50 | 35.2333288025 0.1345223383 -0.1897968342 51 | -------------------------------------------------------------------------------- /hw1/drawsml.dat: -------------------------------------------------------------------------------- 1 | 0.7820353051 -0.8839787354 0.4968492834 -1.3812725808 -0.1067680691 -0.4063719886 1.5574722235 -0.6303379508 0.1145106766 0.8581278655 -0.7336736195 0.3527565322 -1.4049961195 -0.9314328916 0.8368078892 0.0861700224 -0.8643617700 2.0037767843 -1.3362347125 -0.6019186849 2 | 0.3802238478 0.4553182572 -0.3406161906 1.0229479471 1.1846671761 1.1450079955 1.2083320694 -0.3995280419 0.4056304565 -1.3603068853 -0.2674842882 -1.3626648256 0.2651131727 -0.5100869396 0.4445522340 0.8641907607 -0.3918796191 -0.1483195437 1.0850415009 0.5498481824 3 | -1.1831476696 -1.0041184227 -1.4215741003 -0.8300635819 0.8336465317 -1.3185656538 0.0073759743 -0.2899677199 -1.4077306465 -0.5276168094 -0.4960910480 -2.6013305320 -0.9878126910 -0.9622208539 0.5481605406 -0.0384735300 -0.5155052374 -1.0319697246 -0.3493157768 -0.4617586757 4 | 0.9376740913 -1.7247410687 0.4961817848 1.3342562135 -0.6580308771 -1.7823831757 -1.0002489478 1.4182740045 -0.0304634820 -1.4088920915 -0.5898823558 0.8569036207 0.3113967250 0.8684219696 -0.3033338377 -1.7226587468 -0.4380929410 -0.8142227349 -0.5343830936 0.4037322873 5 | -2.1772187416 -1.0598514631 -2.2539017139 0.2553140090 0.6872062868 -0.0773547213 2.1563820506 -0.3073820750 0.0311043418 0.9730721947 -0.3345100794 2.3353513835 -0.2106772586 -0.5521098328 0.1568772461 0.4413657540 1.5838045265 -0.3114429649 0.7000370763 1.1428277612 6 | -0.0836603268 -1.3355111795 0.2962820674 -0.8993985658 -0.3531670594 0.9137257441 -0.7189993186 -1.6433478115 1.0701107055 -2.3178573987 -0.0516704249 -0.0589750309 -1.0355729044 -0.5646721868 -0.2458355103 -0.4461678236 0.1627547781 1.5957263062 -1.1261873023 -2.7985645053 7 | -0.6549850456 -0.3838828040 -2.7401930390 1.3304226898 -0.0963696797 0.1938645945 1.8980217277 1.1809759386 -0.9484086923 0.7341061675 0.9673422144 2.4378802949 1.3957269465 -1.1620342856 0.1673294343 1.0204194264 -1.9264392271 -1.4652901283 0.6062882876 0.4442971410 8 | 0.0565446586 -0.5905145607 0.3384979033 -0.2164542564 0.1911514741 0.2758022964 0.2994178556 -0.8635733526 -0.7956491649 0.7442811405 -0.8467213919 -0.1697763597 -0.0732129313 -0.3477285818 -1.1215650176 0.8290495470 -0.1440575539 -1.3068462308 -0.0576467472 1.1062942382 9 | 0.3888522832 -0.4265378437 1.1958174457 -0.1640119434 1.6968029529 -0.2878500802 0.7026687492 -1.6532000258 0.2381085783 0.4789871497 -0.2990424925 1.1558330938 -0.6634433545 0.3169490933 0.0990362674 -0.2347374793 -1.2922637885 -0.1210255296 2.4017720686 -0.2722717229 10 | 1.3008149326 0.4500561579 0.0960224736 -0.6292717145 1.2306325015 0.9247467245 -0.6153339964 0.6126589286 0.0282800511 -0.8206004473 -0.2974887794 -0.0984364976 -0.1624221891 -0.6229620466 -1.0468988737 -0.9888888761 -1.3119852160 -0.8569564423 0.2123523055 1.4568821779 11 | -3.3680852323 -1.6984910211 1.3285421975 1.0797854152 -0.9583347788 1.1750694079 0.6095946805 0.4058639636 0.9499674856 0.2176452196 -0.2707088987 -0.7790505742 0.6464373881 -2.9505668298 0.6827568868 1.4213031991 0.8843259564 0.6766616119 -0.5651442202 -0.1188532276 12 | 0.0045447016 1.2446442908 -0.0781154625 1.5101049637 1.9361206674 0.5445205819 0.2580518389 0.5604387021 1.7646361484 1.5184594114 1.1756911979 0.5865646172 0.0502167619 -0.1671274728 -0.2306388948 0.0448683875 0.3739237517 1.3810286377 0.3417513886 2.0806975675 13 | -0.0714351789 -0.1918950640 0.6875381998 -0.7557711928 0.0855777196 -0.8848130642 -1.2473924454 0.3061736853 -0.7346231577 -1.6315910814 -0.9655635846 -0.8744010423 -0.1012611888 -1.4363898090 -1.0388024737 -0.9774959847 1.0700565660 0.6951906337 -1.1173390166 -0.3880378932 14 | 1.2816892528 0.2161661138 -0.9701788346 -0.1907625390 1.8973883048 0.0205472649 -1.1866043651 -1.7356282797 -0.7905005887 0.2778177902 -1.5903415999 -0.8803240507 1.5055736532 0.9208735750 -0.7626908604 0.7752098607 0.2004445157 -0.6185369614 -0.4801286976 -0.1656379364 15 | 0.7098466557 1.1944598143 0.1454223237 -1.1017281031 -0.8475220114 1.0830193020 1.9541669197 0.7814390045 -0.4168349868 -0.0902543565 0.1069014845 -0.1582974878 1.3928442707 -1.5187504413 1.1182375172 0.5500439028 1.4774510867 -1.3556991844 -0.7953222452 -0.2943075449 16 | 1.9951710623 1.8758672662 -1.0120231624 -0.1609372779 -0.1142605868 -1.1092003414 0.5977454544 -0.8770099327 -0.7418505185 1.2830812749 -0.6220869409 1.2426076754 -1.1235476142 0.0415556562 0.0084643352 0.8516593874 -0.3212888934 0.3684110315 -0.2669414214 0.4278839119 17 | 0.6941631989 -1.2954136209 -0.0781826034 -0.1978781642 0.5047719267 -0.1821804063 -1.1736302752 0.0069685810 -1.2576913849 0.5244982865 0.5562563235 1.7079243083 0.8900449994 0.6664540723 -0.3604048063 0.3774325099 -0.4679365676 0.0561840502 0.9590350710 -0.8207818559 18 | 0.2574562473 0.0415778414 0.2083053104 2.3631579105 -0.6274224656 -1.3258020474 0.3484849127 1.9808152252 -1.0284833309 -1.5690887703 -0.6827868804 1.7893386809 -0.3376125406 0.0893211331 -0.1868693408 2.4796816685 0.0784416987 -0.1911821631 1.3713812120 -0.3108969920 19 | 1.4868009511 0.2232071034 -0.8492485436 0.6246474896 0.3027275922 -0.5770848962 1.0154008581 0.1464069237 -0.6694692382 0.6445830242 2.4374397849 2.3696933296 -0.0648573465 -0.5561684991 -0.3385031656 0.0341451483 -1.3143529400 1.5385101122 1.1568010159 0.7145575748 20 | -0.0410757639 -1.3009791058 -0.2933907218 0.0485061047 0.4496697540 -2.0219863709 0.8237292954 -0.8490899297 0.6687879879 -0.9656851707 -0.5540693884 1.2911926077 1.8051673604 -2.1800145184 -0.4629381536 0.3824546847 -0.1333914299 -0.2159275661 2.0701936537 -0.4897722923 21 | -0.0709388205 0.6224730263 0.0366628074 -0.7225134602 2.5135701970 0.1375149278 -0.9506978026 0.3088858792 1.3999269440 0.8466357646 0.6280695777 1.4994527273 0.5858292962 -0.6681883630 -0.0116750347 -0.3158593308 0.3993523533 -0.3779247675 0.7004773581 -0.0411955261 22 | 0.9890126407 -0.6299713180 0.1246810139 0.4304297700 0.2281368160 -2.1486706125 1.8184081661 -3.0786303879 -0.9878818485 0.0086018905 -0.9395910705 0.3451073501 0.1768844378 -2.4820858154 -2.3797050674 -0.1252407552 -0.1567632164 -0.8329225551 -0.8402362940 0.8224022332 23 | -1.0582836952 -0.1702539547 0.5250854588 -0.5166326831 -0.3597174463 -0.8334321790 0.5975435987 -0.7923327492 0.8139371494 0.7305330027 -0.2847719016 1.4027878954 0.2466811542 0.6804775050 -1.9519820454 -0.8720365576 -0.0861298656 0.0965009466 -1.2493089199 -0.8355753439 24 | -0.1735660743 -1.1022190716 0.8351005099 1.5698306913 0.8281501417 -0.0555386767 -1.2246803157 -0.1624642452 -0.6669829326 -0.6247218072 0.8477758560 1.6145558574 -0.2895505099 -0.6208248155 -0.8691515703 1.0212784461 -0.7325451142 0.6506815741 -0.4956225280 0.2309223046 25 | -0.7810840692 0.5263708374 -0.5406793912 -2.3606578641 0.6750930919 1.0502521231 -1.4568532683 0.0563285207 0.5361978280 -1.9314481686 -0.0169137895 -0.2627656864 -2.0275788083 -0.2973051952 -0.7237314688 0.1483667544 0.1702315461 0.6644308337 0.4356691777 -0.7030923074 26 | -0.4632454754 -0.1248785942 -0.1446635427 -0.4151341937 -0.2725767877 -1.1138459649 -1.0054073868 1.7442144898 -1.2349348290 0.2619527325 1.1697812863 0.5286038990 1.5921573663 0.5833559360 2.0457056984 1.5927705599 -3.1812033639 1.7470880829 -1.0781289025 -0.9327322450 27 | 0.0624933373 -1.2804705369 -0.4745531990 0.9759072770 -0.6164512139 -1.2734046882 -0.8459410523 -0.5985461242 0.8050474343 0.6898063027 0.5844640596 0.6593898008 -0.4360781859 -0.0934967560 -0.8655337671 0.4293523568 -0.9599356342 0.0706023275 -0.8205998146 0.4423513692 28 | 1.2186774366 -0.2953811571 1.2138388851 0.1673864890 0.1962966402 -0.9344700811 -0.0601279434 1.6272460543 1.3504662979 0.0963851102 0.0265671655 -1.5226752188 1.8657245906 0.5720368044 -0.7321596574 1.2789633379 -0.6530673126 -1.0353401789 1.2416199282 0.1552645910 29 | 2.0046993014 -1.0501284973 -0.2668170214 -0.1803119897 0.5084658574 0.6955345971 -0.8843472757 0.1396076647 0.1986874832 0.5045876088 0.2323385434 1.1263111131 0.2007923546 -1.1004164495 0.3518185110 0.5638632184 -0.5643826019 1.2373902268 0.0751755017 0.3702707710 30 | 0.0279658703 -0.1174238951 0.1214703452 -0.1056327216 -1.5139304847 0.2790784622 0.3427043928 -0.3114469902 -0.3639522469 -0.3366125443 0.8595681024 -0.8440447847 2.1669504281 -0.9572923957 -1.3652432490 -0.3791111066 -0.2589361001 0.1294060026 0.9590774171 -0.5326522612 31 | 0.4303231710 -0.3866016398 0.3944991344 -0.0512674321 -0.5830521945 -0.1142184281 -1.1686830846 1.8542280005 -0.3626879692 0.5027398849 0.7253702475 -0.4592433264 -1.1776553994 -0.2230101940 -0.5522704629 1.4007400140 0.4084589103 -0.2023962435 -0.4642272825 0.9126471609 32 | 2.2481656426 0.3081018737 -1.4712122571 0.5263513625 -0.8503199683 0.4799120781 -0.1542699394 -1.7718377673 2.3314610470 1.9682320916 -0.9211425440 -1.2648433231 -1.2165532248 1.1749769771 -0.2965975854 -0.0504910953 -0.3356043785 1.0450720302 0.5531527284 2.3688772565 33 | 0.1787487177 1.0418949464 -0.2480359916 0.7679169371 1.6633676609 0.5252544217 -1.6985555335 0.1278003802 -1.7922441290 1.0076078803 0.2065847586 -1.2116405021 0.2794383578 1.7508942789 -0.8354177819 -0.1199298449 1.4257917500 -0.9003722961 0.4196788117 0.2854866737 34 | 0.0110759577 0.7913281601 -0.8408813462 1.2934612358 0.6759311361 1.8774477359 -1.1985112573 1.0927799951 0.0916674141 0.7408287963 0.7750510711 -0.3014079189 -1.0703201800 0.1585420578 0.4803374181 -0.2254139297 -1.5128491687 1.4956146310 -1.7115092612 -0.1583025911 35 | -0.0250903899 1.3480480038 -0.1280091526 0.4213832619 0.4600646946 -1.1469526323 -1.3137319402 0.9698349014 -2.3698865317 0.4157041533 -1.3359672667 0.1736178243 -0.1297708063 -1.2208707455 -0.9256594965 -1.5706253795 -1.0259006732 0.2897071797 0.1662027384 -0.0948014434 36 | 0.5478916401 1.1570904209 2.0238885728 -0.8346662504 -0.6866532399 0.9500696886 -0.0744318657 -0.0368260286 -0.7458477091 -3.1871795422 -0.0459549179 1.9401523030 0.7981528713 -0.2191548847 0.0690786315 0.5396299669 -1.8160420686 0.3870408822 0.0581079285 -0.2182056341 37 | -0.1026345511 -0.6161605172 -0.4741926343 -0.6568692495 -0.9363607832 0.0334057437 -1.0497545007 0.0920659202 -0.1747607391 -1.4600694963 0.3782141840 0.2969447079 0.2810437121 -1.5309615117 -0.0631096096 -1.1141197013 -0.9117214790 1.0093896441 0.1225809346 0.8380491095 38 | 0.6074678684 -0.0328248566 -2.2130464333 -1.2007156301 2.3411753017 0.3324734107 1.2986165953 -1.0092852283 -0.5140847056 0.1527241785 -0.3608803622 0.4410129861 0.2821105497 0.2580640669 -2.2199955405 0.1370974398 -1.1278762839 0.2858393630 0.9114021587 -2.3169614421 39 | -1.2787112496 -1.2566979981 -2.1093112352 0.3042787283 1.6186264922 0.1949966111 0.2137643858 -2.0927292828 -0.1664462666 -1.3521004923 -0.1122939962 0.7671612600 0.8079036785 1.0437730587 -1.5897193196 -1.3489243511 0.8574280529 0.2433504905 -1.5300872696 1.2374593485 40 | 0.3970648876 0.1760347367 0.4087786125 0.8966540070 -0.8065174312 0.2037253504 -0.7450581163 1.5278402594 -0.0288829257 -0.2623976240 0.7100634795 0.8716632062 -1.1920288546 -0.1841041346 -0.3535501608 -0.3292053665 -0.6251772834 0.1057151556 0.9268806300 -0.7171215240 41 | -0.4619411273 1.1667934862 1.6455976408 -0.3992732237 0.9898028387 0.2075783567 -1.4960808163 -0.9615875539 0.9275043856 0.6417684600 -0.7862124326 -0.8369272730 -0.2865801333 -1.6461277375 1.6008985467 -1.4311243289 -0.1530050607 -0.5796855247 1.6933431984 -2.1370840922 42 | 2.6244779534 -0.7673465717 -0.2020196263 0.4325660358 0.3447217599 -1.1778194680 0.1235177496 -1.3246249655 0.3943787451 1.2480780099 -0.3587189345 -0.8996756591 -1.7961962264 -1.2151315438 -3.8352418383 -1.3770776861 -1.0552506781 -1.4511255333 -0.4827315087 0.6978452512 43 | -2.0711895725 0.0321686379 -1.4790130045 -0.3254472212 -0.3227780561 2.1551250471 0.5733548352 -0.4316903975 -0.5247399846 -0.5132673300 -0.0098340487 1.0764664976 0.0724287346 0.2406561182 1.4176472904 0.2364064458 0.1640004799 0.4081379603 -0.4357702298 -0.3103313338 44 | 1.8218544525 1.2049389359 -1.4197222808 1.5915571901 1.4415045832 0.4570573235 -0.1948732090 0.3679412068 0.0217540976 -1.0973737910 -0.2027092052 0.2551255926 0.7418912521 -0.7277774386 -0.0483309043 1.2665447614 1.7766280982 0.7467340528 0.4340676419 0.1486265106 45 | 0.0022359163 1.9499582644 -0.0694370046 -0.4406955552 0.6184229185 0.1908378820 -0.7052855328 -0.0635717701 1.5213962992 -0.7983290015 -1.1705444336 -1.5713796756 -1.2645329294 0.0193779518 -0.6436841311 0.7184691116 1.2905172352 1.5034987296 -0.7707648708 0.8735871775 46 | -0.7256875052 2.8764327348 -0.5898581007 -0.3827694106 -0.1311321999 0.0688369346 -1.9131460707 0.2399228472 -0.1646132726 0.6785315655 -0.7597750220 -0.1864508138 0.3223160677 1.4204374064 -2.2528655370 -0.2785562229 -1.4204495966 -0.2888444559 -1.3149974435 -0.0826816647 47 | -0.6942373868 1.0025947926 1.3107073861 -0.4665804701 -1.3090385143 -1.1162555481 -0.0534350638 -1.0364779699 1.8029174042 -2.7106558186 0.8111631028 -0.8740714466 0.9765829617 2.5072473272 1.5968868127 -1.4071733166 0.9842543106 2.1388344314 -0.6732452782 1.9972022268 48 | -0.2243878066 -0.0793786628 1.0863102584 -0.7364307558 -1.8895697924 0.9798253478 2.4885596565 0.5501697138 -0.8944797621 -1.0909381832 0.6137413719 0.3411675447 -0.2367312694 -0.8115205942 0.0788181285 1.1759984973 -0.9218788999 -0.2011442030 1.0169822527 -0.3803396460 49 | 0.5339896567 0.6707844068 1.9472306799 -0.7449720522 -1.6820273569 0.6855585880 -0.7806360783 -1.1671568446 0.0846301214 -0.3745446955 1.6921075433 0.9875983831 -0.0555632634 -1.6762532664 -0.6573346771 0.4249335720 -2.0182128231 -0.5955490011 0.5832179657 0.1244425276 50 | 1.8588374865 1.4785789592 0.4924414939 -2.4869962244 1.1138566423 -1.2562860294 0.9790310316 -0.7922868868 -1.3909079152 -0.3017486203 -0.1878956327 0.0725860178 -0.0298367074 1.9617546611 -0.9780347935 0.5341219019 1.6943029661 -1.3228234146 -0.1641203789 1.0043965965 -------------------------------------------------------------------------------- /hw1/question1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pandas\n", 10 | "import math\n", 11 | "import numpy as np\n", 12 | "import matplotlib.pyplot as plt\n", 13 | "import statsmodels.api as sm\n", 14 | "from scipy.stats import norm\n", 15 | "from statsmodels.sandbox.regression.gmm import GMM\n", 16 | "from statsmodels.base.model import GenericLikelihoodModel" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 2, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "#load data into memory\n", 26 | "data1 = np.genfromtxt('data1.dat', delimiter=' ')\n", 27 | "data1 = data1.transpose()\n", 28 | "\n", 29 | "#partition correctly\n", 30 | "y = data1[0]\n", 31 | "x = sm.add_constant(data1[1])" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 3, 37 | "metadata": {}, 38 | "outputs": [ 39 | { 40 | "name": "stdout", 41 | "output_type": "stream", 42 | "text": [ 43 | " OLS Regression Results \n", 44 | "==============================================================================\n", 45 | "Dep. Variable: y R-squared: 0.799\n", 46 | "Model: OLS Adj. R-squared: 0.799\n", 47 | "Method: Least Squares F-statistic: 1979.\n", 48 | "Date: Thu, 27 Sep 2018 Prob (F-statistic): 1.33e-175\n", 49 | "Time: 17:53:51 Log-Likelihood: -362.72\n", 50 | "No. Observations: 500 AIC: 729.4\n", 51 | "Df Residuals: 498 BIC: 737.9\n", 52 | "Df Model: 1 \n", 53 | "Covariance Type: nonrobust \n", 54 | "==============================================================================\n", 55 | " coef std err t P>|t| [0.025 0.975]\n", 56 | "------------------------------------------------------------------------------\n", 57 | "const 0.0055 0.022 0.245 0.807 -0.039 0.050\n", 58 | "x1 1.0105 0.023 44.486 0.000 0.966 1.055\n", 59 | "==============================================================================\n", 60 | "Omnibus: 0.044 Durbin-Watson: 1.995\n", 61 | "Prob(Omnibus): 0.978 Jarque-Bera (JB): 0.120\n", 62 | "Skew: 0.002 Prob(JB): 0.942\n", 63 | "Kurtosis: 2.924 Cond. No. 1.09\n", 64 | "==============================================================================\n", 65 | "\n", 66 | "Warnings:\n", 67 | "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n" 68 | ] 69 | } 70 | ], 71 | "source": [ 72 | "#part a - estimate using OLS\n", 73 | "part_a = sm.OLS(y,x).fit()\n", 74 | "print part_a.summary()" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 4, 80 | "metadata": {}, 81 | "outputs": [ 82 | { 83 | "name": "stdout", 84 | "output_type": "stream", 85 | "text": [ 86 | "Optimization terminated successfully.\n", 87 | " Current function value: 0.725432\n", 88 | " Iterations: 69\n", 89 | " Function evaluations: 131\n", 90 | " part_b Results \n", 91 | "==============================================================================\n", 92 | "Dep. Variable: y Log-Likelihood: -362.72\n", 93 | "Model: part_b AIC: 727.4\n", 94 | "Method: Maximum Likelihood BIC: 731.6\n", 95 | "Date: Thu, 27 Sep 2018 \n", 96 | "Time: 17:53:52 \n", 97 | "No. Observations: 500 \n", 98 | "Df Residuals: 499 \n", 99 | "Df Model: 0 \n", 100 | "==============================================================================\n", 101 | " coef std err z P>|z| [0.025 0.975]\n", 102 | "------------------------------------------------------------------------------\n", 103 | "theta_1 0.0055 0.022 0.246 0.806 -0.038 0.049\n", 104 | "theta_2 1.0105 0.023 44.572 0.000 0.966 1.055\n", 105 | "sigma 0.4999 0.016 31.619 0.000 0.469 0.531\n", 106 | "==============================================================================\n" 107 | ] 108 | } 109 | ], 110 | "source": [ 111 | "#part b - MLE\n", 112 | "\n", 113 | "class part_b(GenericLikelihoodModel):\n", 114 | " \"\"\"class for evaluating question 1 part b\"\"\"\n", 115 | " \n", 116 | " def nloglikeobs(self, params):\n", 117 | " t1, t2, sigma = params\n", 118 | " endog, exog = self.endog, self.exog.squeeze()\n", 119 | " eps = endog - t1 - t2*exog\n", 120 | " return - norm(0,sigma).logpdf(eps).sum()\n", 121 | " \n", 122 | " \n", 123 | " def fit(self, start_params=None, maxiter=10000, maxfun=5000, **kwds):\n", 124 | " # we have one additional parameter and we need to add it for summary\n", 125 | " if start_params == None:\n", 126 | " start_params = start_params = [.5, .5,.5]\n", 127 | " return super(part_b, self).fit(start_params=start_params,\n", 128 | " maxiter=maxiter, maxfun=maxfun, **kwds)\n", 129 | "\n", 130 | " \n", 131 | "model_b = part_b(data1[0],data1[1])\n", 132 | "result_b = model_b.fit()\n", 133 | "print(result_b.summary(xname=['theta_1', 'theta_2', 'sigma']))\n", 134 | "\n", 135 | "\n", 136 | "#sources: \n", 137 | "#http://www.statsmodels.org/0.6.1/examples/notebooks/generated/generic_mle.html\n", 138 | "#http://rlhick.people.wm.edu/posts/estimating-custom-mle.html" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 5, 144 | "metadata": {}, 145 | "outputs": [ 146 | { 147 | "name": "stdout", 148 | "output_type": "stream", 149 | "text": [ 150 | "Optimization terminated successfully.\n", 151 | " Current function value: 0.000000\n", 152 | " Iterations: 37\n", 153 | " Function evaluations: 70\n", 154 | "Optimization terminated successfully.\n", 155 | " Current function value: 0.000000\n", 156 | " Iterations: 13\n", 157 | " Function evaluations: 26\n", 158 | " part_c Results \n", 159 | "==============================================================================\n", 160 | "Dep. Variable: y Hansen J: 1.288e-06\n", 161 | "Model: part_c Prob (Hansen J): nan\n", 162 | "Method: GMM \n", 163 | "Date: Thu, 27 Sep 2018 \n", 164 | "Time: 17:53:53 \n", 165 | "No. Observations: 500 \n", 166 | "==============================================================================\n", 167 | " coef std err z P>|z| [0.025 0.975]\n", 168 | "------------------------------------------------------------------------------\n", 169 | "theta_1 0.0055 0.022 0.248 0.804 -0.038 0.049\n", 170 | "theta_2 1.0104 0.022 45.052 0.000 0.966 1.054\n", 171 | "==============================================================================\n" 172 | ] 173 | } 174 | ], 175 | "source": [ 176 | "#part c - GMM\n", 177 | "\n", 178 | "class part_c(GMM):\n", 179 | " \"\"\"class for evaluating question 1 part c\"\"\"\n", 180 | " \n", 181 | " def __init__(self, *args, **kwds):\n", 182 | " # set appropriate counts for moment conditions and parameters\n", 183 | " kwds.setdefault('k_moms', 2)\n", 184 | " kwds.setdefault('k_params',2)\n", 185 | " super(part_c, self).__init__(*args, **kwds)\n", 186 | " \n", 187 | " \n", 188 | " def fit(self, start_params=None, maxiter=10000, **kwds):\n", 189 | " if start_params == None:\n", 190 | " start_params = np.array([.5, .5])\n", 191 | " return super(part_c, self).fit(start_params=start_params,\n", 192 | " maxiter=maxiter, **kwds)\n", 193 | " \n", 194 | " \n", 195 | " def momcond(self, params):\n", 196 | " t1,t2 = params #unwrap parameters\n", 197 | " endog, exog = self.endog, self.exog.squeeze()\n", 198 | " eps = endog - t1 - t2*exog \n", 199 | " g = np.column_stack( (eps, eps*exog ))\n", 200 | " return g \n", 201 | "\n", 202 | " \n", 203 | "model_c = part_c(data1[0],data1[1], None)\n", 204 | "result_c = model_c.fit(maxiter=2, optim_method='nm', wargs=dict(centered=False))\n", 205 | "print(result_c.summary(xname=['theta_1', 'theta_2']))\n", 206 | "\n", 207 | "\n", 208 | "#sources:\n", 209 | "#https://github.com/josef-pkt/misc/blob/master/notebooks/ex_gmm_gamma.ipynb\n", 210 | "#https://www.statsmodels.org/dev/generated/statsmodels.sandbox.regression.gmm.GMM.html#statsmodels.sandbox.regression.gmm.GMM\n", 211 | "#https://gist.github.com/josef-pkt/6895915" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": null, 217 | "metadata": {}, 218 | "outputs": [], 219 | "source": [] 220 | } 221 | ], 222 | "metadata": { 223 | "kernelspec": { 224 | "display_name": "Python 2", 225 | "language": "python", 226 | "name": "python2" 227 | }, 228 | "language_info": { 229 | "codemirror_mode": { 230 | "name": "ipython", 231 | "version": 2 232 | }, 233 | "file_extension": ".py", 234 | "mimetype": "text/x-python", 235 | "name": "python", 236 | "nbconvert_exporter": "python", 237 | "pygments_lexer": "ipython2", 238 | "version": "2.7.15" 239 | } 240 | }, 241 | "nbformat": 4, 242 | "nbformat_minor": 2 243 | } 244 | -------------------------------------------------------------------------------- /hw1/question2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 19, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pandas\n", 10 | "import math\n", 11 | "import numpy as np\n", 12 | "import matplotlib.pyplot as plt\n", 13 | "import statsmodels.api as sm\n", 14 | "from scipy.stats import norm\n", 15 | "from statsmodels.sandbox.regression.gmm import GMM\n", 16 | "from statsmodels.base.model import GenericLikelihoodModel" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 20, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "data2 = np.genfromtxt('data2.dat', delimiter=' ')\n", 26 | "data2 = data2.transpose()\n", 27 | "\n", 28 | "y = data2[0]\n", 29 | "x = sm.add_constant(data2[1])" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 21, 35 | "metadata": {}, 36 | "outputs": [ 37 | { 38 | "name": "stdout", 39 | "output_type": "stream", 40 | "text": [ 41 | "Optimization terminated successfully.\n", 42 | " Current function value: 1.381592\n", 43 | " Iterations: 202\n", 44 | " Function evaluations: 360\n", 45 | " part_b Results \n", 46 | "==============================================================================\n", 47 | "Dep. Variable: y Log-Likelihood: -138.16\n", 48 | "Model: part_b AIC: 278.3\n", 49 | "Method: Maximum Likelihood BIC: 280.9\n", 50 | "Date: Thu, 27 Sep 2018 \n", 51 | "Time: 17:35:31 \n", 52 | "No. Observations: 100 \n", 53 | "Df Residuals: 99 \n", 54 | "Df Model: 0 \n", 55 | "==============================================================================\n", 56 | " coef std err z P>|z| [0.025 0.975]\n", 57 | "------------------------------------------------------------------------------\n", 58 | "theta_1 3.0659 0.187 16.379 0.000 2.699 3.433\n", 59 | "theta_2 1.0272 0.229 4.490 0.000 0.579 1.476\n", 60 | "sigma 0.9633 0.068 14.142 0.000 0.830 1.097\n", 61 | "==============================================================================\n" 62 | ] 63 | } 64 | ], 65 | "source": [ 66 | "#part a - MLE\n", 67 | "\n", 68 | "\n", 69 | "class part_b(GenericLikelihoodModel):\n", 70 | " \"\"\"class for evaluating question 2 part a\"\"\"\n", 71 | " \n", 72 | " def nloglikeobs(self, params):\n", 73 | " t1, t2, sigma = params\n", 74 | " endog, exog = self.endog, self.exog.squeeze()\n", 75 | " eps = np.log(endog) - t1 - exog**t2\n", 76 | " #calculate log likelihood\n", 77 | " return -norm(0,sigma).logpdf(eps).sum()\n", 78 | "\n", 79 | " \n", 80 | " def fit(self, start_params=None, maxiter=10000, maxfun=5000, **kwds):\n", 81 | " if start_params == None:\n", 82 | " start_params = [.5, .5,.5]\n", 83 | " return super(part_b, self).fit(start_params=start_params,\n", 84 | " maxiter=maxiter, maxfun=maxfun, **kwds)\n", 85 | "\n", 86 | " \n", 87 | "model_b = part_b(data2[0],data2[1])\n", 88 | "result_b = model_b.fit()\n", 89 | "print(result_b.summary(xname=['theta_1', 'theta_2', 'sigma']))\n", 90 | "\n", 91 | "\n", 92 | "#sources (same as last time):\n", 93 | "#http://www.statsmodels.org/0.6.1/examples/notebooks/generated/generic_mle.html\n", 94 | "#http://rlhick.people.wm.edu/posts/estimating-custom-mle.html" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 22, 100 | "metadata": {}, 101 | "outputs": [ 102 | { 103 | "name": "stdout", 104 | "output_type": "stream", 105 | "text": [ 106 | "Optimization terminated successfully.\n", 107 | " Current function value: 0.000000\n", 108 | " Iterations: 61\n", 109 | " Function evaluations: 119\n", 110 | "Optimization terminated successfully.\n", 111 | " Current function value: 0.000000\n", 112 | " Iterations: 23\n", 113 | " Function evaluations: 46\n", 114 | " part_c Results \n", 115 | "==============================================================================\n", 116 | "Dep. Variable: y Hansen J: 1.456e-09\n", 117 | "Model: part_c Prob (Hansen J): nan\n", 118 | "Method: GMM \n", 119 | "Date: Thu, 27 Sep 2018 \n", 120 | "Time: 17:35:31 \n", 121 | "No. Observations: 100 \n", 122 | "==============================================================================\n", 123 | " coef std err z P>|z| [0.025 0.975]\n", 124 | "------------------------------------------------------------------------------\n", 125 | "theta_1 3.0574 0.186 16.425 0.000 2.693 3.422\n", 126 | "theta_2 1.0394 0.216 4.814 0.000 0.616 1.463\n", 127 | "==============================================================================\n" 128 | ] 129 | } 130 | ], 131 | "source": [ 132 | "#part c - GMM\n", 133 | "\n", 134 | "class part_c(GMM):\n", 135 | " \"\"\"class for evaluating question 2 part b\"\"\"\n", 136 | " \n", 137 | " def __init__(self, *args, **kwds):\n", 138 | " # set appropriate counts for moment conditions and parameters\n", 139 | " kwds.setdefault('k_moms', 2)\n", 140 | " kwds.setdefault('k_params',2)\n", 141 | " super(part_c, self).__init__(*args, **kwds)\n", 142 | " \n", 143 | " \n", 144 | " def fit(self, start_params=None, maxiter=10000, **kwds):\n", 145 | " if start_params == None:\n", 146 | " start_params = np.array([.5, .5])\n", 147 | " return super(part_c, self).fit(start_params=start_params,\n", 148 | " maxiter=maxiter, **kwds)\n", 149 | " \n", 150 | " \n", 151 | " def momcond(self, params):\n", 152 | " t1,t2 = params \n", 153 | " endog, exog = self.endog, self.exog.squeeze()\n", 154 | " #different model, essentially the same since its an injective mapping\n", 155 | " eps = np.log(endog) - t1 - exog**t2 \n", 156 | " g = np.column_stack( (eps, eps*exog ))\n", 157 | " return g \n", 158 | "\n", 159 | " \n", 160 | "model_c = part_c(data2[0],data2[1], None)\n", 161 | "result_c = model_c.fit(maxiter=2, optim_method='nm', wargs=dict(centered=False))\n", 162 | "print(result_c.summary(xname=['theta_1', 'theta_2']))\n", 163 | "\n", 164 | "\n", 165 | "#sources (same as last time):\n", 166 | "#https://github.com/josef-pkt/misc/blob/master/notebooks/ex_gmm_gamma.ipynb\n", 167 | "#https://www.statsmodels.org/dev/generated/statsmodels.sandbox.regression.gmm.GMM.html#statsmodels.sandbox.regression.gmm.GMM\n", 168 | "#https://gist.github.com/josef-pkt/6895915" 169 | ] 170 | }, 171 | { 172 | "cell_type": "code", 173 | "execution_count": null, 174 | "metadata": {}, 175 | "outputs": [], 176 | "source": [] 177 | } 178 | ], 179 | "metadata": { 180 | "kernelspec": { 181 | "display_name": "Python 2", 182 | "language": "python", 183 | "name": "python2" 184 | }, 185 | "language_info": { 186 | "codemirror_mode": { 187 | "name": "ipython", 188 | "version": 2 189 | }, 190 | "file_extension": ".py", 191 | "mimetype": "text/x-python", 192 | "name": "python", 193 | "nbconvert_exporter": "python", 194 | "pygments_lexer": "ipython2", 195 | "version": "2.7.15" 196 | } 197 | }, 198 | "nbformat": 4, 199 | "nbformat_minor": 2 200 | } 201 | -------------------------------------------------------------------------------- /hw1/question3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pandas\n", 10 | "import math\n", 11 | "import numpy as np\n", 12 | "import matplotlib.pyplot as plt\n", 13 | "import statsmodels.api as sm\n", 14 | "from scipy.stats import norm\n", 15 | "from statsmodels.sandbox.regression.gmm import GMM\n", 16 | "from statsmodels.base.model import GenericLikelihoodModel" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 3, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "#load data into memory\n", 26 | "data3 = np.genfromtxt('data3.dat', delimiter=' ')\n", 27 | "data3 = data3.transpose()\n", 28 | "\n", 29 | "#test to see if other data works\n", 30 | "drawsml = np.genfromtxt('drawsml.dat', delimiter=' ')\n", 31 | "drawsgmm = np.genfromtxt('drawsgmm.dat', delimiter=' ')" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 4, 37 | "metadata": {}, 38 | "outputs": [ 39 | { 40 | "name": "stdout", 41 | "output_type": "stream", 42 | "text": [ 43 | "Optimization terminated successfully.\n", 44 | " Current function value: -3.174360\n", 45 | " Iterations: 92\n", 46 | " Function evaluations: 166\n", 47 | " part_b Results \n", 48 | "==============================================================================\n", 49 | "Dep. Variable: y Log-Likelihood: 158.72\n", 50 | "Model: part_b AIC: -313.4\n", 51 | "Method: Maximum Likelihood BIC: -309.6\n", 52 | "Date: Fri, 28 Sep 2018 \n", 53 | "Time: 09:11:33 \n", 54 | "No. Observations: 50 \n", 55 | "Df Residuals: 48 \n", 56 | "Df Model: 1 \n", 57 | "==============================================================================\n", 58 | " coef std err z P>|z| [0.025 0.975]\n", 59 | "------------------------------------------------------------------------------\n", 60 | "theta_1 1.0034 0.006 154.754 0.000 0.991 1.016\n", 61 | "theta_2 1.0504 0.088 11.972 0.000 0.878 1.222\n", 62 | "sigma 0.0701 0.005 15.102 0.000 0.061 0.079\n", 63 | "==============================================================================\n" 64 | ] 65 | } 66 | ], 67 | "source": [ 68 | "def sim_ll(y,x1,x2,t1,t2,sigma,v=False):\n", 69 | " \"\"\"Simulate the log likelihood function by integrating out\"\"\"\n", 70 | " #hard coded draws\n", 71 | " eps1 = np.genfromtxt('drawsml.dat', delimiter=' ').transpose()\n", 72 | " sim_like = 0 \n", 73 | " #set up vectors for adding\n", 74 | " zeros = np.full(len(x1),.0001)\n", 75 | " const = np.full(len(x1), 100) \n", 76 | " \n", 77 | " #run simulations, to simulate likelihoods\n", 78 | " for s in range(len(eps1)): \n", 79 | " #calculate f inverse\n", 80 | " mc1 = np.exp(t1 + t2*x1 + sigma*eps1[s])\n", 81 | " safe_log1 = np.maximum( 3*y - const - mc1 ,zeros)\n", 82 | " f_inv = (np.log(safe_log1) - t1 - t2*x2)\n", 83 | " safe_f_inv = np.maximum( f_inv ,zeros)\n", 84 | " #calculate f prime\n", 85 | " f_prime = (3.0/sigma)*1/(3.0*y - const - mc1)\n", 86 | " sim_like = sim_like + norm(0,sigma).pdf(f_inv)*f_prime\n", 87 | " \n", 88 | " #finalized simulated likelihoods\n", 89 | " safe_sim = np.maximum(sim_like/len(eps1),zeros) \n", 90 | " return np.log(safe_sim).sum()\n", 91 | "\n", 92 | "\n", 93 | "class part_b(GenericLikelihoodModel):\n", 94 | " \"\"\"class for evaluating question 3 part b\"\"\"\n", 95 | " \n", 96 | " def nloglikeobs(self, params):\n", 97 | " t1, t2, sigma = params\n", 98 | " y = self.endog\n", 99 | " x1,x2 = self.exog.transpose()\n", 100 | " return -sim_ll(y, x1,x2,t1,t2,sigma)\n", 101 | "\n", 102 | " \n", 103 | " def fit(self, start_params=None, maxiter=100, maxfun=5000, **kwds):\n", 104 | " if start_params == None:\n", 105 | " start_params = np.array([1,1,1])\n", 106 | " return super(part_b, self).fit(start_params=start_params,\n", 107 | " maxiter=maxiter, maxfun=maxfun, **kwds)\n", 108 | "\n", 109 | " \n", 110 | "model_b = part_b(data3[0],data3[1:].transpose()).fit(start_params = [1,1,1])\n", 111 | "print(model_b.summary(xname=['theta_1','theta_2','sigma']))" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": 8, 117 | "metadata": {}, 118 | "outputs": [ 119 | { 120 | "name": "stdout", 121 | "output_type": "stream", 122 | "text": [ 123 | "Optimization terminated successfully.\n", 124 | " Current function value: 0.000000\n", 125 | " Iterations: 42\n", 126 | " Function evaluations: 84\n", 127 | " part_d Results \n", 128 | "==============================================================================\n", 129 | "Dep. Variable: y Hansen J: 1.552e-05\n", 130 | "Model: part_d Prob (Hansen J): 0.997\n", 131 | "Method: GMM \n", 132 | "Date: Fri, 28 Sep 2018 \n", 133 | "Time: 09:14:08 \n", 134 | "No. Observations: 50 \n", 135 | "==============================================================================\n", 136 | " coef std err z P>|z| [0.025 0.975]\n", 137 | "------------------------------------------------------------------------------\n", 138 | "theta_1 0.8812 0.025 34.668 0.000 0.831 0.931\n", 139 | "theta_2 0.2548 0.220 1.160 0.246 -0.176 0.685\n", 140 | "sigma 0.5424 0.036 14.964 0.000 0.471 0.613\n", 141 | "==============================================================================\n", 142 | "\n", 143 | "\n", 144 | "Optimization terminated successfully.\n", 145 | " Current function value: 0.000000\n", 146 | " Iterations: 42\n", 147 | " Function evaluations: 84\n", 148 | "Optimization terminated successfully.\n", 149 | " Current function value: 0.003829\n", 150 | " Iterations: 126\n", 151 | " Function evaluations: 214\n", 152 | " part_d Results \n", 153 | "==============================================================================\n", 154 | "Dep. Variable: y Hansen J: 0.1914\n", 155 | "Model: part_d Prob (Hansen J): 0.662\n", 156 | "Method: GMM \n", 157 | "Date: Fri, 28 Sep 2018 \n", 158 | "Time: 09:14:09 \n", 159 | "No. Observations: 50 \n", 160 | "==============================================================================\n", 161 | " coef std err z P>|z| [0.025 0.975]\n", 162 | "------------------------------------------------------------------------------\n", 163 | "theta_1 0.9953 0.010 97.539 0.000 0.975 1.015\n", 164 | "theta_2 1.1028 0.120 9.171 0.000 0.867 1.339\n", 165 | "sigma -0.1295 0.008 -16.948 0.000 -0.144 -0.115\n", 166 | "==============================================================================\n" 167 | ] 168 | } 169 | ], 170 | "source": [ 171 | "def sim_g(t1,t2,sigma,y,x1,x2,eps1,eps2):\n", 172 | " \"\"\"simulate moment conditions, given predetermined\n", 173 | " simulations\"\"\"\n", 174 | " g = 0\n", 175 | " for s in range(len(eps1)):\n", 176 | " y_hat = 1/3.0*(100 + np.exp(t1 + t2*x1 + sigma*eps1[s])\n", 177 | " + np.exp(t1 + t2*x2 + sigma*eps2[s]))\n", 178 | " g = g + (y - y_hat)\n", 179 | " \n", 180 | " return g/ (len(eps1)*len(eps2))\n", 181 | "\n", 182 | "\n", 183 | "def sim_g_sq(t1,t2,sigma,y,x1,x2,eps1,eps2):\n", 184 | " \"\"\"simulate square moment conditions, given predetermined\n", 185 | " simulations\"\"\"\n", 186 | " g = 0\n", 187 | " for s in range(len(eps1)):\n", 188 | " y_hat = 1/3.0*(100 + np.exp(t1 + t2*x1 + sigma*eps1[s])\n", 189 | " + np.exp(t1 + t2*x2 + sigma*eps2[s]))\n", 190 | " g = g + (y**2-y_hat**2)\n", 191 | " return g/(len(eps1)*len(eps2))\n", 192 | "\n", 193 | "\n", 194 | "class part_d(GMM):\n", 195 | " \"\"\"class for evaluating question 3 part d\"\"\"\n", 196 | "\n", 197 | " def __init__(self, *args, **kwds):\n", 198 | " \"\"\"set appropriate counts for moment conditions and parameters\"\"\"\n", 199 | " kwds.setdefault('k_moms', 4)\n", 200 | " kwds.setdefault('k_params',3)\n", 201 | " super(part_d, self).__init__(*args, **kwds)\n", 202 | " \n", 203 | " \n", 204 | " def fit(self, start_params=None, maxiter=10000, **kwds):\n", 205 | " if start_params == None:\n", 206 | " start_params = np.array([.5, .5, .5])\n", 207 | " return super(part_d, self).fit(start_params=start_params,\n", 208 | " maxiter=maxiter, **kwds)\n", 209 | "\n", 210 | " \n", 211 | " def momcond(self, params):\n", 212 | " t1,t2, sigma = params \n", 213 | " y = self.endog\n", 214 | " x1,x2 = self.exog.transpose() \n", 215 | " \n", 216 | " #initialize draws\n", 217 | " eps = np.genfromtxt('drawsgmm.dat', delimiter=' ').transpose()\n", 218 | " eps1 = eps[0:len(eps)/2]\n", 219 | " eps2 = eps[len(eps)/2:len(eps)]\n", 220 | " \n", 221 | " #calc moment conditions\n", 222 | " g = sim_g(t1,t2,sigma,y,x1,x2,eps1,eps2)\n", 223 | " g_sq = sim_g_sq(t1,t2,sigma,y,x1,x2,eps1,eps2)\n", 224 | " return np.column_stack((g,g*x1,g*x2,g_sq))\n", 225 | "\n", 226 | "\n", 227 | "model_d = part_d(data3[0],data3[1:].transpose(), None)\n", 228 | "\n", 229 | "\n", 230 | "#print first iteration (i.e. 1 stage)\n", 231 | "result_d_stage1 = model_d.fit(maxiter=1, optim_method='nm', wargs=dict(centered=False))\n", 232 | "print(result_d_stage1.summary(xname=['theta_1','theta_2','sigma']))\n", 233 | "print('\\n')\n", 234 | "\n", 235 | "\n", 236 | "#print second iteration (i.e. 2 stage)\n", 237 | "result_d_stage2 = model_d.fit(maxiter=2, optim_method='nm', wargs=dict(centered=False))\n", 238 | "print(result_d_stage2.summary(xname=['theta_1','theta_2','sigma']))" 239 | ] 240 | }, 241 | { 242 | "cell_type": "code", 243 | "execution_count": null, 244 | "metadata": {}, 245 | "outputs": [], 246 | "source": [] 247 | } 248 | ], 249 | "metadata": { 250 | "kernelspec": { 251 | "display_name": "Python 2", 252 | "language": "python", 253 | "name": "python2" 254 | }, 255 | "language_info": { 256 | "codemirror_mode": { 257 | "name": "ipython", 258 | "version": 2 259 | }, 260 | "file_extension": ".py", 261 | "mimetype": "text/x-python", 262 | "name": "python", 263 | "nbconvert_exporter": "python", 264 | "pygments_lexer": "ipython2", 265 | "version": "2.7.15" 266 | } 267 | }, 268 | "nbformat": 4, 269 | "nbformat_minor": 2 270 | } 271 | -------------------------------------------------------------------------------- /hw1_io/nest_logit.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pandas as pd\n", 10 | "import math\n", 11 | "import numpy as np\n", 12 | "import matplotlib.pyplot as plt\n", 13 | "import statsmodels.api as sm\n", 14 | "from scipy.stats import norm\n", 15 | "from statsmodels.sandbox.regression.gmm import GMM\n", 16 | "from statsmodels.base.model import GenericLikelihoodModel" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 2, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "def comp_outside_good(data,name):\n", 26 | " \"\"\"pre-processing to calculate outside good shares\"\"\"\n", 27 | " shares = data[['Market_ID',name,'PPO']].copy()\n", 28 | "\n", 29 | " group_shares = shares.groupby('Market_ID').sum()\n", 30 | " group_shares['Outside Good Share'] = 1 - group_shares[name]\n", 31 | "\n", 32 | " data = pd.merge(data,group_shares[['Outside Good Share']], \n", 33 | " right_index=True, left_on = 'Market_ID')\n", 34 | " return data\n", 35 | "\n", 36 | "\n", 37 | "def comp_nest_shares(x,name):\n", 38 | " \"\"\"calculate shares within nest\"\"\"\n", 39 | " nest_x = x[['Market_ID',name,'PPO']].copy()\n", 40 | " nest_x['ppo_share'] = nest_x[name] * nest_x['PPO']\n", 41 | " nest_x['hmo_share'] = nest_x[name] * (1 - nest_x['PPO'])\n", 42 | " \n", 43 | " group_shares = nest_x.groupby('Market_ID').sum()\n", 44 | " \n", 45 | " x = pd.merge(x, group_shares[['hmo_share','ppo_share']], right_index=True,\n", 46 | " left_on = 'Market_ID')\n", 47 | " \n", 48 | " x['nest_size'] = x['PPO'] * x['ppo_share'] + (1 - x['PPO']) * x['hmo_share']\n", 49 | " x = x.drop(labels=['ppo_share','hmo_share'],axis=1)\n", 50 | " return x\n", 51 | "\n", 52 | "\n", 53 | "data = pd.read_csv('data.csv')\n", 54 | "data = comp_outside_good(data,'Inside Good Share')\n", 55 | "data = comp_nest_shares(data,'Inside Good Share')\n", 56 | "data['ln(Within Nest Share)'] = np.log( data['Inside Good Share']/data['nest_size'] )" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": 3, 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "#first estimate using logit\n", 66 | "class logit(GMM):\n", 67 | " \n", 68 | " def __init__(self, *args, **kwds):\n", 69 | " # set appropriate counts for moment conditions and parameters\n", 70 | " super(logit, self).__init__(*args, **kwds)\n", 71 | "\n", 72 | " \n", 73 | " def momcond(self, params):\n", 74 | " #unwrap stuff\n", 75 | " shares = np.array(self.endog).transpose()\n", 76 | " exog = np.array(self.exog)\n", 77 | " instr = np.array(self.instrument)\n", 78 | " \n", 79 | " lshare = np.log(shares[0]) - np.log(shares[1])\n", 80 | " lshare = lshare.transpose()\n", 81 | " \n", 82 | " lshare_fit = np.matmul(exog,params) #linear equation \n", 83 | " \n", 84 | " xi = lshare_fit - lshare\n", 85 | " g = instr * xi[:, np.newaxis]\n", 86 | " \n", 87 | " return g" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "# Question 1 - Estimate the Model" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 4, 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [ 103 | "#calculate hausmann insturments\n", 104 | "plan_dum = pd.get_dummies(data['Plan_ID'], prefix='plan',drop_first=True)\n", 105 | "mkt_dum = pd.get_dummies(data['Market_ID'], prefix='plan',drop_first=True)\n", 106 | "#hausman_instr = pd.concat( [data[['Network Score','Satisfaction Score','PPO']],\n", 107 | "# mkt_dum],axis=1)\n", 108 | "\n", 109 | "hausman_instr = plan_dum\n", 110 | "\n", 111 | "#set up data for logit\n", 112 | "y = data[['Inside Good Share','Outside Good Share']]\n", 113 | "\n", 114 | "# add ln(inside good share) as regressor like formula\n", 115 | "x_nested = data[['Network Score','Satisfaction Score','PPO',\n", 116 | " 'Premium','ln(Within Nest Share)']]" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "metadata": {}, 122 | "source": [ 123 | "I use dummy variables for the plan as my instrument. When regressing these dummy variables on plan, my model has the form \n", 124 | "\n", 125 | "$$p_{jm} = p_j + \\epsilon_{jm}$$ \n", 126 | "\n", 127 | "as is standard where $\\epsilon_{jm}$ is a market specific shock for product $j$. I estimated a model with the other exogeneous characteristics (i.e. Network score, Satisfaction, PPO) in the instrument. However, the model coefficients where similar, so for simplicitiy I just use the dummy variables.\n", 128 | "\n", 129 | "\n", 130 | "Additionally, I agrue these dummies are also valid instruments for nest share\n", 131 | "\n", 132 | "$$ln(s_{jm|g}) = ln(s_{j|g}) + \\epsilon_{jm}$$\n", 133 | "\n", 134 | "It is plausible that average nested share accross markets will be exogenous from the share in any given market. This would true if roughly the same proportion of consumers prefer plan $j$ in each market (for its exogenous characteristics), but the plans available in each market are differ(as is the case)" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 5, 140 | "metadata": {}, 141 | "outputs": [ 142 | { 143 | "name": "stdout", 144 | "output_type": "stream", 145 | "text": [ 146 | "Optimization terminated successfully.\n", 147 | " Current function value: 0.000006\n", 148 | " Iterations: 571\n", 149 | " Function evaluations: 928\n", 150 | "Optimization terminated successfully.\n", 151 | " Current function value: 0.005680\n", 152 | " Iterations: 235\n", 153 | " Function evaluations: 380\n", 154 | " logit Results \n", 155 | "=======================================================================================================\n", 156 | "Dep. Variable: ['Inside Good Share', 'Outside Good Share'] Hansen J: 18.74\n", 157 | "Model: logit Prob (Hansen J): 0.0437\n", 158 | "Method: GMM \n", 159 | "Date: Sun, 14 Oct 2018 \n", 160 | "Time: 12:46:55 \n", 161 | "No. Observations: 3300 \n", 162 | "=========================================================================================\n", 163 | " coef std err z P>|z| [0.025 0.975]\n", 164 | "-----------------------------------------------------------------------------------------\n", 165 | "Network Score 2.2683 0.360 6.304 0.000 1.563 2.974\n", 166 | "Satisfaction Score 1.1985 0.228 5.266 0.000 0.752 1.645\n", 167 | "PPO 0.6065 0.059 10.220 0.000 0.490 0.723\n", 168 | "Premium -1.0951 0.270 -4.059 0.000 -1.624 -0.566\n", 169 | "ln(Within Nest Share) 0.4254 0.123 3.466 0.001 0.185 0.666\n", 170 | "=========================================================================================\n" 171 | ] 172 | } 173 | ], 174 | "source": [ 175 | "#set up and run model\n", 176 | "beta_nested = np.full(len(x_nested.columns),1)\n", 177 | "model = logit(y , x_nested, hausman_instr)\n", 178 | "result = model.fit(beta_nested, maxiter=2, optim_method='nm',\n", 179 | " wargs=dict(centered=False))\n", 180 | "\n", 181 | "print(result.summary())" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 6, 187 | "metadata": {}, 188 | "outputs": [], 189 | "source": [ 190 | "#calc unobservables\n", 191 | "data['Xi'] = (np.log(y['Inside Good Share']) - np.log(y['Outside Good Share']) \n", 192 | " - np.matmul(np.array(x_nested),result.params))" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": 7, 198 | "metadata": {}, 199 | "outputs": [], 200 | "source": [ 201 | "#compute market shares\n", 202 | "\n", 203 | "def comp_shares(x,beta,sigma):\n", 204 | " x = x.copy()\n", 205 | " characs = np.array(x[['Network Score','Satisfaction Score','PPO','Premium']])\n", 206 | " x['exp_delta'] = np.exp(( np.matmul(characs,beta) +x['Xi'])/(1-sigma))\n", 207 | " \n", 208 | " #compute Dg = sum_j|g exp(delta_j)\n", 209 | " shares = x[['Market_ID','exp_delta','PPO']].copy()\n", 210 | " shares['PPO_delta'] = x['exp_delta'] * x['PPO']\n", 211 | " shares['HMO_delta'] = x['exp_delta'] * (1 - x['PPO'])\n", 212 | " \n", 213 | " group_shares = shares.groupby('Market_ID').sum()\n", 214 | " group_shares['PP0_delta_sigma'] = group_shares['PPO_delta']**(sigma)\n", 215 | " group_shares['HMO_delta_sigma'] = group_shares['HMO_delta']**(sigma)\n", 216 | " group_shares['sum_g'] = (group_shares['PPO_delta']**(1-sigma) \n", 217 | " + group_shares['HMO_delta']**(1-sigma) + 1)\n", 218 | " \n", 219 | " x = pd.merge(x,group_shares[['PPO_delta','HMO_delta','PP0_delta_sigma','sum_g']], \n", 220 | " right_index=True, left_on = 'Market_ID')\n", 221 | "\n", 222 | " #compute sum_g Dg^(1-sigma)\n", 223 | " x['denom'] = ( (1 - x['PPO'])*x['HMO_delta']**sigma + \n", 224 | " x['PPO']*x['PPO_delta']**sigma) * (x['sum_g'])\n", 225 | " x['fitted_share'] = x['exp_delta']/x['denom']\n", 226 | " return x[['Market_ID','Plan_ID','PPO','fitted_share']]" 227 | ] 228 | }, 229 | { 230 | "cell_type": "code", 231 | "execution_count": 8, 232 | "metadata": {}, 233 | "outputs": [], 234 | "source": [ 235 | "#initialize parameters and compute fitted shares\n", 236 | "characs = data[['Market_ID','Plan_ID','Network Score',\n", 237 | " 'Satisfaction Score','PPO','Premium','Xi']]\n", 238 | "beta = result.params[:-1]\n", 239 | "alpha = abs(beta[3])\n", 240 | "sigma = abs(result.params[-1])\n", 241 | "\n", 242 | "fitted_shares = comp_shares(characs,beta,sigma)" 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": 9, 248 | "metadata": {}, 249 | "outputs": [], 250 | "source": [ 251 | "#compute total share of each nest\n", 252 | "fitted_shares = comp_nest_shares(fitted_shares,'fitted_share')\n", 253 | "fitted_shares['nest_shares'] = (fitted_shares['fitted_share']/\n", 254 | " fitted_shares['nest_size'])" 255 | ] 256 | }, 257 | { 258 | "cell_type": "markdown", 259 | "metadata": {}, 260 | "source": [ 261 | "Characteristics of the fitted shares" 262 | ] 263 | }, 264 | { 265 | "cell_type": "code", 266 | "execution_count": 10, 267 | "metadata": {}, 268 | "outputs": [ 269 | { 270 | "name": "stdout", 271 | "output_type": "stream", 272 | "text": [ 273 | "Mean: 0.155440963636\n", 274 | "Max: 0.35561000000000004\n", 275 | "Min: 0.03767\n" 276 | ] 277 | } 278 | ], 279 | "source": [ 280 | "print 'Mean: %s'%fitted_shares['fitted_share'].mean()\n", 281 | "print 'Max: %s'%fitted_shares['fitted_share'].max()\n", 282 | "print 'Min: %s'%fitted_shares['fitted_share'].min()" 283 | ] 284 | }, 285 | { 286 | "cell_type": "markdown", 287 | "metadata": {}, 288 | "source": [ 289 | "# Question 2 - Compute Elasticities, Markups" 290 | ] 291 | }, 292 | { 293 | "cell_type": "markdown", 294 | "metadata": {}, 295 | "source": [ 296 | "## Elasticities\n", 297 | "\n", 298 | "Below are the formulas for the elasticities in the Nested logit\n", 299 | "\n", 300 | "Own Price: $$-\\alpha p_{jm} ( \\dfrac{1}{1-\\sigma} - \\dfrac{1}{1-\\sigma}s_{jm|g} -s_{jm} ) $$\n", 301 | "Cross Prices Same Nest (good $j$, price $k$): $$\\alpha \\dfrac{p_{km}}{s_{jm}} s_{km} (\\dfrac{\\sigma}{1-\\sigma}s_{jm|g} + s_{jm} )$$\n", 302 | "Cross Prices Different Nest (good $j$, price $k$): $$-\\alpha s_{km} p_{km}$$" 303 | ] 304 | }, 305 | { 306 | "cell_type": "code", 307 | "execution_count": 17, 308 | "metadata": {}, 309 | "outputs": [], 310 | "source": [ 311 | "#aggregate elasticities\n", 312 | "fitted_shares['Premium'] = data['Premium']\n", 313 | "\n", 314 | "fitted_shares = fitted_shares.groupby('Plan_ID').mean()\n", 315 | "\n", 316 | "#diagonal formula\n", 317 | "nest_shares = np.array(fitted_shares['nest_shares'])\n", 318 | "shares = np.array(fitted_shares['fitted_share'])\n", 319 | "prices = np.array(fitted_shares['Premium'])\n", 320 | "ppo = np.array([fitted_shares['PPO']]) #this one is a matrix\n", 321 | "\n", 322 | "#selector matrices\n", 323 | "own_price = np.identity(len(shares))\n", 324 | "inside_nest = (np.matmul(ppo.transpose(),ppo) + \n", 325 | " np.matmul((1-ppo.transpose()),(1-ppo)) - own_price)\n", 326 | "outside_nest = (1 - inside_nest) - own_price\n", 327 | "\n", 328 | "\n", 329 | "#elasticity variables\n", 330 | "inside_elasticity = np.matmul( np.array( [ (sigma/(1-sigma)* nest_shares\n", 331 | " + shares)/shares ] ).transpose(),\n", 332 | " np.array([alpha*prices*shares]))\n", 333 | "\n", 334 | "own_elasticity = -alpha*((1/(1-sigma)) - sigma/(1-sigma) * \n", 335 | " nest_shares - shares)*prices\n", 336 | "\n", 337 | "outside_elasticity = shares * alpha * prices\n", 338 | "\n", 339 | "nest_elasticity = (own_price*own_elasticity + \n", 340 | " inside_nest*inside_elasticity + \n", 341 | " outside_nest*outside_elasticity)" 342 | ] 343 | }, 344 | { 345 | "cell_type": "markdown", 346 | "metadata": {}, 347 | "source": [ 348 | "Below are the elasticities from the nested logit. Note that the indexing starts at 0" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": 18, 354 | "metadata": { 355 | "scrolled": false 356 | }, 357 | "outputs": [ 358 | { 359 | "name": "stdout", 360 | "output_type": "stream", 361 | "text": [ 362 | " 0 1 2 3 4 5 6 \\\n", 363 | "0 -3.614758 0.289348 1.427780 1.066116 0.301170 0.388905 1.310656 \n", 364 | "1 0.553277 -3.625294 0.596565 0.445453 0.907179 1.171454 0.547628 \n", 365 | "2 1.326098 0.289348 -3.540520 1.067664 0.301170 0.388905 1.312559 \n", 366 | "3 1.387476 0.289348 1.496032 -3.694212 0.301170 0.388905 1.373310 \n", 367 | "4 0.553277 0.888736 0.596565 0.445453 -3.534876 1.194525 0.547628 \n", 368 | "5 0.553277 0.843088 0.596565 0.445453 0.877533 -3.356309 0.547628 \n", 369 | "6 1.335440 0.289348 1.439925 1.075185 0.301170 0.388905 -3.624992 \n", 370 | "7 0.553277 0.871988 0.596565 0.445453 0.907614 1.172015 0.547628 \n", 371 | "8 1.360937 0.289348 1.467417 1.095713 0.301170 0.388905 1.347042 \n", 372 | "9 0.553277 0.910438 0.596565 0.445453 0.947634 1.223694 0.547628 \n", 373 | "10 0.553277 0.875027 0.596565 0.445453 0.910777 1.176100 0.547628 \n", 374 | "11 1.336768 0.289348 1.441356 1.076254 0.301170 0.388905 1.323119 \n", 375 | "12 1.440995 0.289348 1.553738 1.160169 0.301170 0.388905 1.426282 \n", 376 | "13 0.553277 0.867251 0.596565 0.445453 0.902683 1.165648 0.547628 \n", 377 | "14 1.335680 0.289348 1.440183 1.075378 0.301170 0.388905 1.322042 \n", 378 | "15 0.553277 0.847084 0.596565 0.445453 0.881692 1.138542 0.547628 \n", 379 | "\n", 380 | " 7 8 9 10 11 12 13 \\\n", 381 | "0 0.404680 1.077531 0.236349 0.316133 1.294680 0.977441 0.361846 \n", 382 | "1 1.218973 0.450222 0.711927 0.952252 0.540953 0.408402 1.089947 \n", 383 | "2 0.404680 1.079095 0.236349 0.316133 1.296559 0.978860 0.361846 \n", 384 | "3 0.404680 1.129040 0.236349 0.316133 1.356570 1.024166 0.361846 \n", 385 | "4 1.242980 0.450222 0.725948 0.971006 0.540953 0.408402 1.111413 \n", 386 | "5 1.179138 0.450222 0.688662 0.921133 0.540953 0.408402 1.054328 \n", 387 | "6 0.404680 1.086697 0.236349 0.316133 1.305693 0.985755 0.361846 \n", 388 | "7 -3.373637 0.450222 0.712268 0.952708 0.540953 0.408402 1.090469 \n", 389 | "8 0.404680 -3.717100 0.236349 0.316133 1.330622 1.004576 0.361846 \n", 390 | "9 1.273332 0.450222 -3.711404 0.994717 0.540953 0.408402 1.138553 \n", 391 | "10 1.223807 0.450222 0.714751 -3.474018 0.540953 0.408402 1.094270 \n", 392 | "11 0.404680 1.087777 0.236349 0.316133 -3.649444 0.986735 0.361846 \n", 393 | "12 0.404680 1.172591 0.236349 0.316133 1.408896 -3.741786 0.361846 \n", 394 | "13 1.212931 0.450222 0.708399 0.947533 0.540953 0.408402 -3.510241 \n", 395 | "14 0.404680 1.086892 0.236349 0.316133 1.305927 0.985932 0.361846 \n", 396 | "15 1.184726 0.450222 0.691926 0.925499 0.540953 0.408402 1.059325 \n", 397 | "\n", 398 | " 14 15 \n", 399 | "0 1.420186 0.362297 \n", 400 | "1 0.593393 1.091306 \n", 401 | "2 1.422248 0.362297 \n", 402 | "3 1.488075 0.362297 \n", 403 | "4 0.593393 1.112798 \n", 404 | "5 0.593393 1.055642 \n", 405 | "6 1.432266 0.362297 \n", 406 | "7 0.593393 1.091828 \n", 407 | "8 1.459612 0.362297 \n", 408 | "9 0.593393 1.139972 \n", 409 | "10 0.593393 1.095633 \n", 410 | "11 1.433691 0.362297 \n", 411 | "12 1.545474 0.362297 \n", 412 | "13 0.593393 1.085897 \n", 413 | "14 -3.516016 0.362297 \n", 414 | "15 0.593393 -3.448638 \n" 415 | ] 416 | } 417 | ], 418 | "source": [ 419 | "print pd.DataFrame(nest_elasticity)" 420 | ] 421 | }, 422 | { 423 | "cell_type": "markdown", 424 | "metadata": {}, 425 | "source": [ 426 | "We can see the elasticities fall relative to the simple logit within the nest, this is because you are restricted to buying within the nest. Conversely, the between nest elasticities go up." 427 | ] 428 | }, 429 | { 430 | "cell_type": "markdown", 431 | "metadata": {}, 432 | "source": [ 433 | "## Markups" 434 | ] 435 | }, 436 | { 437 | "cell_type": "code", 438 | "execution_count": 13, 439 | "metadata": {}, 440 | "outputs": [ 441 | { 442 | "name": "stdout", 443 | "output_type": "stream", 444 | "text": [ 445 | " Markup\n", 446 | "Plan_ID \n", 447 | "1 0.731614\n", 448 | "2 0.660008\n", 449 | "3 0.755827\n", 450 | "4 0.699635\n", 451 | "5 0.675452\n", 452 | "6 0.717732\n", 453 | "7 0.735489\n", 454 | "8 0.729162\n", 455 | "9 0.696208\n", 456 | "10 0.639947\n", 457 | "11 0.682427\n", 458 | "12 0.730343\n", 459 | "13 0.695612\n", 460 | "14 0.699386\n", 461 | "15 0.761726\n", 462 | "16 0.698719\n" 463 | ] 464 | } 465 | ], 466 | "source": [ 467 | "#solve for marginal costs\n", 468 | "def comp_markup(shares,nest_shares):\n", 469 | " shares_vector = np.array([shares])\n", 470 | " \n", 471 | " #set up matrix \n", 472 | " own_price = np.identity(len(shares))\n", 473 | "\n", 474 | " #caclulate formula\n", 475 | " own_deriv = -alpha*((1/(1-sigma)) - sigma/(1-sigma) * nest_shares\n", 476 | " - shares)*shares\n", 477 | " \n", 478 | " derivative = own_price *own_deriv\n", 479 | " #take inverse and calc markup\n", 480 | " inv_derivative = np.linalg.inv(derivative)\n", 481 | "\n", 482 | " markup = - np.matmul(inv_derivative, shares_vector.transpose()) \n", 483 | " return markup.transpose()[0]\n", 484 | "\n", 485 | "\n", 486 | "\n", 487 | "fitted_shares = comp_shares(characs,beta,sigma)\n", 488 | "fitted_shares = comp_nest_shares(fitted_shares,'fitted_share')\n", 489 | "fitted_shares['nest_shares'] = fitted_shares['fitted_share']/fitted_shares['nest_size']\n", 490 | "\n", 491 | "nest_shares = np.array(fitted_shares['nest_shares']).squeeze()\n", 492 | "shares = np.array(fitted_shares['fitted_share']).squeeze()\n", 493 | "prices = np.array(data['Premium']).squeeze()\n", 494 | "\n", 495 | "data['Markup'] = comp_markup(shares,nest_shares)\n", 496 | "print data[['Plan_ID','Markup']].groupby('Plan_ID').mean()" 497 | ] 498 | }, 499 | { 500 | "cell_type": "markdown", 501 | "metadata": {}, 502 | "source": [ 503 | "Overall the markups are higher than with the pure logit model. This is because there is less competition within the nest." 504 | ] 505 | }, 506 | { 507 | "cell_type": "code", 508 | "execution_count": 16, 509 | "metadata": {}, 510 | "outputs": [ 511 | { 512 | "name": "stdout", 513 | "output_type": "stream", 514 | "text": [ 515 | " OLS Regression Results \n", 516 | "==============================================================================\n", 517 | "Dep. Variable: Markup R-squared: 0.749\n", 518 | "Model: OLS Adj. R-squared: 0.749\n", 519 | "Method: Least Squares F-statistic: 1784.\n", 520 | "Date: Sun, 14 Oct 2018 Prob (F-statistic): 1.30e-181\n", 521 | "Time: 12:51:22 Log-Likelihood: 906.08\n", 522 | "No. Observations: 600 AIC: -1808.\n", 523 | "Df Residuals: 598 BIC: -1799.\n", 524 | "Df Model: 1 \n", 525 | "Covariance Type: nonrobust \n", 526 | "==============================================================================\n", 527 | " coef std err t P>|t| [0.025 0.975]\n", 528 | "------------------------------------------------------------------------------\n", 529 | "const 1.0326 0.007 140.103 0.000 1.018 1.047\n", 530 | "Plan_ID -0.0541 0.001 -42.235 0.000 -0.057 -0.052\n", 531 | "==============================================================================\n", 532 | "Omnibus: 9.600 Durbin-Watson: 1.259\n", 533 | "Prob(Omnibus): 0.008 Jarque-Bera (JB): 15.364\n", 534 | "Skew: 0.045 Prob(JB): 0.000461\n", 535 | "Kurtosis: 3.779 Cond. No. 20.0\n", 536 | "==============================================================================\n", 537 | "\n", 538 | "Warnings:\n", 539 | "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n" 540 | ] 541 | } 542 | ], 543 | "source": [ 544 | "mean_markup = data[['Market_ID','Markup']].groupby('Market_ID').mean()\n", 545 | "no_firms = data[['Market_ID','Plan_ID']].groupby('Market_ID').count()\n", 546 | "\n", 547 | "\n", 548 | "model_q2 = sm.OLS(mean_markup,sm.add_constant(no_firms))\n", 549 | "result_q2 = model_q2.fit()\n", 550 | "print result_q2.summary()" 551 | ] 552 | }, 553 | { 554 | "cell_type": "markdown", 555 | "metadata": {}, 556 | "source": [ 557 | "As we can see the Markup is decreasing in the number of firms in the market" 558 | ] 559 | }, 560 | { 561 | "cell_type": "markdown", 562 | "metadata": {}, 563 | "source": [ 564 | "# Question 3 - Marginal Costs against Plan Characteristics" 565 | ] 566 | }, 567 | { 568 | "cell_type": "code", 569 | "execution_count": 15, 570 | "metadata": {}, 571 | "outputs": [ 572 | { 573 | "name": "stdout", 574 | "output_type": "stream", 575 | "text": [ 576 | " OLS Regression Results \n", 577 | "==============================================================================\n", 578 | "Dep. Variable: y R-squared: 0.383\n", 579 | "Model: OLS Adj. R-squared: 0.383\n", 580 | "Method: Least Squares F-statistic: 682.2\n", 581 | "Date: Sun, 14 Oct 2018 Prob (F-statistic): 0.00\n", 582 | "Time: 12:47:03 Log-Likelihood: 2672.2\n", 583 | "No. Observations: 3300 AIC: -5336.\n", 584 | "Df Residuals: 3296 BIC: -5312.\n", 585 | "Df Model: 3 \n", 586 | "Covariance Type: nonrobust \n", 587 | "======================================================================================\n", 588 | " coef std err t P>|t| [0.025 0.975]\n", 589 | "--------------------------------------------------------------------------------------\n", 590 | "const 1.5074 0.043 35.090 0.000 1.423 1.592\n", 591 | "Network Score 0.2681 0.065 4.100 0.000 0.140 0.396\n", 592 | "Satisfaction Score -0.0785 0.047 -1.653 0.098 -0.172 0.015\n", 593 | "PPO 0.1708 0.004 44.940 0.000 0.163 0.178\n", 594 | "==============================================================================\n", 595 | "Omnibus: 1573.922 Durbin-Watson: 1.746\n", 596 | "Prob(Omnibus): 0.000 Jarque-Bera (JB): 12671.486\n", 597 | "Skew: -2.104 Prob(JB): 0.00\n", 598 | "Kurtosis: 11.628 Cond. No. 69.6\n", 599 | "==============================================================================\n", 600 | "\n", 601 | "Warnings:\n", 602 | "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n" 603 | ] 604 | } 605 | ], 606 | "source": [ 607 | "model_q3 = sm.OLS(data['Premium'] - data['Markup'], \n", 608 | " sm.add_constant(data[['Network Score','Satisfaction Score','PPO']]))\n", 609 | "result_q3 = model_q3.fit()\n", 610 | "print result_q3.summary()" 611 | ] 612 | } 613 | ], 614 | "metadata": { 615 | "kernelspec": { 616 | "display_name": "Python 2", 617 | "language": "python", 618 | "name": "python2" 619 | }, 620 | "language_info": { 621 | "codemirror_mode": { 622 | "name": "ipython", 623 | "version": 2 624 | }, 625 | "file_extension": ".py", 626 | "mimetype": "text/x-python", 627 | "name": "python", 628 | "nbconvert_exporter": "python", 629 | "pygments_lexer": "ipython2", 630 | "version": "2.7.15" 631 | } 632 | }, 633 | "nbformat": 4, 634 | "nbformat_minor": 2 635 | } 636 | -------------------------------------------------------------------------------- /hw2/388E_ps2_2018.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ericschulman/struct/260ee95ac8e364bc49d9bb54b484f138759ba904/hw2/388E_ps2_2018.pdf -------------------------------------------------------------------------------- /hw2/question1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Assignment 2 Structural Econometrics: Question 1\n", 8 | "## November 9, 2018 \n", 9 | "## Eric Schulman " 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 21, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import pandas as pd\n", 19 | "import math\n", 20 | "import numpy as np\n", 21 | "import matplotlib.pyplot as plt\n", 22 | "import statsmodels.api as sm\n", 23 | "from scipy.stats import norm\n", 24 | "from statsmodels.sandbox.regression.gmm import GMM\n", 25 | "from statsmodels.base.model import GenericLikelihoodModel" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 28, 31 | "metadata": {}, 32 | "outputs": [ 33 | { 34 | "name": "stdout", 35 | "output_type": "stream", 36 | "text": [ 37 | "y 0.568393\n", 38 | "x1 42.537849\n", 39 | "x2 12.286853\n", 40 | "z 9.029880\n", 41 | "dtype: float64\n" 42 | ] 43 | } 44 | ], 45 | "source": [ 46 | "#load data into memory\n", 47 | "data = pd.DataFrame(data = np.genfromtxt('ps2.dat', delimiter=' '), columns=['y','x1','x2','z'])\n", 48 | "\n", 49 | "#summary statistics\n", 50 | "print data.mean()" 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": {}, 56 | "source": [ 57 | "### Part a" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 32, 63 | "metadata": {}, 64 | "outputs": [ 65 | { 66 | "name": "stdout", 67 | "output_type": "stream", 68 | "text": [ 69 | "Optimization terminated successfully.\n", 70 | " Current function value: 0.664055\n", 71 | " Iterations 4\n", 72 | " Probit Regression Results \n", 73 | "==============================================================================\n", 74 | "Dep. Variable: y No. Observations: 753\n", 75 | "Model: Probit Df Residuals: 750\n", 76 | "Method: MLE Df Model: 2\n", 77 | "Date: Fri, 19 Oct 2018 Pseudo R-squ.: 0.02882\n", 78 | "Time: 19:08:07 Log-Likelihood: -500.03\n", 79 | "converged: True LL-Null: -514.87\n", 80 | " LLR p-value: 3.590e-07\n", 81 | "==============================================================================\n", 82 | " coef std err z P>|z| [0.025 0.975]\n", 83 | "------------------------------------------------------------------------------\n", 84 | "const -0.7080 0.380 -1.864 0.062 -1.453 0.037\n", 85 | "x1 -0.0092 0.006 -1.592 0.111 -0.021 0.002\n", 86 | "x2 0.1040 0.021 4.905 0.000 0.062 0.146\n", 87 | "==============================================================================\n" 88 | ] 89 | } 90 | ], 91 | "source": [ 92 | "#fit a simple probit\n", 93 | "probit_mod = sm.Probit(data['y'], sm.add_constant(data[['x1','x2']]),missing='drop')\n", 94 | "\n", 95 | "probit_results = probit_mod.fit()\n", 96 | "print probit_results.summary()" 97 | ] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": {}, 102 | "source": [ 103 | "### Part b" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 35, 109 | "metadata": {}, 110 | "outputs": [ 111 | { 112 | "name": "stdout", 113 | "output_type": "stream", 114 | "text": [ 115 | " Probit Marginal Effects \n", 116 | "=====================================\n", 117 | "Dep. Variable: y\n", 118 | "Method: dydx\n", 119 | "At: mean\n", 120 | "==============================================================================\n", 121 | " dy/dx std err z P>|z| [0.025 0.975]\n", 122 | "------------------------------------------------------------------------------\n", 123 | "x1 -0.0036 0.002 -1.592 0.111 -0.008 0.001\n", 124 | "x2 0.0408 0.008 4.907 0.000 0.025 0.057\n", 125 | "==============================================================================\n" 126 | ] 127 | } 128 | ], 129 | "source": [ 130 | "#calculate marginal effects\n", 131 | "probit_margeff = probit_results.get_margeff(at='mean',dummy=True)\n", 132 | "print probit_margeff.summary()" 133 | ] 134 | }, 135 | { 136 | "cell_type": "markdown", 137 | "metadata": {}, 138 | "source": [ 139 | "For a woman of mean age and education, the marginal effect of an additional year of education on the probability of working is about 4.1%. " 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "### Part c" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 39, 152 | "metadata": {}, 153 | "outputs": [ 154 | { 155 | "name": "stdout", 156 | "output_type": "stream", 157 | "text": [ 158 | "Optimization terminated successfully.\n", 159 | " Current function value: 0.664044\n", 160 | " Iterations 5\n", 161 | " Logit Regression Results \n", 162 | "==============================================================================\n", 163 | "Dep. Variable: y No. Observations: 753\n", 164 | "Model: Logit Df Residuals: 750\n", 165 | "Method: MLE Df Model: 2\n", 166 | "Date: Fri, 19 Oct 2018 Pseudo R-squ.: 0.02884\n", 167 | "Time: 19:12:32 Log-Likelihood: -500.03\n", 168 | "converged: True LL-Null: -514.87\n", 169 | " LLR p-value: 3.561e-07\n", 170 | "==============================================================================\n", 171 | " coef std err z P>|z| [0.025 0.975]\n", 172 | "------------------------------------------------------------------------------\n", 173 | "const -1.1322 0.614 -1.843 0.065 -2.336 0.072\n", 174 | "x1 -0.0152 0.009 -1.624 0.104 -0.034 0.003\n", 175 | "x2 0.1681 0.035 4.819 0.000 0.100 0.237\n", 176 | "==============================================================================\n" 177 | ] 178 | } 179 | ], 180 | "source": [ 181 | "#fit a simple logit\n", 182 | "logit_mod = sm.Logit(data['y'], sm.add_constant(data[['x1','x2']]),missing='drop')\n", 183 | "\n", 184 | "logit_results = logit_mod.fit()\n", 185 | "print logit_results.summary()" 186 | ] 187 | }, 188 | { 189 | "cell_type": "markdown", 190 | "metadata": {}, 191 | "source": [ 192 | "* Why are there big differences in the ratio of estimated coefficients? \n", 193 | "\n", 194 | "The tails on the logit distribution are thicker. However, the estimated marignal effect should be roughly the same between the two models. The partial effects in both cases are given by $\\frac{\\partial{p(x)}}{\\partial x_j} = g(x\\beta)\\beta_j$ where $g(x\\beta)$ is the pdf. As a result the coefficeints for logit model are bigger in magnitude. \n", 195 | "\n", 196 | "* What about the ratio of estimated coefficients?\n", 197 | "\n", 198 | "More over, since the estimated marignal effect should be roughly the same between the two models. As a result, the coefficients have roughly the same ratio. \n", 199 | "\n", 200 | "\n", 201 | "\n" 202 | ] 203 | }, 204 | { 205 | "cell_type": "code", 206 | "execution_count": null, 207 | "metadata": {}, 208 | "outputs": [], 209 | "source": [] 210 | } 211 | ], 212 | "metadata": { 213 | "kernelspec": { 214 | "display_name": "Python 2", 215 | "language": "python", 216 | "name": "python2" 217 | }, 218 | "language_info": { 219 | "codemirror_mode": { 220 | "name": "ipython", 221 | "version": 2 222 | }, 223 | "file_extension": ".py", 224 | "mimetype": "text/x-python", 225 | "name": "python", 226 | "nbconvert_exporter": "python", 227 | "pygments_lexer": "ipython2", 228 | "version": "2.7.15" 229 | } 230 | }, 231 | "nbformat": 4, 232 | "nbformat_minor": 2 233 | } 234 | -------------------------------------------------------------------------------- /hw2/question2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Assignment 2 Structural Econometrics: Question 2\n", 8 | "## November 9, 2018 \n", 9 | "## Eric Schulman " 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 2, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import pandas as pd\n", 19 | "import matplotlib.pyplot as plt\n", 20 | "import numpy as np\n", 21 | "import math\n", 22 | "\n", 23 | "import statsmodels.api as sm\n", 24 | "from statsmodels.sandbox.regression.gmm import GMM\n", 25 | "from statsmodels.base.model import GenericLikelihoodModel\n", 26 | "\n", 27 | "from scipy.stats import norm\n", 28 | "from scipy.stats import multivariate_normal" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 3, 34 | "metadata": {}, 35 | "outputs": [ 36 | { 37 | "name": "stdout", 38 | "output_type": "stream", 39 | "text": [ 40 | "y 0.568393\n", 41 | "x1 42.537849\n", 42 | "x2 12.286853\n", 43 | "z 9.029880\n", 44 | "dtype: float64\n" 45 | ] 46 | } 47 | ], 48 | "source": [ 49 | "#load data into memory\n", 50 | "data = pd.DataFrame(data = np.genfromtxt('ps2.dat', delimiter=' '), columns=['y','x1','x2','z'])\n", 51 | "\n", 52 | "print data.mean()" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "### Part a\n", 60 | "\n", 61 | "An economic story where $x_{2i}$ is correlated with $\\epsilon_i$ involves simultaneity between a woman's decision of an education level and years she wants to work. Women who intend work may select more education. If women make this decision simultaneously, you would expect correlation between $x_{2i}$ and $\\epsilon_i$ and an upward bias on $\\theta_2$" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "### Part b\n" 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": {}, 74 | "source": [ 75 | "### Part c\n", 76 | "\n", 77 | "If $x_{2i}$ is exogenous, we have $\\rho = 0$. This is because\n", 78 | "\n", 79 | "$$E(x_{2i} \\epsilon_i) = E(\\eta_i \\epsilon_i) = \\rho$$\n", 80 | "\n", 81 | "Since we believe $x_{2i}$ is endogoenous, I would expect $\\rho > 0$. One might expect parents education to be positively related to your education (i.e. your parents can serve as a role model).\n", 82 | "\n", 83 | "Assuming that $z_i$ does not directly determine $y_i$ is the exclusion restriction. Without this restriction, $\\theta_2$ would not be identified." 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": {}, 89 | "source": [ 90 | "### Part d\n", 91 | "\n", 92 | "In order to estimate the model we must derive the likelihood function.\n", 93 | "\n", 94 | "$$p(y_i,x_{2i} | x_{1i}, z_i, \\theta) = p(x_{2i} | x_{1i}, z_i, \\theta) p(y_i | x_{1i},x_{2i}, z_i, \\theta) = p(x_{2i} | x_{1i}, z_i, \\theta) p(y_i | x_{1i},x_{2i}, z_i, \\eta_i, \\theta)$$\n", 95 | "\n", 96 | "Preforming a change of variable of $\\eta_i$ for $x_{2i}$, we can write\n", 97 | "\n", 98 | "$$p(x_{2i} | x_{1i}, z_i, \\theta) = p(\\eta_i|x_i,z_i,\\theta)\\dfrac{dx_{2i}}{d\\eta_i} = \\phi(\\dfrac{\\eta_i}{\\sigma_\\eta}) \\dfrac{1}{\\sigma_\\eta}$$\n", 99 | "\n", 100 | "We can derive an analytic experession for $p(y_i | x_{1i},x_{2i}, z_i, \\theta)$ below:\n", 101 | "\n", 102 | "For notational convenience let, $\\gamma_i = \\theta_2 \\eta_i + \\theta_0 + \\theta_2\\theta_3 + (\\theta_1 + \\theta_2\\theta_4) + \\theta_2\\theta_5 z_i$\n", 103 | "\n", 104 | "When $y_i =1$, we have $p(y_i | x_{1i},x_{2i}, z_i, \\theta) = 1 - P(\\epsilon_i + \\gamma_i > 0) $\n", 105 | "\n", 106 | "When $y_i = 0$, we have $p(y_i | x_{1i},x_{2i}, z_i, \\theta) = P(\\epsilon_i + \\gamma_i > 0) $\n", 107 | "\n", 108 | "So, we have \n", 109 | "\n", 110 | "$$p(y_i | x_{1i},x_{2i}, z_i, \\theta) = (1-y_i) P(\\epsilon_i + \\gamma_i > 0) + y_i (1 - P(\\epsilon_i + \\gamma_i > 0) ) $$\n", 111 | "\n", 112 | "Using results about the distribution of conditional normals we know\n", 113 | "\n", 114 | "$\\epsilon_i|\\eta_i \\sim N(\\eta_i \\dfrac{\\rho}{\\sigma_\\eta^2}, 1 - \\dfrac{\\rho^2}{\\sigma_\\eta^2})$\n", 115 | "\n", 116 | "\n", 117 | "So, $p(y_i | x_{1i},x_{2i}, z_i, \\theta) = y_i (1 -\\Phi(\\dfrac{- \\gamma_i - \\frac{\\rho}{\\sigma_\\eta^2}}{1 - \\frac{\\rho^2}{\\sigma_\\eta^2}})) + (1-y_i)\\Phi(\\dfrac{- \\gamma_i - \\frac{\\rho}{\\sigma_\\eta^2}}{1 - \\frac{\\rho^2}{\\sigma_\\eta^2}}) $\n", 118 | "\n", 119 | "Now we can write\n", 120 | "\n", 121 | "$$L = \\sum_i log(p(x_{2i} | x_{1i}, z_i, \\theta)) + log(p(y_i | x_{1i},x_{2i}, z_i, \\eta_i, \\theta))$$" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 14, 127 | "metadata": {}, 128 | "outputs": [ 129 | { 130 | "name": "stdout", 131 | "output_type": "stream", 132 | "text": [ 133 | "Optimization terminated successfully.\n", 134 | " Current function value: 2.765785\n", 135 | " Iterations: 1171\n", 136 | " Function evaluations: 1699\n", 137 | " part_d Results \n", 138 | "==============================================================================\n", 139 | "Dep. Variable: ['y', 'x2'] Log-Likelihood: -2082.6\n", 140 | "Model: part_d AIC: 4169.\n", 141 | "Method: Maximum Likelihood BIC: 4179.\n", 142 | "Date: Wed, 07 Nov 2018 \n", 143 | "Time: 14:46:51 \n", 144 | "No. Observations: 753 \n", 145 | "Df Residuals: 751 \n", 146 | "Df Model: 1 \n", 147 | "==============================================================================\n", 148 | " coef std err z P>|z| [0.025 0.975]\n", 149 | "------------------------------------------------------------------------------\n", 150 | "theta_0 -0.3913 0.641 -0.611 0.541 -1.647 0.864\n", 151 | "theta_1 -0.0100 0.006 -1.688 0.091 -0.022 0.002\n", 152 | "theta_2 0.0808 0.043 1.863 0.063 -0.004 0.166\n", 153 | "theta_3 9.1254 0.492 18.544 0.000 8.161 10.090\n", 154 | "theta_4 -0.0031 0.009 -0.342 0.732 -0.021 0.015\n", 155 | "theta_5 0.3649 0.024 15.167 0.000 0.318 0.412\n", 156 | "rho 0.1172 0.190 0.615 0.538 -0.256 0.491\n", 157 | "sigma 1.9799 0.051 38.807 0.000 1.880 2.080\n", 158 | "==============================================================================\n" 159 | ] 160 | } 161 | ], 162 | "source": [ 163 | "class part_d(GenericLikelihoodModel):\n", 164 | " \"\"\"class for evaluating question 1 part b\"\"\"\n", 165 | " \n", 166 | " def nloglikeobs(self, params):\n", 167 | " \"\"\"evaluate the likelihood function as derived above\"\"\"\n", 168 | " t0,t1,t2,t3,t4,t5,rho,sigma = params\n", 169 | "\n", 170 | " y,x2 = self.endog.transpose()\n", 171 | " x1,z = self.exog.transpose()\n", 172 | " \n", 173 | " eta = x2 - t3 - t4*x1 - t5*z\n", 174 | " \n", 175 | " mu_epsilon = (rho/sigma**2)*eta\n", 176 | " var_epsilon = np.sqrt( abs(1 - (rho/sigma)**2) )\n", 177 | " \n", 178 | " #pr(eta | ... )\n", 179 | " pr_eta = norm(0,sigma).pdf(eta)\n", 180 | " \n", 181 | " #pr(y|x2 ... )\n", 182 | " gamma = t0 + t2*t3 + (t1 + t2*t4)*x1 + t2*t5*z + t2*eta\n", 183 | " \n", 184 | " pr_epsilon = (y*(1 - norm(mu_epsilon,var_epsilon).cdf(-gamma))\n", 185 | " + (1-y)*norm(mu_epsilon,var_epsilon).cdf(-gamma))\n", 186 | " \n", 187 | " likelihood = np.log( pr_epsilon*pr_eta )\n", 188 | "\n", 189 | " return -( likelihood.sum() ) \n", 190 | " \n", 191 | " \n", 192 | " def fit(self, start_params=None, maxiter=2000, maxfun=5000, **kwds):\n", 193 | " \"\"\"fit the likelihood function using the right start parameters\"\"\"\n", 194 | " # we have one additional parameter and we need to add it for summary\n", 195 | " if start_params == None:\n", 196 | " start_params = [-.39,.01,.08,9.1, 0.0, .36, .11, 1.9]\n", 197 | " \n", 198 | " return super(part_d, self).fit(start_params=start_params,\n", 199 | " maxiter=maxiter, maxfun=maxfun, **kwds)\n", 200 | "\n", 201 | " \n", 202 | "model_d = part_d(data[['y','x2']],data[['x1','z']])\n", 203 | "\n", 204 | "result_d = model_d.fit()\n", 205 | "print(result_d.summary(xname=['theta_0', 'theta_1', 'theta_2',\n", 206 | " 'theta_3','theta_4','theta_5',\n", 207 | " 'rho', 'sigma']))" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "### Part e\n", 215 | "\n", 216 | "Using results from the table above, we can see that $\\rho$ is roughly .12 and it's standard error is .19. As a result, we fail to reject the null hypothesis beyond a .50 confidence level. Either $x_{2i}$ is exogenous or $z_i$ is not." 217 | ] 218 | }, 219 | { 220 | "cell_type": "markdown", 221 | "metadata": {}, 222 | "source": [ 223 | "### Part f\n", 224 | "\n", 225 | "$\\tau_i$ is a random coefficeint on $x_{2i}$ to capture a heterogenous response in labor force participation to education. Simply put, education might make a bigger difference for some people's labor force participation than others. If this is the case, you should include a random coefficient.\n" 226 | ] 227 | }, 228 | { 229 | "cell_type": "markdown", 230 | "metadata": {}, 231 | "source": [ 232 | "### Part g\n", 233 | "\n", 234 | "As in part d)\n", 235 | "\n", 236 | "$$p(y_i,x_{2i} | x_{1i}, z_i, \\theta) = p(x_{2i} | x_{1i}, z_i, \\theta) p(y_i | x_{1i},x_{2i}, z_i, \\theta) = p(x_{2i} | x_{1i}, z_i, \\theta) p(y_i | x_{1i},x_{2i}, z_i, \\eta_i, \\theta)$$\n", 237 | "\n", 238 | "This holds because $p(x_{2i} | x_{1i}, z_i, \\tau_i, \\theta) = p(x_{2i} | x_{1i}, z_i, \\theta) $\n", 239 | "Now, we can write \n", 240 | "\n", 241 | "$$p(y_i | x_{1i},x_{2i}, z_i, \\eta_i, \\theta) = \\int p(y_i | x_{1i},x_{2i}, \\tau_i, z_i, \\eta_i, \\theta)p(\\tau_i)d \\tau'_i$$ and simulate to get\n", 242 | "\n", 243 | "$$p(y_i | x_{1i},x_{2i}, z_i, \\eta_i, \\theta) = \\frac{1}{S} \\sum_s p(y_i | x_{1i},x_{2i}, \\tau_{i,s}, z_i, \\eta_i, \\theta)$$\n", 244 | "\n", 245 | "We can modify $\\gamma_i(\\tau_i)$ from before to include the simulated $\\tau_i$. Specifically,\n", 246 | "\n", 247 | "$$\\gamma_i(\\tau_i) = (\\theta_2 + \\sigma_\\tau \\tau_i) \\eta_i + \\theta_0 + (\\theta_2+ \\sigma_\\tau \\tau_i)\\theta_3 + (\\theta_1 + (\\theta_2+ \\sigma_\\tau \\tau_i)\\theta_4) + (\\theta_2+ \\sigma_\\tau \\tau_i)\\theta_5 z_i$$\n", 248 | "\n", 249 | "Now we can write\n", 250 | "\n", 251 | "$$L = \\sum_i log(p(x_{2i} | x_{1i}, z_i, \\theta)) + log(p(y_i | x_{1i},x_{2i}, z_i, \\eta_i, \\theta))$$\n", 252 | "\n", 253 | "Where\n", 254 | "\n", 255 | "$$p(x_{2i} | x_{1i}, z_i, \\theta) = p(\\eta_i|x_i,z_i,\\theta)\\dfrac{dx_{2i}}{d\\eta_i} = \\phi(\\dfrac{\\eta_i}{\\sigma_\\eta}) \\dfrac{1}{\\sigma_\\eta}$$\n", 256 | "\n", 257 | "\n", 258 | "$$p(y_i | x_{1i},x_{2i}, z_i, \\eta_i, \\theta) = \\frac{1}{S} \\sum_s y_i (1 -\\Phi(\\dfrac{- \\gamma_i(\\tau_i) - \\frac{\\rho}{\\sigma_\\eta^2}}{1 - \\frac{\\rho^2}{\\sigma_\\eta^2}})) + (1-y_i)\\Phi(\\dfrac{- \\gamma_i(\\tau_i) - \\frac{\\rho}{\\sigma_\\eta^2}}{1 - \\frac{\\rho^2}{\\sigma_\\eta^2}})$$\n" 259 | ] 260 | }, 261 | { 262 | "cell_type": "markdown", 263 | "metadata": {}, 264 | "source": [ 265 | "### Part h\n", 266 | "\n", 267 | "\n", 268 | "We can use the following conditions\n", 269 | "\n", 270 | "1. $E(\\eta_i) = 0$\n", 271 | "2. $E(\\eta_i x_{1i}) = 0$\n", 272 | "3. $E(\\eta_i z_i) = 0$\n", 273 | "\n", 274 | "\n", 275 | "Now letting,\n", 276 | "\n", 277 | "$$E( g( x_{i1}, x_{i2}, z{i}) ) = \\frac{1}{S} \\sum \\sum_s \\textbf{1}( (\\theta_2 + \\sigma_\\tau \\tau_i) \\eta_i + \\theta_0 + (\\theta_2+ \\sigma_\\tau \\tau_i)\\theta_3 + (\\theta_1 + (\\theta_2+ \\sigma_\\tau \\tau_i)\\theta_4) + (\\theta_2+ \\sigma_\\tau \\tau_i)\\theta_5 z_i + \\epsilon_i > 0)$$\n", 278 | "\n", 279 | "Where $S$ reflects simualtions of both $\\tau_i$ and $\\epsilon_i$ using the conditional distribution of $\\epsilon_i$ derived in part d)\n", 280 | "\n", 281 | "4. $E( y_i - g(x_{i1}, x_{i2}, z{i}) ) = 0$\n", 282 | "5. $E( ( y_i - g(x_{i1}, x_{i2}, z{i})) x_{1i} ) = 0$\n", 283 | "6. $E( ( y_i - g(x_{i1}, x_{i2}, z{i})) z_{i} ) = 0$\n", 284 | "\n", 285 | "The following moments will help idetnify $\\rho$ aand $\\sigma_\\eta$\n", 286 | "\n", 287 | "7. $E(\\eta_i x_{1i}^2) = 0$\n", 288 | "8. $E(\\eta_i z_i^2) = 0$\n", 289 | "9. $E(( y_i - g(x_{i1}, x_{i2}, z{i})) x_{1i}^2 ) = 0$\n", 290 | "10. $E( ( y_i - g(x_{i1}, x_{i2}, z{i})) z_{i}^2 ) = 0$\n", 291 | "\n", 292 | "From class we know that\n", 293 | "\n", 294 | "$$m^{opt}(z_i) = E( \\dfrac{ \\partial g^{-1}(x_i,y_i,\\theta)}{\\partial \\theta} )$$\n", 295 | "\n", 296 | "Squaring $z_i$, and $x_{i1}$ are the most 'direct' way to make inferences about $\\rho$ and $\\sigma_\\eta$. This is because the squared terms interact directly with these parameters in the model." 297 | ] 298 | }, 299 | { 300 | "cell_type": "markdown", 301 | "metadata": {}, 302 | "source": [ 303 | "### Part i\n", 304 | "\n", 305 | "* Compared to MSM, SML will require more simulation draws because assymptotically we assume that $S \\rightarrow \\infty$. MSM is consistent reguardless of the number of simulations. The efficiency is still related to the number of simulations. Also, technically MSM does not rely on a distributional assumption on $\\eta_i$\n", 306 | "\n", 307 | "* On the other hand, we only need to simulate $\\tau_i$ in SML. As shown in part d) we can derive an analytic distribution for the likelihood of $\\epsilon_i$ conditional on $\\eta_i$. " 308 | ] 309 | }, 310 | { 311 | "cell_type": "markdown", 312 | "metadata": {}, 313 | "source": [ 314 | "### Part j\n", 315 | "\n", 316 | "No they are not smooth in $\\theta_2$. We could simulate $E( g( x_{i1}, x_{i2}, z{i}) )$ using importance sampling to make the functions smooth.\n", 317 | "\n", 318 | "This would involve letting\n", 319 | "\n", 320 | "$$E( g( x_{i1}, x_{i2}, z_{i}) )= $$ \n", 321 | "\n", 322 | "$$ \\int \\int \\textbf{1}( (\\theta_2 + \\sigma_\\tau \\tau_i) \\eta_i + \\theta_0 + (\\theta_2+ \\sigma_\\tau \\tau_i)\\theta_3 + (\\theta_1 + (\\theta_2+ \\sigma_\\tau \\tau_i)\\theta_4) + (\\theta_2+ \\sigma_\\tau \\tau_i)\\theta_5 z_i + \\epsilon_i > 0) p(\\epsilon_i | \\eta_i ) p(\\tau_i) d\\tau'_i d \\epsilon'_i $$\n", 323 | "\n", 324 | "$$ = \\int \\int \\textbf{1}( \\gamma_i > 0) p(\\gamma_i | \\eta_i ) p(\\tau_i) d\\tau'_i d \\epsilon'_i $$\n", 325 | "\n", 326 | "$$ = \\int \\int \\textbf{1}( \\gamma_i > 0) \\dfrac{ p(\\gamma_i | \\eta_i ) p(\\tau_i) h(\\eta_i) } {h(\\eta_i)} d\\tau'_i d \\epsilon'_i $$\n", 327 | "\n", 328 | "Let $h(\\eta_i) = \\dfrac{1}{p(\\eta_i)}$\n", 329 | "\n", 330 | "Since $p(\\gamma_i | \\eta_i ) =p(\\epsilon_i | \\eta_i ) = \\dfrac{p(\\epsilon_i, \\eta_i)}{p(\\eta_i)} = \\dfrac{p(\\gamma_i)}{p(\\eta_i)}$, we ahve\n", 331 | "\n", 332 | "$$ = \\int \\int \\textbf{1}( \\gamma_i > 0 ) \\dfrac{p(\\gamma_i)}{p(\\eta_i)} p(\\tau_i) d\\tau'_i d \\epsilon'_i $$\n", 333 | "\n", 334 | "Instead of simulating from $p(\\gamma_i | \\eta_i )$ we can simulate from $p(\\gamma_i)$\n", 335 | "\n", 336 | "$$ = \\frac{1}{S} \\sum \\sum_s \\textbf{1}( \\gamma_i > 0) \\dfrac{1}{p(\\eta_i)} $$" 337 | ] 338 | }, 339 | { 340 | "cell_type": "markdown", 341 | "metadata": {}, 342 | "source": [ 343 | "### Part k\n", 344 | "\n", 345 | "This assumption may not be reasonable. If education and labor force partiticipation are simultaneously determined, then you would expect the error $\\eta_i$ to reflect this simultaneous decision. Additionally, an individual's $\\tau_i$ would influence this simultaneous decision. As a result you would expect $\\tau_i$ and $\\eta_i$ to be positively correlated and $\\sigma_\\tau$ to be biased downward" 346 | ] 347 | }, 348 | { 349 | "cell_type": "markdown", 350 | "metadata": {}, 351 | "source": [ 352 | "### Part l\n", 353 | "\n", 354 | "In order to produce consistent estimates, “ivprobit” requires\n", 355 | "\n", 356 | "* The endogenous regressors are continuous.\n", 357 | "* The error term inside the indicator function, $\\epsilon_i$, is homoskedastic. If it is heteroskedastic, point estimates will be inconsistent as with most other probit models.\n", 358 | "* ($\\epsilon_i$, $\\eta_i$) is i.i.d. multivariate normal $\\forall i$.\n", 359 | "\n", 360 | "\n", 361 | "This command cannot estimate the model in part f) because the estimate for $\\sigma_\\eta$ and $\\tau_i$ will depend on $x_{2i}$. As a result, including $\\tau_i$ in the model will violate our assumption about homoskedasticity" 362 | ] 363 | }, 364 | { 365 | "cell_type": "code", 366 | "execution_count": null, 367 | "metadata": {}, 368 | "outputs": [], 369 | "source": [] 370 | } 371 | ], 372 | "metadata": { 373 | "kernelspec": { 374 | "display_name": "Python 2", 375 | "language": "python", 376 | "name": "python2" 377 | }, 378 | "language_info": { 379 | "codemirror_mode": { 380 | "name": "ipython", 381 | "version": 2 382 | }, 383 | "file_extension": ".py", 384 | "mimetype": "text/x-python", 385 | "name": "python", 386 | "nbconvert_exporter": "python", 387 | "pygments_lexer": "ipython2", 388 | "version": "2.7.15" 389 | } 390 | }, 391 | "nbformat": 4, 392 | "nbformat_minor": 2 393 | } 394 | -------------------------------------------------------------------------------- /hw2/question3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Assignment 2 Structural Econometrics: Question 3\n", 8 | "## November 9, 2018 \n", 9 | "## Eric Schulman" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import pandas as pd\n", 19 | "import matplotlib.pyplot as plt\n", 20 | "import numpy as np\n", 21 | "import math\n", 22 | "\n", 23 | "import statsmodels.api as sm\n", 24 | "from statsmodels.sandbox.regression.gmm import GMM\n", 25 | "from statsmodels.base.model import GenericLikelihoodModel\n", 26 | "\n", 27 | "from scipy.stats import norm\n", 28 | "from scipy.stats import multivariate_normal" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 2, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "#load data into memory\n", 38 | "data = pd.DataFrame(data = np.genfromtxt('sim3.dat', delimiter=' '), columns=['i','t','y_t','p_t'])\n", 39 | "\n", 40 | "#set up lag\n", 41 | "shift_data = data[['i','y_t','p_t']]\n", 42 | "shift_data['t'] = data['t'] + 1\n", 43 | "data = data.merge(shift_data,how='left',on=['i','t'],suffixes=['','-1'])\n", 44 | "data = data.fillna(0) # the initial period is 0" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": {}, 50 | "source": [ 51 | "### Part a\n", 52 | "\n", 53 | "\n", 54 | "Because of state dependence, $U_{it}$ only depends on $\\epsilon_{it}$ when we know the values of $p_{it}, y_{it-1}$, and $\\alpha_i$. Since, $\\epsilon_{it}$ is i.i.d.\n", 55 | "\n", 56 | "$$Pr(\\textbf{1}(U_{it} >0)| p_{it}, y_{it-1}; \\theta) \\perp Pr(\\textbf{1}(U_{it+1} >0)| p_{it+1}, y_{it}; \\theta) $$ \n", 57 | "\n", 58 | "Since $y_{it} = \\textbf{1}(U_{it} >0)$\n", 59 | "\n", 60 | "$$Pr(y_{it}| p_{it}, y_{it-1}, \\alpha_i; \\theta) \\perp Pr( y_{it+1}| p_{it+1}, y_{it}, \\alpha_i; \\theta)$$\n", 61 | "\n", 62 | "\n", 63 | "Thus we can write \n", 64 | "\n", 65 | "$$\\int Pr( y_{i1},... y_{iT} | p_{i1}, ... ,p_{it}, y_{i0} , \\alpha_i; \\theta ) d \\alpha'_i = $$\n", 66 | "\n", 67 | "$$\\int Pr( \\textbf{1}(U_{i1} >0), ... , \\textbf{1}(U_{iT} >0) | p_{i1}, ... ,p_{iT}, y_{i0}, .... y_{i,T}, \\alpha_i ; \\theta ) d \\alpha'_i = $$\n", 68 | "\n", 69 | "$$\\int Pr(\\textbf{1}(U_{i1} >0)| p_{i1}, y_{i0}, \\alpha_i) ... Pr(\\textbf{1}(U_{iT} >0)| p_{iT}, y_{iT-1}, \\alpha_i ; \\theta) d \\alpha'_i = $$\n", 70 | "\n", 71 | "\n", 72 | "\n", 73 | "$$\\int Pr(y_{i1} | p_{i1}, y_{i0}, \\alpha_i) ... Pr(y_{iT} | p_{iT}, y_{iT-1}, \\alpha_i ; \\theta) d \\alpha'_i $$" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "### Part b\n", 81 | "\n", 82 | "The equality would not hold without integrating out $\\alpha_i$. The $\\epsilon_{it}$ may be correlated over time due to individual heterogeneity. The terms inside the product are no longer independent of each other." 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "metadata": {}, 88 | "source": [ 89 | "### Part c\n", 90 | "\n", 91 | "According to our model\n", 92 | "\n", 93 | "$$Pr(y_{it} | \\alpha_i, y_{it-1}, p_{it}) =Pr(\\textbf{1}(U_{it} >0)| p_{it}, y_{it-1})$$ \n", 94 | "\n", 95 | "\n", 96 | "When $y_{it} = 1$, we know that $U_{it} >0$, so \n", 97 | "\n", 98 | "$$Pr(\\textbf{1}(U_{it} >0)| p_{it}, y_{it-1}) = \\dfrac{e^{\\theta_0 + \\theta_1 p_{it} + \\theta_2 y_{it-1} + \\sigma_\\alpha \\alpha_i } }{ 1 + e^{\\theta_0 + \\theta_1 p_{it} + \\theta_2 y_{it-1} + \\sigma_\\alpha \\alpha_i}}$$\n", 99 | "\n", 100 | "When $y_{it} = 0 $, our model tells us that $U_{it} <0$ so \n", 101 | "\n", 102 | "$$ Pr(\\textbf{1}(U_{it} >0)| p_{it}, y_{it-1}) = \\dfrac{1 }{ 1 + e^{\\theta_0 + \\theta_1 p_{it} + \\theta_2 y_{it-1} + \\sigma_\\alpha \\alpha_i}}$$\n", 103 | "\n", 104 | "Combining these results we know\n", 105 | "\n", 106 | "$$Pr(y_{it} | \\alpha_i, y_{it-1}, p_{it}) = y_{it} \\dfrac{e^{\\theta_0 + \\theta_1 p_{it} + \\theta_2 y_{it-1} + \\sigma_\\alpha \\alpha_i } }{ 1 + e^{\\theta_0 + \\theta_1 p_{it} + \\theta_2 y_{it-1} + \\sigma_\\alpha \\alpha_i}} + (1-y_{it}) \\dfrac{1 }{ 1 + e^{\\theta_0 + \\theta_1 p_{it} + \\theta_2 y_{it-1} + \\sigma_\\alpha \\alpha_i}}$$" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "### Part d" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 3, 119 | "metadata": {}, 120 | "outputs": [], 121 | "source": [ 122 | "#set up useful global variables\n", 123 | "\n", 124 | "NSIM = 1000\n", 125 | "T = int(data.groupby('i').count().max()['t'])\n", 126 | "I = len(data.i.unique())\n", 127 | "\n", 128 | "alpha = np.random.normal(0,1 ,(NSIM, I))\n", 129 | "alpha = alpha.reshape( (1, NSIM, I) )\n", 130 | "alpha = np.tile(alpha, (T, 1,1))" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": 4, 136 | "metadata": {}, 137 | "outputs": [], 138 | "source": [ 139 | "def shape_data(x):\n", 140 | " \"\"\" format data as a 3d array to make working with it easier\"\"\"\n", 141 | " x = np.array([x])\n", 142 | " x = x.reshape(I,1,T)\n", 143 | " x = np.tile(x ,(1,NSIM,1)).transpose() \n", 144 | " return x" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": 8, 150 | "metadata": {}, 151 | "outputs": [ 152 | { 153 | "name": "stdout", 154 | "output_type": "stream", 155 | "text": [ 156 | "Optimization terminated successfully.\n", 157 | " Current function value: 0.620089\n", 158 | " Iterations: 157\n", 159 | " Function evaluations: 257\n", 160 | " part_d Results \n", 161 | "==============================================================================\n", 162 | "Dep. Variable: y_t Log-Likelihood: -1240.2\n", 163 | "Model: part_d AIC: 2484.\n", 164 | "Method: Maximum Likelihood BIC: 2496.\n", 165 | "Date: Thu, 08 Nov 2018 \n", 166 | "Time: 19:31:55 \n", 167 | "No. Observations: 2000 \n", 168 | "Df Residuals: 1998 \n", 169 | "Df Model: 1 \n", 170 | "==============================================================================\n", 171 | " coef std err z P>|z| [0.025 0.975]\n", 172 | "------------------------------------------------------------------------------\n", 173 | "theta_0 -0.8067 0.209 -3.852 0.000 -1.217 -0.396\n", 174 | "theta_1 0.9111 0.179 5.100 0.000 0.561 1.261\n", 175 | "theta_2 0.5013 0.109 4.588 0.000 0.287 0.715\n", 176 | "sigma 0.8801 0.097 9.094 0.000 0.690 1.070\n", 177 | "==============================================================================\n" 178 | ] 179 | } 180 | ], 181 | "source": [ 182 | "class part_d(GenericLikelihoodModel):\n", 183 | " \"\"\"class for evaluating question 3 part d\"\"\"\n", 184 | " \n", 185 | " def __init__(self, sims, *args, **kwds):\n", 186 | " super(part_d, self).__init__(*args, **kwds)\n", 187 | " self.sims = sims\n", 188 | " \n", 189 | " \n", 190 | " def nloglikeobs(self, params):\n", 191 | " \"\"\"Log likelihood function derived above\"\"\"\n", 192 | " t0, t1, t2, sigma = params\n", 193 | " y = shape_data(self.endog)\n", 194 | " \n", 195 | " p = shape_data(self.exog.transpose()[0])\n", 196 | " y_lag = shape_data(self.exog.transpose()[1])\n", 197 | " alpha = self.sims\n", 198 | " \n", 199 | " #calculate the mean 'delta' for the inside good\n", 200 | " U1 = np.exp(t0 + t1*p + t2*y_lag + sigma*alpha)\n", 201 | " \n", 202 | " #calculate ll, for each simulation\n", 203 | " like = y*U1/(1.+U1) + (1.-y)/(1.+U1)\n", 204 | " like = 1./NSIM * (like.prod(axis=0)).sum(axis=0)\n", 205 | " like = np.log(like).sum(axis = 0)\n", 206 | "\n", 207 | " return - like\n", 208 | "\n", 209 | " \n", 210 | " def fit(self, start_params=None, maxiter=1000, maxfun=5000, **kwds):\n", 211 | " \"\"\"fit log likelihood to data\"\"\"\n", 212 | " if start_params == None:\n", 213 | " start_params = [.5,.5,.5,.5]\n", 214 | " return super(part_d, self).fit(start_params=start_params,\n", 215 | " maxiter=maxiter, maxfun=maxfun, **kwds)\n", 216 | " \n", 217 | "\n", 218 | "model_d = part_d(alpha, data['y_t'] ,data[['p_t','y_t-1']])\n", 219 | "\n", 220 | "result_d = model_d.fit()\n", 221 | "print(result_d.summary(xname=['theta_0', 'theta_1', 'theta_2', 'sigma']))" 222 | ] 223 | }, 224 | { 225 | "cell_type": "markdown", 226 | "metadata": {}, 227 | "source": [ 228 | "### Part e\n", 229 | "\n", 230 | "The coefficient on $\\theta_2$ and $\\sigma_\\alpha$ are both significant. The coefficient on $\\sigma_\\alpha$ is larger than $\\theta_2$. As a result, individual heterogeniety may be more important in explaining the correlation acrros time" 231 | ] 232 | }, 233 | { 234 | "cell_type": "markdown", 235 | "metadata": {}, 236 | "source": [ 237 | "### Part f\n", 238 | "\n", 239 | "By re-estimating the model (below) the coefficient on $\\theta_2$ increases. This is individual heterogenity is now an omitted variable which is correlated with the effect from the preivous state. As a result, excluding the heterogeniety causes an upward bias." 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 25, 245 | "metadata": {}, 246 | "outputs": [ 247 | { 248 | "name": "stdout", 249 | "output_type": "stream", 250 | "text": [ 251 | "Optimization terminated successfully.\n", 252 | " Current function value: 0.646619\n", 253 | " Iterations: 94\n", 254 | " Function evaluations: 164\n", 255 | " part_f Results \n", 256 | "==============================================================================\n", 257 | "Dep. Variable: y_t Log-Likelihood: -1293.2\n", 258 | "Model: part_f AIC: 2590.\n", 259 | "Method: Maximum Likelihood BIC: 2602.\n", 260 | "Date: Wed, 07 Nov 2018 \n", 261 | "Time: 17:16:39 \n", 262 | "No. Observations: 2000 \n", 263 | "Df Residuals: 1998 \n", 264 | "Df Model: 1 \n", 265 | "==============================================================================\n", 266 | " coef std err z P>|z| [0.025 0.975]\n", 267 | "------------------------------------------------------------------------------\n", 268 | "theta_0 -0.9485 0.176 -5.390 0.000 -1.293 -0.604\n", 269 | "theta_1 0.7298 0.163 4.475 0.000 0.410 1.049\n", 270 | "theta_2 1.0118 0.094 10.768 0.000 0.828 1.196\n", 271 | "==============================================================================\n" 272 | ] 273 | } 274 | ], 275 | "source": [ 276 | "class part_f(GenericLikelihoodModel):\n", 277 | " \"\"\"class for evaluating question 3 part f\"\"\"\n", 278 | " \n", 279 | " def nloglikeobs(self, params, v=False):\n", 280 | " t0, t1, t2 = params\n", 281 | " y = self.endog\n", 282 | " p,y_lag = self.exog.transpose()\n", 283 | " \n", 284 | " #calculate the mean 'delta' for the inside good\n", 285 | " U1 = t0 + t1*p + t2*y_lag\n", 286 | " U1 = np.exp(U1)\n", 287 | " \n", 288 | " #calculate ll, for each simulation\n", 289 | " likelihood_sims = np.log(y*U1/(1+U1) + (1-y)/(1+U1))\n", 290 | " likelihood = likelihood_sims.sum(axis=0)\n", 291 | " \n", 292 | " if v: raise Exception('Stop drop and roll')\n", 293 | " return - likelihood.sum()\n", 294 | "\n", 295 | " \n", 296 | " def fit(self, start_params=None, maxiter=1000, maxfun=5000, **kwds):\n", 297 | " if start_params == None:\n", 298 | " start_params = [.5,.5,.5]\n", 299 | " return super(part_f, self).fit(start_params=start_params,\n", 300 | " maxiter=maxiter, maxfun=maxfun, **kwds)\n", 301 | " \n", 302 | "\n", 303 | "model_f = part_f(data['y_t'],data[['p_t','y_t-1']])\n", 304 | "\n", 305 | "result_f = model_f.fit()\n", 306 | "print(result_f.summary(xname=['theta_0', 'theta_1', 'theta_2']))" 307 | ] 308 | }, 309 | { 310 | "cell_type": "markdown", 311 | "metadata": {}, 312 | "source": [ 313 | "### Part g" 314 | ] 315 | }, 316 | { 317 | "cell_type": "markdown", 318 | "metadata": {}, 319 | "source": [ 320 | "A crude way to test the null hypothesis would be using the following linear probability model\n", 321 | "\n", 322 | "$$y_{it} = \\theta_1 p_{it} + \\theta_2 p_{it-1} \\epsilon_{it}$$\n", 323 | "\n", 324 | "We could run a t-test on $\\theta_2$ to test for state dependence.\n", 325 | "\n", 326 | "There are technically two key exclusionary restriction here. First we need price is exogenous. Secondly, we require $p_{it-1}$ only effects $y_{it}$ through the current state $y_{it-1}$." 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "execution_count": null, 332 | "metadata": {}, 333 | "outputs": [], 334 | "source": [] 335 | } 336 | ], 337 | "metadata": { 338 | "kernelspec": { 339 | "display_name": "Python 2", 340 | "language": "python", 341 | "name": "python2" 342 | }, 343 | "language_info": { 344 | "codemirror_mode": { 345 | "name": "ipython", 346 | "version": 2 347 | }, 348 | "file_extension": ".py", 349 | "mimetype": "text/x-python", 350 | "name": "python", 351 | "nbconvert_exporter": "python", 352 | "pygments_lexer": "ipython2", 353 | "version": "2.7.15" 354 | } 355 | }, 356 | "nbformat": 4, 357 | "nbformat_minor": 2 358 | } 359 | -------------------------------------------------------------------------------- /hw2_io/BLP.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Homework 2 - BLP Estimation\n", 8 | "Solutions to ECO 384k Problem set 2 at the Universtiy of Texas by Eric Schulman\n", 9 | "\n", 10 | "## Question 1 - Estimation" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 1, 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "import pandas as pd\n", 20 | "import math\n", 21 | "import numpy as np\n", 22 | "from scipy.optimize import minimize\n", 23 | "from scipy.optimize import fsolve\n", 24 | "import statsmodels.api as sm\n", 25 | "from scipy.stats import norm\n", 26 | "from statsmodels.sandbox.regression.gmm import GMM" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": {}, 32 | "source": [ 33 | "### Data setup\n", 34 | "\n", 35 | "Below I write functions to set up the data. The most important is `setup_hausman`. This function calculates the instruments for the estimation. I use 2. I use the mean price for product $i$ in other markets following Hausman. I also use the mean characteristics of the other products $j \\neq i$ in market $m$ following BLP." 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 2, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "def comp_outside_good(data,name):\n", 45 | " \"\"\"pre-processing to calculate outside good shares\"\"\"\n", 46 | " shares = data[['Market_ID',name]].copy()\n", 47 | " group_shares = shares.groupby('Market_ID').sum()\n", 48 | " group_shares['Outside Good Share'] = 1 - group_shares[name]\n", 49 | " data = pd.merge(data,group_shares[['Outside Good Share']], \n", 50 | " right_index=True, left_on = 'Market_ID')\n", 51 | " return data\n", 52 | "\n", 53 | "\n", 54 | "data = pd.read_csv('data.csv')\n", 55 | "data = comp_outside_good(data,'Inside Good Share')" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 3, 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [ 64 | "def setup_data(data):\n", 65 | " \"\"\"simplify setting up data correctly\"\"\"\n", 66 | " #set up x and y\n", 67 | " y = data[['Inside Good Share','Outside Good Share']]\n", 68 | " x = data[['Network Score','Satisfaction Score','PPO','Premium']]\n", 69 | " return x,y\n", 70 | "\n", 71 | "\n", 72 | "def setup_hausman(data):\n", 73 | " #calculate hausmann insturments\n", 74 | " price = data['Premium']\n", 75 | " mkt_dum = pd.get_dummies(data['Market_ID'],prefix='mkt',drop_first=True)\n", 76 | " plan_dum = pd.get_dummies(data['Plan_ID'],prefix='plan',drop_first=True)\n", 77 | " exog = np.array( data[['Network Score','Satisfaction Score', 'PPO']])\n", 78 | " \n", 79 | " \n", 80 | " # number of other products (in different mkts)\n", 81 | " hausman_instr = data[['Market_ID','Plan_ID']].groupby('Plan_ID').count()\n", 82 | " hausman_instr = pd.merge(data[['Market_ID','Plan_ID']],\n", 83 | " hausman_instr[['Market_ID']], right_index=True, left_on = 'Plan_ID')\n", 84 | " hausman_instr = np.array([hausman_instr['Market_ID_y']]).transpose()\n", 85 | " \n", 86 | " #calc avg price in other markets\n", 87 | " hausman_instr2 = data[['Plan_ID','Premium']].groupby('Plan_ID').mean()\n", 88 | " hausman_instr2 = pd.merge(data[['Plan_ID']],\n", 89 | " hausman_instr2[['Premium']], right_index=True, left_on = 'Plan_ID')\n", 90 | " \n", 91 | " hausman_instr2 = np.array(hausman_instr2)[:,-1:]\n", 92 | " hausman_instr2 = (hausman_instr2*hausman_instr - exog[:,-1:])/(hausman_instr-1)\n", 93 | " \n", 94 | " #no of competitors\n", 95 | " BLP_instr = data[['Market_ID','Plan_ID']].groupby('Market_ID').count()\n", 96 | " BLP_instr = pd.merge(data[['Market_ID','Plan_ID']],\n", 97 | " BLP_instr[['Plan_ID']], right_index=True, left_on = 'Market_ID')\n", 98 | " BLP_instr = np.array([BLP_instr['Plan_ID_y']]).transpose()\n", 99 | " \n", 100 | " #average characteristics among competititors\n", 101 | " BLP_instr2 = data[['Market_ID','Network Score','Satisfaction Score']].groupby('Market_ID').mean()\n", 102 | " BLP_instr2 = pd.merge(data[['Market_ID']],\n", 103 | " BLP_instr2[['Network Score','Satisfaction Score']], right_index=True, left_on = 'Market_ID')\n", 104 | " BLP_instr2 = (np.array(BLP_instr2)[:,1:]*BLP_instr - exog[:,:-1])/(BLP_instr-1)\n", 105 | " \n", 106 | " #sum the characteristics together?\n", 107 | " BLP_instr2 = BLP_instr2.sum(axis=1).reshape((3300,1))\n", 108 | " \n", 109 | " #concat hausman instr with exog variables\n", 110 | " instr = np.concatenate( (exog, hausman_instr2, BLP_instr2), axis =1 ) \n", 111 | " return instr\n", 112 | "\n", 113 | "\n", 114 | "#pre process for testing\n", 115 | "x,y = setup_data(data)\n", 116 | "z = setup_hausman(data)\n", 117 | "X,Z = np.array(x), np.array(z)\n", 118 | "V = np.linalg.inv( z.transpose().dot(z) ) #set up initial weight matrix" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": 4, 124 | "metadata": {}, 125 | "outputs": [ 126 | { 127 | "name": "stdout", 128 | "output_type": "stream", 129 | "text": [ 130 | "600 16 3300\n" 131 | ] 132 | } 133 | ], 134 | "source": [ 135 | "#set up useful global variables \n", 136 | "NMKTS = data['Market_ID'].nunique()\n", 137 | "NPLANS = data['Plan_ID'].nunique()\n", 138 | "NOBS = data['Plan_ID'].count()\n", 139 | "NSIM = 50\n", 140 | "\n", 141 | "theta1 = np.array([4,1.5,.7,-1.5])\n", 142 | "theta2 = np.array([2,2,1]) # initialize theta2 for testing purposes\n", 143 | "delta = np.ones(NOBS)*(-2)\n", 144 | "\n", 145 | "#print global variables\n", 146 | "print NMKTS,NPLANS,NOBS" 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": {}, 152 | "source": [ 153 | "I set up my draws at the market level, so if observation $i$ and $j$ are in the same\n", 154 | "market, they have the same random draw.\n", 155 | "\n", 156 | "If they are in different markets, their draws will be different as well." 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": 5, 162 | "metadata": {}, 163 | "outputs": [], 164 | "source": [ 165 | "#set up random draws v\n", 166 | "\n", 167 | "def gen_newsim():\n", 168 | " mkt_ids = np.array(data['Market_ID'])\n", 169 | " v = [0]*NOBS\n", 170 | " for mkt in range(1,601):\n", 171 | " v_i = np.random.normal(size=(3,NSIM))\n", 172 | " for i in range(NOBS):\n", 173 | " if mkt_ids[i] == mkt:\n", 174 | " v[i] = v_i\n", 175 | " return np.array(v).transpose()\n", 176 | "\n", 177 | "v = gen_newsim()\n", 178 | "#np.savetxt(\"simulations.csv\", v.reshape(3*NSIM,3300), delimiter=\",\")" 179 | ] 180 | }, 181 | { 182 | "cell_type": "code", 183 | "execution_count": 6, 184 | "metadata": {}, 185 | "outputs": [], 186 | "source": [ 187 | "#use same simulations each time\n", 188 | "v = np.genfromtxt('simulations.csv', delimiter=',').reshape(NSIM,3,3300)" 189 | ] 190 | }, 191 | { 192 | "cell_type": "markdown", 193 | "metadata": {}, 194 | "source": [ 195 | "### Estimating coefficients" 196 | ] 197 | }, 198 | { 199 | "cell_type": "markdown", 200 | "metadata": {}, 201 | "source": [ 202 | "#### Calculating $\\delta_{jt}$, $\\xi_{jt}$\n", 203 | "\n", 204 | "The first part of the estimation involves calculating the mean utility with the BLP inversion and the mean unobservable. I follow Nevo (2000) for the calculation" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": 7, 210 | "metadata": {}, 211 | "outputs": [], 212 | "source": [ 213 | "def cal_sim_s(data, v, delta, theta2):\n", 214 | " \"\"\"calculate market share for each simulated consumer\"\"\"\n", 215 | " \n", 216 | " #copy x and delta for simulations using tiling\n", 217 | " x = np.array(data.copy()[['Network Score','Satisfaction Score','PPO']]).transpose()\n", 218 | " x = np.tile(x,(NSIM,1,1))\n", 219 | " theta2 = np.tile( np.array([theta2]).transpose() ,(NSIM,1,3300))\n", 220 | " delta = np.tile( delta ,(NSIM,1))\n", 221 | " \n", 222 | " # Compute the numerator for each market\n", 223 | " sim_exp = pd.DataFrame( np.exp(delta + (theta2*v*x).sum(axis=1)).transpose() ) \n", 224 | " \n", 225 | " #sum up between markets\n", 226 | " sim_exp['mkt_id'] = data['Market_ID']\n", 227 | " sum_exp = sim_exp.groupby('mkt_id').sum() \n", 228 | " sum_exp = pd.merge(data.copy()[['Market_ID']], sum_exp, \n", 229 | " right_index=True, left_on = 'Market_ID')\n", 230 | " \n", 231 | " #format so I can broadcast\n", 232 | " sim_exp = np.array(sim_exp).transpose()[:-1]\n", 233 | " sum_exp = np.array(sum_exp).transpose()[1:] + 1\n", 234 | " \n", 235 | " return sim_exp/sum_exp\n", 236 | "\n", 237 | "\n", 238 | "def cal_s(data, v, delta, theta2):\n", 239 | " \"\"\"Calculate market share\n", 240 | " Calculates individual choice probability first, then take sum\"\"\"\n", 241 | " \n", 242 | " shares = (1./NSIM)*cal_sim_s(data, v, delta, theta2).sum(axis=0)\n", 243 | " return shares" 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": 8, 249 | "metadata": {}, 250 | "outputs": [], 251 | "source": [ 252 | "def cal_delta(data, v, theta2, error = 1e-3, maxiter = 500):\n", 253 | " \"\"\"Calculate mean utility via contraction mapping\n", 254 | " described in BLP 1995\"\"\"\n", 255 | "\n", 256 | " niter = 0\n", 257 | " \n", 258 | " #initialize loop parameters\n", 259 | " delta = np.zeros(NOBS)\n", 260 | " s = cal_s(data, v, delta, theta2)\n", 261 | " diff = np.log(data['Inside Good Share']) - np.log(s)\n", 262 | " \n", 263 | " \n", 264 | " while ((abs(diff).max() > 1e-10) #this is easier to converge\n", 265 | " and (abs(diff).mean() > error) \n", 266 | " and niter < maxiter):\n", 267 | " \n", 268 | " s = cal_s(data, v, delta, theta2)\n", 269 | " diff = np.log(data['Inside Good Share']) - np.log(s)\n", 270 | "\n", 271 | " if np.isnan(diff).sum():\n", 272 | " raise Exception('nan in diffs')\n", 273 | " \n", 274 | " delta += diff\n", 275 | " niter += 1\n", 276 | "\n", 277 | " return delta" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": 9, 283 | "metadata": {}, 284 | "outputs": [], 285 | "source": [ 286 | "def cal_xi(data, delta, theta1):\n", 287 | " \"\"\"Calculate xi (i.e. mean 'unexplained' utility) with F.O.C.\"\"\"\n", 288 | " x,y = setup_data(data)\n", 289 | " explained = np.matmul(np.array(x),theta1)\n", 290 | " xi = delta - explained\n", 291 | " return xi" 292 | ] 293 | }, 294 | { 295 | "cell_type": "markdown", 296 | "metadata": {}, 297 | "source": [ 298 | "#### Calculating $\\theta_1,\\theta_2$\n", 299 | "\n", 300 | "Here the linear parameter $\\theta_1 = (\\alpha, \\beta)$\n", 301 | "\n", 302 | "I only solve GMM over $\\theta_2$, the non-linear parameters. $\\theta_1$ is calculated as a function of $\\delta$ using the formula from Nevo 2000\n", 303 | "\n", 304 | "$$\\hat{\\theta_1} = (X'Z V^{-1} Z'X)^{-1} X'Z V^{-1} Z' \\delta(\\hat{\\theta}_2) $$\n", 305 | "\n", 306 | "\n", 307 | "I calculate the covariance matrix for GMM following chapter 12 in Hansen's Econometrics textbook.\n", 308 | "\n", 309 | "Specifically, I used the formula:\n", 310 | "\n", 311 | "$$\\hat{V} = \\dfrac{1}{n} \\sum_n z_i z_i' \\hat{\\xi}_i^2 - \\overline{g}_n \\overline{g}_n'$$\n", 312 | "\n", 313 | "Where $$\\bar{g}_n = \\dfrac{1}{n} \\sum_n z_i \\hat{\\xi_i} $$" 314 | ] 315 | }, 316 | { 317 | "cell_type": "code", 318 | "execution_count": 10, 319 | "metadata": {}, 320 | "outputs": [], 321 | "source": [ 322 | "def calc_var(data, xi):\n", 323 | " \"\"\"calculate optimal covariance matrix\n", 324 | " for GMM \"\"\"\n", 325 | " x,y = setup_data(data)\n", 326 | " z = setup_hausman(data)\n", 327 | " X,Z = np.array(x), np.array(z)\n", 328 | " \n", 329 | " if xi.shape == (3300,):\n", 330 | " xi = np.array([xi]).transpose()\n", 331 | " \n", 332 | " gn = Z.transpose().dot(xi)\n", 333 | " gn = gn.dot(gn.transpose()) \n", 334 | " gn2 = np.zeros((5,5))\n", 335 | " \n", 336 | " for i in range(NOBS):\n", 337 | " Zi = np.array([Z[i]])\n", 338 | " gn2 = gn2 + Zi.transpose().dot(Zi) *(xi[i])**2\n", 339 | " \n", 340 | " return (1./NOBS)*(gn2 - gn)" 341 | ] 342 | }, 343 | { 344 | "cell_type": "code", 345 | "execution_count": 11, 346 | "metadata": {}, 347 | "outputs": [], 348 | "source": [ 349 | "def cal_theta1(data, delta, z, V):\n", 350 | " \"\"\" calculate theta_1 using FOCs \n", 351 | " \n", 352 | " (X1'Z T Z'X )^-1 X1'Z T Z' delta \"\"\"\n", 353 | " \n", 354 | " #set up variables\n", 355 | " x,y = setup_data(data)\n", 356 | " X,Z = np.array(x), np.array(z)\n", 357 | " \n", 358 | " #build up to main equation\n", 359 | " XtZ = X.transpose().dot(Z)\n", 360 | " ZtX = Z.transpose().dot(X)\n", 361 | " \n", 362 | " first_exp = np.linalg.inv( XtZ.dot(V).dot(ZtX))\n", 363 | " second_exp = XtZ.dot(V).dot(Z.transpose()).dot(delta)\n", 364 | " theta1 = first_exp.dot(second_exp)\n", 365 | " return theta1" 366 | ] 367 | }, 368 | { 369 | "cell_type": "code", 370 | "execution_count": 12, 371 | "metadata": {}, 372 | "outputs": [], 373 | "source": [ 374 | "def gmm_objective(theta2_init, data, v, z, V):\n", 375 | " \"\"\"calculate the GMM objective and minimize it to find theta_2\n", 376 | " \n", 377 | " I use the formula from Nevo 2000: w' z phi-1 z' w, of theta2\"\"\"\n", 378 | " \n", 379 | " #set up variables\n", 380 | " x,y = setup_data(data)\n", 381 | " X,Z = np.array(x), np.array(z)\n", 382 | " \n", 383 | " #do calculations\n", 384 | " delta = cal_delta(data, v, theta2_init)\n", 385 | " theta1 = cal_theta1(data, delta, z, V)\n", 386 | " xi = cal_xi(data, delta, theta1)\n", 387 | " \n", 388 | " xitZ = xi.transpose().dot(Z)\n", 389 | " Ztxi = Z.transpose().dot(xi)\n", 390 | " return xitZ.dot(V).dot(Ztxi)\n", 391 | " \n", 392 | "\n", 393 | "def calc_theta2(data, v, z, T, theta2_init,NM=True):\n", 394 | " \"\"\"calculate theta2 using scipy\"\"\"\n", 395 | " if NM:\n", 396 | " theta2 = minimize(gmm_objective, theta2_init, args=(data, v, z, T), method='Nelder-Mead',\n", 397 | " options={'xatol': 0.001, 'fatol': 0.1, 'maxiter':100, 'disp': True})\n", 398 | " else:\n", 399 | " theta2 = minimize(gmm_objective, theta2_init, args=(data, v, z, T), method='BFGS',\n", 400 | " options={'maxiter':100, 'disp': True})\n", 401 | " return abs(theta2.x)" 402 | ] 403 | }, 404 | { 405 | "cell_type": "code", 406 | "execution_count": 13, 407 | "metadata": { 408 | "scrolled": true 409 | }, 410 | "outputs": [ 411 | { 412 | "name": "stdout", 413 | "output_type": "stream", 414 | "text": [ 415 | "Optimization terminated successfully.\n", 416 | " Current function value: 0.000000\n", 417 | " Iterations: 31\n", 418 | " Function evaluations: 63\n", 419 | "Optimization terminated successfully.\n", 420 | " Current function value: 0.000000\n", 421 | " Iterations: 29\n", 422 | " Function evaluations: 57\n" 423 | ] 424 | } 425 | ], 426 | "source": [ 427 | "theta2_init = np.array([2,2,1])\n", 428 | "\n", 429 | "def calc_theta(data, v, theta2_init, stages=2):\n", 430 | " \"\"\"put everything together to calculate theta1 and theta2\"\"\"\n", 431 | " #initialize theta\n", 432 | " x,y = setup_data(data)\n", 433 | " z = setup_hausman(data)\n", 434 | " \n", 435 | " X,Z = np.array(x), np.array(z)\n", 436 | " theta2 = theta2_init \n", 437 | " \n", 438 | " #on first step, use consistent approximation of V\n", 439 | " V = np.linalg.inv( Z.transpose().dot(Z) )\n", 440 | " \n", 441 | " for i in range(stages): \n", 442 | " \n", 443 | " #on second use V using estimated xi\n", 444 | " if i==1:\n", 445 | " xi = cal_xi(data, delta, theta1)\n", 446 | " xi =np.array([xi]).transpose()\n", 447 | " V = np.linalg.inv( calc_var(data, xi) )\n", 448 | " \n", 449 | " theta2 = calc_theta2(data, v, z, V, theta2)\n", 450 | " delta = cal_delta(data, v, theta2)\n", 451 | " theta1 = cal_theta1(data, delta, z, V)\n", 452 | " \n", 453 | " return theta1, theta2\n", 454 | "\n", 455 | "theta = calc_theta(data, v, theta2_init, stages=2)" 456 | ] 457 | }, 458 | { 459 | "cell_type": "code", 460 | "execution_count": 14, 461 | "metadata": {}, 462 | "outputs": [ 463 | { 464 | "name": "stdout", 465 | "output_type": "stream", 466 | "text": [ 467 | "------------------------------------------------------------------\n", 468 | "Mean Coefficients \n", 469 | "------------------------------------------------------------------\n", 470 | " 0 1 2 3\n", 471 | "0 Network Score Satisfaction Score PPO Premium\n", 472 | "1 3.1582 1.65122 0.647288 -1.08951\n", 473 | "------------------------------------------------------------------\n", 474 | "Variance Coefficients\n", 475 | "------------------------------------------------------------------\n", 476 | " 0 1 2 3\n", 477 | "0 Network Score Satisfaction Score PPO Premium\n", 478 | "1 2.32968 2.16973 0.816625 None\n", 479 | "------------------------------------------------------------------\n" 480 | ] 481 | } 482 | ], 483 | "source": [ 484 | "print '------------------------------------------------------------------'\n", 485 | "print 'Mean Coefficients \\n------------------------------------------------------------------'\n", 486 | "labels1 = np.array(['Network Score','Satisfaction Score','PPO','Premium'])\n", 487 | "print pd.DataFrame([labels1, theta[0]])\n", 488 | "print '------------------------------------------------------------------'\n", 489 | "\n", 490 | "print 'Variance Coefficients'\n", 491 | "print '------------------------------------------------------------------'\n", 492 | "print pd.DataFrame([labels1, theta[1]])\n", 493 | "print '------------------------------------------------------------------'" 494 | ] 495 | }, 496 | { 497 | "cell_type": "code", 498 | "execution_count": 15, 499 | "metadata": {}, 500 | "outputs": [ 501 | { 502 | "name": "stdout", 503 | "output_type": "stream", 504 | "text": [ 505 | "(array([ 3.15820237, 1.65121504, 0.64728765, -1.08950616]), array([2.32968109, 2.16972611, 0.81662519]))\n" 506 | ] 507 | } 508 | ], 509 | "source": [ 510 | "#save xi and write to array for counterfactuals\n", 511 | "theta1_est, theta2_est = theta\n", 512 | "delta_est = cal_delta(data, v, theta2_est)\n", 513 | "xi_est = cal_xi(data, delta_est, theta1_est)\n", 514 | "\n", 515 | "np.savetxt(\"xi.csv\", xi_est, delimiter=\",\")\n", 516 | "print theta" 517 | ] 518 | }, 519 | { 520 | "cell_type": "markdown", 521 | "metadata": {}, 522 | "source": [ 523 | "### Calculating Standard Errors\n", 524 | "\n", 525 | "In order to calculate standard errors I used a numeric gradient.\n", 526 | "\n", 527 | "I tried following Nevo to calculate $\\dfrac{\\partial \\delta_{jt}}{\\partial \\theta_l}$ using the implicit function theorem. However, I was unable to complete this do to time constraints" 528 | ] 529 | }, 530 | { 531 | "cell_type": "code", 532 | "execution_count": 16, 533 | "metadata": {}, 534 | "outputs": [], 535 | "source": [ 536 | "def gradient_helper(theta1, theta2, data, v, z):\n", 537 | " \"\"\"w' z phi z' w, this function computes\n", 538 | " the perturbed value of the objective function\"\"\"\n", 539 | " #set up variables\n", 540 | " x,y = setup_data(data)\n", 541 | " X,Z = np.array(x), np.array(z)\n", 542 | " \n", 543 | " #do calculations\n", 544 | " delta = cal_delta(data, v, theta2)\n", 545 | " xi = cal_xi(data, delta, theta1)\n", 546 | " \n", 547 | " return xi.transpose().dot(Z)\n", 548 | "\n", 549 | "\n", 550 | "\n", 551 | "def gradient_numer(theta, data, v, z, h=1e-8):\n", 552 | " \"\"\"This function cylces through the coefficients and perturbs them to \n", 553 | " compute a numeric derivative\"\"\"\n", 554 | " gamma = []\n", 555 | " theta= np.concatenate(theta)\n", 556 | " for i in range(len(theta)):\n", 557 | " theta1 = theta[0:4]\n", 558 | " theta2 = theta[4:]\n", 559 | " fx = gradient_helper(theta1, theta2, data, v, z)\n", 560 | "\n", 561 | " #perturb theta\n", 562 | " theta_perturb = theta\n", 563 | " theta_perturb[i] = theta_perturb[i] + h\n", 564 | " theta1_perturb = theta_perturb[0:4]\n", 565 | " theta2_perturb = theta_perturb[4:]\n", 566 | " fx_plush = gradient_helper(theta1_perturb, theta2_perturb, data, v, z)\n", 567 | " \n", 568 | " #calculate gradient\n", 569 | " gamma_i = (fx_plush - fx)/h\n", 570 | " \n", 571 | " gamma.append(gamma_i)\n", 572 | " return np.array(gamma).transpose()" 573 | ] 574 | }, 575 | { 576 | "cell_type": "markdown", 577 | "metadata": {}, 578 | "source": [ 579 | "Below I have calculated standard errors using the formula $$(\\Gamma' A \\Gamma)^{-1}(\\Gamma' A V A \\Gamma)^{-1} (\\Gamma' A \\Gamma)^{-1}$$\n", 580 | "\n", 581 | "Where $\\Gamma$ is a numeric approximation of the gradient $A$ is the initial weighting matrix and $V$ is the covaraince matrix (also the optimal weight matrix)" 582 | ] 583 | }, 584 | { 585 | "cell_type": "code", 586 | "execution_count": 17, 587 | "metadata": {}, 588 | "outputs": [], 589 | "source": [ 590 | "def cal_standard_errors(theta, xi, data, v):\n", 591 | " \"\"\"Put everything together to compute standard\n", 592 | " errors\"\"\"\n", 593 | " \n", 594 | " #setup variables\n", 595 | " xi =np.array([xi]).transpose()\n", 596 | " x,y = setup_data(data)\n", 597 | " z = setup_hausman(data)\n", 598 | " \n", 599 | " #set up weight matrices\n", 600 | " X,Z = np.array(x), np.array(z)\n", 601 | " V = calc_var(data, xi)\n", 602 | " A = np.linalg.inv( Z.transpose().dot(Z) )\n", 603 | " G = gradient_numer(theta, data, v, Z)\n", 604 | " \n", 605 | " GAG_inv = np.linalg.inv( G.transpose().dot(A).dot(G) )\n", 606 | " GAVAG = G.transpose().dot(A).dot(V).dot(A).dot(G)\n", 607 | " \n", 608 | " return GAG_inv.dot(GAVAG).dot(GAG_inv)/NOBS\n", 609 | "\n", 610 | "se = np.sqrt ( abs (cal_standard_errors(theta, xi_est, data, v) ) )/NOBS\n", 611 | "\n", 612 | "se1 = np.diagonal(se)[:4]\n", 613 | "se2 = np.diagonal(se)[4:]" 614 | ] 615 | }, 616 | { 617 | "cell_type": "markdown", 618 | "metadata": {}, 619 | "source": [ 620 | "Below we can see the standard errors calculated using the formula." 621 | ] 622 | }, 623 | { 624 | "cell_type": "code", 625 | "execution_count": 18, 626 | "metadata": {}, 627 | "outputs": [ 628 | { 629 | "name": "stdout", 630 | "output_type": "stream", 631 | "text": [ 632 | "------------------------------------------------------------------\n", 633 | "Mean Coefficients (Standard Error) \n", 634 | "------------------------------------------------------------------\n", 635 | " 0 1 2 3\n", 636 | "0 Network Score Satisfaction Score PPO Premium\n", 637 | "1 0.233099 0.155631 0.0849477 0.0315459\n", 638 | "------------------------------------------------------------------\n", 639 | "Coefficients Variance (Standard Error)\n", 640 | "------------------------------------------------------------------\n", 641 | " 0 1 2 3\n", 642 | "0 Network Score Satisfaction Score PPO Premium\n", 643 | "1 0.151254 0.847477 0.726318 None\n", 644 | "------------------------------------------------------------------\n" 645 | ] 646 | } 647 | ], 648 | "source": [ 649 | "print '------------------------------------------------------------------'\n", 650 | "print 'Mean Coefficients (Standard Error) \\n------------------------------------------------------------------'\n", 651 | "labels1 = np.array(['Network Score','Satisfaction Score','PPO','Premium'])\n", 652 | "print pd.DataFrame([labels1, se1])\n", 653 | "print '------------------------------------------------------------------'\n", 654 | "\n", 655 | "print 'Coefficients Variance (Standard Error)'\n", 656 | "print '------------------------------------------------------------------'\n", 657 | "print pd.DataFrame([labels1,se2])\n", 658 | "print '------------------------------------------------------------------'" 659 | ] 660 | }, 661 | { 662 | "cell_type": "code", 663 | "execution_count": null, 664 | "metadata": {}, 665 | "outputs": [], 666 | "source": [] 667 | } 668 | ], 669 | "metadata": { 670 | "kernelspec": { 671 | "display_name": "Python 2", 672 | "language": "python", 673 | "name": "python2" 674 | }, 675 | "language_info": { 676 | "codemirror_mode": { 677 | "name": "ipython", 678 | "version": 2 679 | }, 680 | "file_extension": ".py", 681 | "mimetype": "text/x-python", 682 | "name": "python", 683 | "nbconvert_exporter": "python", 684 | "pygments_lexer": "ipython2", 685 | "version": "2.7.15" 686 | } 687 | }, 688 | "nbformat": 4, 689 | "nbformat_minor": 2 690 | } 691 | -------------------------------------------------------------------------------- /hw2_io/Problem Set 2 2018.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ericschulman/struct/260ee95ac8e364bc49d9bb54b484f138759ba904/hw2_io/Problem Set 2 2018.pdf -------------------------------------------------------------------------------- /hw3/Rust.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Assignment 3: Structural Econometrics\n", 8 | "## Eric Schulman\n", 9 | "\n", 10 | "Solutions to ECO 388E assignment 3 at the University of Texas written by Eric Schulman in collaboration with Lauri Kytomma and Ivan Larsen" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 1, 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "import pandas as pd\n", 20 | "import math\n", 21 | "import numpy as np\n", 22 | "import statsmodels.api as sm\n", 23 | "import matplotlib.pyplot as plt\n", 24 | "\n", 25 | "from scipy.interpolate import interp1d #pre written interpolation function\n", 26 | "from statsmodels.base.model import GenericLikelihoodModel" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": {}, 32 | "source": [ 33 | "### Part 1\n", 34 | "\n", 35 | "The value for a machine of age $a_t$ is\n", 36 | "\n", 37 | "$$ V(a_t, \\epsilon_t; \\theta) = \\underset{i_t}{max} E[\\sum_{\\tau=t}^\\infty \\beta^{\\tau-t}\\pi(a_\\tau, i_\\tau, \\epsilon_{\\tau}, ;\\theta)|a_t; \\theta] $$ \n", 38 | "\n", 39 | "\n", 40 | "As a result we can write a Bellman equation for the firm maximizing future profits is expressed below:\n", 41 | "\n", 42 | "$$V(a_t,\\epsilon_{0t},\\epsilon_{1t}) = max_{i_{t}} \\pi(a_t, i_t, \\epsilon_{1t}, \\epsilon_{0t}) + \\beta E[V(a_{t+1},\\epsilon_{0t+1},\\epsilon_{1t+1}) |a_t, i_t; \\theta]$$\n", 43 | "\n", 44 | "Because of the conditional independence assumption $\\epsilon_{it}$ is not serially correlated.\n", 45 | "\n", 46 | "### Part 2\n", 47 | "\n", 48 | "In class, $x_t$ was continuous. Here $a_t$ is discrete. Additionally, we did not parameterize $c(x_t, \\theta)$. Here $c(a_t,\\theta) = \\theta a_t$. As a result, $c(0,\\theta) = 0$ Technically, $a_t =0$ is not a feasible state." 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": {}, 54 | "source": [ 55 | "### Part 3\n", 56 | "\n", 57 | "The code below is designed to calculate the value function using forward recursion. We determine the initial value using a contraction mapping iterating forward until it converges.\n", 58 | "\n", 59 | "The value function is a 5x2 array. The rows contain the values when the state is $a_t$. The columns contain the value based on $i_t$." 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 2, 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "BETA = .9\n", 69 | "GAMMA = .5772 #euler's constant\n", 70 | "\n", 71 | "def nextperiod(v):\n", 72 | " \"\"\"cycle the value function so, the last 2 periods are the same\"\"\"\n", 73 | " return np.concatenate( (v[1:],[v[-1]]) )\n", 74 | " \n", 75 | " \n", 76 | "def operator(a_max, theta1, cost, v0, v1):\n", 77 | " \"\"\"perform the operator for the Rust contraction mapping\"\"\"\n", 78 | " a = np.arange(1,a_max+1)\n", 79 | " \n", 80 | " v0_next = theta1*a + BETA*(GAMMA + np.log(np.exp(nextperiod(v0))\n", 81 | " + np.exp(nextperiod(v1)))) \n", 82 | " \n", 83 | " v1_next = cost + BETA*(GAMMA + np.log(np.exp(v0[0]) + np.exp(v1[0])))\n", 84 | " \n", 85 | " #tile so that v0 and v1 have the same dimension\n", 86 | " v1_next = np.tile(v1_next,a_max)\n", 87 | " \n", 88 | " return np.array([v0_next, v1_next])\n", 89 | "\n", 90 | "\n", 91 | "def value_function(a, theta1, cost, error, maxiter):\n", 92 | " \"\"\"calculate the Rust value function using a contraction mapping\"\"\"\n", 93 | " \n", 94 | " #initialize loop variables\n", 95 | " v0, v1 = np.ones(a), np.ones(a)\n", 96 | " v0_next, v1_next = operator(a, theta1, cost, v0, v1)\n", 97 | " \n", 98 | " while maxiter >= 0 and ( \n", 99 | " np.abs(v0 - v0_next ).max() > error\n", 100 | " or np.abs(v1 - v1_next ).max() > error ):\n", 101 | " \n", 102 | " #iterate loop variables\n", 103 | " v0, v1 = v0_next, v1_next\n", 104 | " v0_next, v1_next = operator(a, theta1, cost, v0, v1)\n", 105 | " maxiter = maxiter -1\n", 106 | "\n", 107 | " return np.array([v0_next, v1_next])" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "### Part 4\n", 115 | "\n", 116 | "* Below I solve the model when $\\theta_1 = -1$ and $R = -3$. \n", 117 | "\n", 118 | "* When $a_t = 2$, we can see that $V(2,0) - V(2,1) = 1$ so the firm chooses not to replace the engine. If the value of $\\epsilon_{0t} - \\epsilon_{1t}$ exceeds 1, then the firm will choose to replace the engine in period 2.\n", 119 | "\n", 120 | "* I calculate the probability of this difference below using the exterme value distribution.\n", 121 | "\n", 122 | "* Below I also calulate the value function when $a_t = 4$, $\\epsilon_{0t} = 1$ and $\\epsilon_{1t} =-1.5$. It is still cheaper to replace this period than to wait until period 5 to replace." 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": 76, 128 | "metadata": {}, 129 | "outputs": [ 130 | { 131 | "name": "stdout", 132 | "output_type": "stream", 133 | "text": [ 134 | "1. Value Function:\n", 135 | " 0 1 2 3 4\n", 136 | "0 -10.160666 -11.508696 -12.649107 -13.702107 -14.702107\n", 137 | "1 -11.394208 -11.394208 -11.394208 -11.394208 -11.394208\n", 138 | "\n", 139 | "2. V(2,0) - V(2,1) = -0.11448797184436543\n", 140 | "\n", 141 | "3. Likelihood: 0.5285907703313698\n", 142 | "\n", 143 | "4. PDV: -14.75478735241021\n" 144 | ] 145 | } 146 | ], 147 | "source": [ 148 | "THETA1, R = -1,-3\n", 149 | "\n", 150 | "v = value_function(5, THETA1, R, .001 , 100)\n", 151 | "print '1. Value Function:'\n", 152 | "print pd.DataFrame(v)\n", 153 | "\n", 154 | "#difference between e0 and e1\n", 155 | "diff = v[0,1] - v[1,1]\n", 156 | "print '\\n2. V(2,0) - V(2,1) = %s'%diff\n", 157 | "\n", 158 | "#probability of this different\n", 159 | "print '\\n3. Likelihood: %s'%( np.exp(-diff)/(1+np.exp(-diff)) )\n", 160 | "\n", 161 | "#PDV \n", 162 | "a, e0, e1 = 4,1,-1.5\n", 163 | "print '\\n4. PDV: %s'%np.maximum(THETA1*a + e0 + BETA*v[0,a], R + e1 + BETA*v[1,a] )" 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "metadata": {}, 169 | "source": [ 170 | "### Part 5 - 6 \n", 171 | "\n", 172 | "Below I calculate the value of $\\theta_1$ and $R$ and standard errors. \n", 173 | "\n", 174 | "The likelihood of $i_t$ is conditional on $a_t$ because my decision to replace this period depends on how old the engine is. The expected future costs, which I base my decision on, depend on the current age of the engine." 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": 15, 180 | "metadata": {}, 181 | "outputs": [], 182 | "source": [ 183 | "#load data into memory for part 5\n", 184 | "data = np.loadtxt(\"data.asc\")" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": 78, 190 | "metadata": {}, 191 | "outputs": [ 192 | { 193 | "name": "stdout", 194 | "output_type": "stream", 195 | "text": [ 196 | "Optimization terminated successfully.\n", 197 | " Current function value: 0.424159\n", 198 | " Iterations: 57\n", 199 | " Function evaluations: 108\n", 200 | " Rust Results \n", 201 | "==============================================================================\n", 202 | "Dep. Variable: y Log-Likelihood: -424.16\n", 203 | "Model: Rust AIC: 850.3\n", 204 | "Method: Maximum Likelihood BIC: 855.2\n", 205 | "Date: Fri, 21 Dec 2018 \n", 206 | "Time: 12:16:49 \n", 207 | "No. Observations: 1000 \n", 208 | "Df Residuals: 999 \n", 209 | "Df Model: 0 \n", 210 | "==============================================================================\n", 211 | " coef std err z P>|z| [0.025 0.975]\n", 212 | "------------------------------------------------------------------------------\n", 213 | "theta_1 -1.1484 0.076 -15.100 0.000 -1.297 -0.999\n", 214 | "R -4.4465 0.325 -13.668 0.000 -5.084 -3.809\n", 215 | "==============================================================================\n" 216 | ] 217 | } 218 | ], 219 | "source": [ 220 | "class Rust(GenericLikelihoodModel):\n", 221 | " \"\"\"class for estimating the values of R and theta\"\"\"\n", 222 | " \n", 223 | " def nloglikeobs(self, params, v=False):\n", 224 | " \n", 225 | " theta1, R = params\n", 226 | " \n", 227 | " # Input our data into the model\n", 228 | " i = self.exog[:,0] #reshape\n", 229 | " a = self.endog.astype(int)\n", 230 | " \n", 231 | " #solve value function based on params\n", 232 | " v = value_function(5, theta1, R, .001 , 100)\n", 233 | " \n", 234 | " #interpolate using scipy (easier than indexing)\n", 235 | " v0 = interp1d(range(1,6), v[0,:],fill_value=\"extrapolate\")\n", 236 | " v1 = interp1d(range(1,6), v[1,:],fill_value=\"extrapolate\")\n", 237 | " \n", 238 | " diff = v1(a) - v0(a)\n", 239 | " \n", 240 | " #calculate likelihood of each obs\n", 241 | " pr0 = 1/(1+np.exp(diff))\n", 242 | " pr1 = np.exp(diff)/(1+np.exp(diff))\n", 243 | "\n", 244 | " likelihood = (1-i)*pr0 + i*pr1\n", 245 | " return -np.log(likelihood).sum()\n", 246 | " \n", 247 | " \n", 248 | " def fit(self, start_params=None, maxiter=1000, maxfun=5000, **kwds):\n", 249 | " if start_params == None:\n", 250 | " start_params = [1,1]\n", 251 | " return super(Rust, self).fit(start_params=start_params,\n", 252 | " maxiter=maxiter, maxfun=maxfun, **kwds)\n", 253 | " \n", 254 | " \n", 255 | "model = Rust(data[:,0],data[:,1])\n", 256 | "\n", 257 | "result = model.fit()\n", 258 | "print(result.summary(xname=['theta_1', 'R']))" 259 | ] 260 | }, 261 | { 262 | "cell_type": "markdown", 263 | "metadata": {}, 264 | "source": [ 265 | "### Part 7\n", 266 | "\n", 267 | "#### Section A\n", 268 | "\n", 269 | "To accomodate $\\theta_{1A}$ and $\\theta_{1B}$ we would need to modify the dynamic program as follows\n", 270 | "\n", 271 | "$$V_j(a_{t},i_t,\\epsilon_{it}) = \\pi(a_t, i_t, \\epsilon_{jt}; \\theta_j) + max_{i_{t+1}} \\beta E(V_j(a_{t+1},i_{t+1},\\epsilon_{jt+1}) |a_t, \\epsilon_{it}, i_t; \\theta_j)$$\n", 272 | "\n", 273 | "Now, there is an $j$ subscript on $\\theta$. In principle, this means we will have to calculate two different value functions using the contraction mapping. The likelihood of replacing or not $i_j$. \n", 274 | "\n", 275 | "\n", 276 | "$$Pr(i_j =1 | a_j, \\epsilon_{jt} ) = \\alpha Pr(i_j =1 | a_j, \\epsilon_{jt} ; \\theta_{1A}) + (1-\\alpha) Pr(i_j =1 | a_j, \\epsilon_{jt} ; \\theta_{1A}) $$\n", 277 | "\n", 278 | "Using the extreme value distribution and conditional independence. This is given by:\n", 279 | "\n", 280 | "$$ = \\alpha \\dfrac{e^{V_{1A}(a_j, \\epsilon_{jt})}}{e^{V_{0A}(a_j, \\epsilon_{jt})} + e^{V_{1A}(a_j, \\epsilon_{jt})}} + (1-\\alpha) \\dfrac{e^{V_{1B}(a_j, \\epsilon_{jt})}}{e^{V_{0B}(a_j, \\epsilon_{jt})} + e^{V_{1B}(a_j, \\epsilon_{jt})}}$$\n", 281 | "\n", 282 | "#### Section B\n", 283 | "\n", 284 | "We must now consider the likelihood of a sequence of decisions $ \\{i(a_{jt},\\epsilon_{jt}) = 1\\}_{t