my-markdown-library 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/F24LS_md/ Lecture 4 - Public.md +347 -0
- data/F24LS_md/Lecture 1 - Introduction and Overview.md +327 -0
- data/F24LS_md/Lecture 10 - Development_.md +631 -0
- data/F24LS_md/Lecture 11 - Econometrics.md +345 -0
- data/F24LS_md/Lecture 12 - Finance.md +692 -0
- data/F24LS_md/Lecture 13 - Environmental Economics.md +299 -0
- data/F24LS_md/Lecture 15 - Conclusion.md +272 -0
- data/F24LS_md/Lecture 2 - Demand.md +349 -0
- data/F24LS_md/Lecture 3 - Supply.md +329 -0
- data/F24LS_md/Lecture 5 - Production C-D.md +291 -0
- data/F24LS_md/Lecture 6 - Utility and Latex.md +440 -0
- data/F24LS_md/Lecture 7 - Inequality.md +607 -0
- data/F24LS_md/Lecture 8 - Macroeconomics.md +704 -0
- data/F24LS_md/Lecture 8 - Macro.md +700 -0
- data/F24LS_md/Lecture 9 - Game Theory_.md +436 -0
- data/F24LS_md/summary.yaml +105 -0
- data/F24Lec_MD/LecNB_summary.yaml +206 -0
- data/F24Lec_MD/lec01/lec01.md +267 -0
- data/F24Lec_MD/lec02/Avocados_demand.md +425 -0
- data/F24Lec_MD/lec02/Demand_Steps_24.md +126 -0
- data/F24Lec_MD/lec02/PriceElasticity.md +83 -0
- data/F24Lec_MD/lec02/ScannerData_Beer.md +171 -0
- data/F24Lec_MD/lec02/demand-curve-Fa24.md +213 -0
- data/F24Lec_MD/lec03/3.0-CubicCostCurve.md +239 -0
- data/F24Lec_MD/lec03/3.1-Supply.md +274 -0
- data/F24Lec_MD/lec03/3.2-sympy.md +332 -0
- data/F24Lec_MD/lec03/3.3a-california-energy.md +120 -0
- data/F24Lec_MD/lec03/3.3b-a-really-hot-tuesday.md +121 -0
- data/F24Lec_MD/lec04/lec04-CSfromSurvey-closed.md +335 -0
- data/F24Lec_MD/lec04/lec04-CSfromSurvey.md +331 -0
- data/F24Lec_MD/lec04/lec04-Supply-Demand-closed.md +519 -0
- data/F24Lec_MD/lec04/lec04-Supply-Demand.md +514 -0
- data/F24Lec_MD/lec04/lec04-four-plot-24.md +34 -0
- data/F24Lec_MD/lec04/lec04-four-plot.md +34 -0
- data/F24Lec_MD/lec05/Lec5-Cobb-Douglas.md +131 -0
- data/F24Lec_MD/lec05/Lec5-CobbD-AER1928.md +283 -0
- data/F24Lec_MD/lec06/6.1-Sympy-Differentiation.md +253 -0
- data/F24Lec_MD/lec06/6.2-3D-utility.md +287 -0
- data/F24Lec_MD/lec06/6.3-QuantEcon-Optimization.md +399 -0
- data/F24Lec_MD/lec06/6.4-latex.md +138 -0
- data/F24Lec_MD/lec06/6.5-Edgeworth.md +269 -0
- data/F24Lec_MD/lec07/7.1-inequality.md +283 -0
- data/F24Lec_MD/lec07/7.2-historical-inequality.md +237 -0
- data/F24Lec_MD/lec08/macro-fred-api.md +313 -0
- data/F24Lec_MD/lec09/lecNB-prisoners-dilemma.md +88 -0
- data/F24Lec_MD/lec10/Lec10.2-waterguard.md +401 -0
- data/F24Lec_MD/lec10/lec10.1-mapping.md +199 -0
- data/F24Lec_MD/lec11/11.1-slr.md +305 -0
- data/F24Lec_MD/lec11/11.2-mlr.md +171 -0
- data/F24Lec_MD/lec12/Lec12-4-PersonalFinance.md +590 -0
- data/F24Lec_MD/lec12/lec12-1_Interest_Payments.md +267 -0
- data/F24Lec_MD/lec12/lec12-2-stocks-options.md +235 -0
- data/F24Lec_MD/lec13/Co2_ClimateChange.md +139 -0
- data/F24Lec_MD/lec13/ConstructingMAC.md +213 -0
- data/F24Lec_MD/lec13/EmissionsTracker.md +170 -0
- data/F24Lec_MD/lec13/KuznetsHypothesis.md +219 -0
- data/F24Lec_MD/lec13/RoslingPlots.md +217 -0
- data/F24Lec_MD/lec15/vibecession.md +485 -0
- data/F24Textbook_MD/00-intro/index.md +292 -0
- data/F24Textbook_MD/01-demand/01-demand.md +152 -0
- data/F24Textbook_MD/01-demand/02-example.md +131 -0
- data/F24Textbook_MD/01-demand/03-log-log.md +284 -0
- data/F24Textbook_MD/01-demand/04-elasticity.md +248 -0
- data/F24Textbook_MD/01-demand/index.md +15 -0
- data/F24Textbook_MD/02-supply/01-supply.md +203 -0
- data/F24Textbook_MD/02-supply/02-eep147-example.md +86 -0
- data/F24Textbook_MD/02-supply/03-sympy.md +138 -0
- data/F24Textbook_MD/02-supply/04-market-equilibria.md +204 -0
- data/F24Textbook_MD/02-supply/index.md +16 -0
- data/F24Textbook_MD/03-public/govt-intervention.md +73 -0
- data/F24Textbook_MD/03-public/index.md +10 -0
- data/F24Textbook_MD/03-public/surplus.md +351 -0
- data/F24Textbook_MD/03-public/taxes-subsidies.md +282 -0
- data/F24Textbook_MD/04-production/index.md +15 -0
- data/F24Textbook_MD/04-production/production.md +178 -0
- data/F24Textbook_MD/04-production/shifts.md +296 -0
- data/F24Textbook_MD/05-utility/budget-constraints.md +166 -0
- data/F24Textbook_MD/05-utility/index.md +15 -0
- data/F24Textbook_MD/05-utility/utility.md +136 -0
- data/F24Textbook_MD/06-inequality/historical-inequality.md +253 -0
- data/F24Textbook_MD/06-inequality/index.md +15 -0
- data/F24Textbook_MD/06-inequality/inequality.md +226 -0
- data/F24Textbook_MD/07-game-theory/bertrand.md +257 -0
- data/F24Textbook_MD/07-game-theory/cournot.md +333 -0
- data/F24Textbook_MD/07-game-theory/equilibria-oligopolies.md +96 -0
- data/F24Textbook_MD/07-game-theory/expected-utility.md +61 -0
- data/F24Textbook_MD/07-game-theory/index.md +19 -0
- data/F24Textbook_MD/07-game-theory/python-classes.md +340 -0
- data/F24Textbook_MD/08-development/index.md +35 -0
- data/F24Textbook_MD/09-macro/CentralBanks.md +101 -0
- data/F24Textbook_MD/09-macro/Indicators.md +77 -0
- data/F24Textbook_MD/09-macro/fiscal_policy.md +36 -0
- data/F24Textbook_MD/09-macro/index.md +14 -0
- data/F24Textbook_MD/09-macro/is_curve.md +76 -0
- data/F24Textbook_MD/09-macro/phillips_curve.md +70 -0
- data/F24Textbook_MD/10-finance/index.md +10 -0
- data/F24Textbook_MD/10-finance/options.md +178 -0
- data/F24Textbook_MD/10-finance/value-interest.md +60 -0
- data/F24Textbook_MD/11-econometrics/index.md +16 -0
- data/F24Textbook_MD/11-econometrics/multivariable.md +218 -0
- data/F24Textbook_MD/11-econometrics/reading-econ-papers.md +25 -0
- data/F24Textbook_MD/11-econometrics/single-variable.md +483 -0
- data/F24Textbook_MD/11-econometrics/statsmodels.md +58 -0
- data/F24Textbook_MD/12-environmental/KuznetsHypothesis-Copy1.md +187 -0
- data/F24Textbook_MD/12-environmental/KuznetsHypothesis.md +187 -0
- data/F24Textbook_MD/12-environmental/MAC.md +254 -0
- data/F24Textbook_MD/12-environmental/index.md +36 -0
- data/F24Textbook_MD/LICENSE.md +11 -0
- data/F24Textbook_MD/intro.md +26 -0
- data/F24Textbook_MD/references.md +25 -0
- data/F24Textbook_MD/summary.yaml +414 -0
- metadata +155 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
---
|
2
|
+
title: equilibria-oligopolies
|
3
|
+
type: textbook
|
4
|
+
source_path: content/07-game-theory/equilibria-oligopolies.ipynb
|
5
|
+
chapter: 7
|
6
|
+
---
|
7
|
+
|
8
|
+
```python
|
9
|
+
from datascience import *
|
10
|
+
import matplotlib.pyplot as plt
|
11
|
+
import numpy as np
|
12
|
+
import pandas as pd
|
13
|
+
import datetime as dt
|
14
|
+
import warnings
|
15
|
+
warnings.simplefilter("ignore")
|
16
|
+
import plotly.graph_objects as go
|
17
|
+
from plotly.offline import plot
|
18
|
+
from IPython.display import display, HTML
|
19
|
+
%matplotlib inline
|
20
|
+
```
|
21
|
+
|
22
|
+
# Equilibria & Oligopolies
|
23
|
+
|
24
|
+
This section introduces the concept of equilibria in games, the paradigm of the prisoner's dilemma, and oligopolies. These concepts are essential to understanding the models we will be studying the next sections, and for relating game theory to its economic applications.
|
25
|
+
|
26
|
+
## Equilibrium
|
27
|
+
|
28
|
+
The [prisoner's dilemma](https://en.wikipedia.org/wiki/Prisoner%27s_dilemma) is a classic game first discussed by Merrill Flood and Melvin Dresher in 1950. In this game, there are two prisoners who have been captured and are being interrogated. The prisoners cannot contact each other in any way. They have two options: they can **defect** (betray the other prisoner to the police) or they can **cooperate** (maintain their silence). If both defect, both receive 4 years in prison. If one defects and the other does not, the defector goes free and the cooperator receives 5 years in prison. If both cooperate (meaning neither talks to the police), then they each receive 2 years in prison. We define **mutual defection** as the case when both prisoners defect and **mutual cooperation** as the case when both cooperate. The purpose of this game is to consider how a completely rational person would be best advised to proceed, and how different strategies for playing this game can be more or less effective.
|
29
|
+
|
30
|
+

|
31
|
+
|
32
|
+
In the above payoff matrix, we see that if Prisoner A cooperates and Prisoner B defects, then Prisoner A gets 5 years in prisoner and Prisoner B gets none. It is important to note that the above payoff matrix is inverted; because we are talking about _years in prison_ as opposed to utility, a higher value is **worse** for the player, and a player's goal is to _minimize_ their value in the payoff matrix, not maximize it as normally. We will use this payoff matrix convention when discussing the prisoner's dilemma, but _not_ with other games.
|
33
|
+
|
34
|
+
An important concept in game theory is finding the equilibrium of a game. There are different types of equilibria, but the most common one considered is the **Nash equilibrium**, named for the mathematician John Forbes Nash, Jr. (who you may remember as a character played by Russel Crowe in [_A Beautiful Mind_](https://en.wikipedia.org/wiki/A_Beautiful_Mind_(film))). A Nash equilibrium occurs when no player can increase their own payoff by changing only their own strategy.
|
35
|
+
|
36
|
+
```{admonition} Definition
|
37
|
+
A **Nash equilibrium** is a set of strategy choices in a non-cooperative game in which each player, assumed to know the equilibrium strategies of the other players, has a chosen strategy and there can be no monotonic improvement; that is, no player can increase their payoffs by changing their strategy without another player changing _their_ strategy.
|
38
|
+
```
|
39
|
+
|
40
|
+
Using this definition, what constitutes a Nash equilibrium for the prisoner's dilemma? Well let's consider the four possible combinations of strategies. (We use "D" as shorthand for "defect" and "C" for "cooperate" below.)
|
41
|
+
|
42
|
+
1. **Prisoner A: C, Prisoner B: C.** In this case, both Prisoner A and Prisoner B get 2 years. However, if Prisoner A's strategy remains unchanged, Prisoner B can get fewer years in prison by changing to D, and vice versa. Thus, this is **not** a Nash equilibrium.
|
43
|
+
2. **Prisoner A: D, Prisoner B: C.** In this case, Prisoner B can change to D and lower their years from 5 to 4. Thus, this is **not** a Nash equilibrium.
|
44
|
+
3. **Prisoner A: C, Prisoner B: D.** As with (2), Prisoner A can change to D and lower their years in prison. Thus, this is **not** a Nash equilibrium.
|
45
|
+
4. **Prisoner A: D, Prisoner B: D.** In this case, if Prisoner A changes to C, then their years in prison _increases_ from 4 to 5, as with Prisoner B. Neither player can increase their winnings (decrease their years in prison) by changing their strategy. Thus, this **is** a Nash equilibrium, with both Prisoner A and Prisoner B getting 4 years.
|
46
|
+
|
47
|
+
By describing the four states of the game, we see that only mutual defection is a Nash equilibrium of the prisoner's dilemma.
|
48
|
+
|
49
|
+
```{admonition} Nash equilibria in payoff matrices
|
50
|
+
:class: tip
|
51
|
+
|
52
|
+
It is easy to use a payoff matrix to see which states, if any, are Nash equilibria. To see if a game state is a Nash equilibrium, the first value in the cell must be the maximum among all first values in that column and the second value must be the maximum across all second values in that row. This is because moving up and down a column represents changing the row-player's strategy and moving along a row represents changing the column-player's strategy. If these values are both maxima in their respective directions, then no player can obtain a better payoff by unilaterally changing their strategy, and we have a Nash equilibrium.
|
53
|
+
|
54
|
+
You can easily verify this by looking at the payoff matrix for the prisoner's dilemma: the first 4 in mutual defection has the best payoff in the column and the second 4 has the best payoff in the row.
|
55
|
+
```
|
56
|
+
|
57
|
+
## Oligopolies
|
58
|
+
|
59
|
+
One of the most common applications of game theory in economics is the study of **oligopolies**, markets where the number of participants is limited. There are several examples of oligopolies that we experience without knowing in daily life: airlines, soft drinks, and telecom providers, to name a few. Oligopolies are different from regular markets in that they allow their participants to function similar to a monopoly by setting prices as a group; groups of participants conspiring on this kind of illicit activity are referred to as **cartels**.
|
60
|
+
|
61
|
+
Within oligopolies, however, we can observe competition more like a normal market as firms attempt to take market share from one another. When cartels set prices (by limiting the production of the good or service provided by their market), a firm can make a bid for market share by ignoring the agreed-upon production level and producing more. This has the effect of lowering the price of the good but the increase in production by the renegade firm will allow them to make up for the lost marginal revenue through increased sales volume. In this way, oligopoly members can compete against each other, making the market more and more competitive.
|
62
|
+
|
63
|
+
A prime example of this type of within-cartel competition was observed in the [2020 oil price war between Russia and Saudi Arabia](https://en.wikipedia.org/wiki/2020_Russia%E2%80%93Saudi_Arabia_oil_price_war). Both countries are members of [OPEC (the Organization of Petroleum Exporting Countries)](https://en.wikipedia.org/wiki/OPEC), an oil cartel that consists of 12 member countries controlling 79% of the world's oil reserves and 44% of oil production. OPEC sets oil prices by limiting the output of its member countries (a decrease in production results in higher prices).
|
64
|
+
|
65
|
+
The price war began when Saudi Arabia discounted its oil in response to Russia's refusal to reduce production in accordance with OPEC's directive. OPEC's members had agreed to reduce oil production due to a low forecasted demand for oil due to the COVID-19 pandemic. When Russia (who was not an official member of OPEC but had agreed to cooperate with Saudi Arabia to manage oil prices) didn't abide by OPEC's decision, Saudi Arabia announced discounts on its oil, starting the price war and leading to a massive drop in the price of oil. We can see the effects of this price war by looking at the price per barrel of OPEC's crude oil, plotted below.
|
66
|
+
|
67
|
+
```python
|
68
|
+
# data from https://www.quandl.com/data/OPEC/ORB-OPEC-Crude-Oil-Price
|
69
|
+
opec = pd.read_csv("opec_prices.csv")
|
70
|
+
opec["Date"] = opec["Date"].apply(pd.to_datetime)
|
71
|
+
opec = opec[opec["Date"] >= dt.datetime(2019, 7, 1)]
|
72
|
+
start_date = dt.datetime(2020, 3, 8)
|
73
|
+
|
74
|
+
fig = go.Figure()
|
75
|
+
fig.add_trace(go.Scatter(x=opec["Date"], y=opec["Value"], name="OPEC Crude Oil Price", showlegend=False))
|
76
|
+
fig.add_trace(go.Scatter(x=[start_date, start_date], y=[0, 120], mode="lines", name="Start of Price War", showlegend=False))
|
77
|
+
fig.update_layout(yaxis=dict(range=[8, 82], title="OPEC Crude Oil Price ($)"), xaxis=dict(title="Date"))
|
78
|
+
plot(fig, filename="fig0.html", auto_open=False)
|
79
|
+
|
80
|
+
display(HTML("fig0.html"))
|
81
|
+
```
|
82
|
+
|
83
|
+
```
|
84
|
+
old plot code -- this cell is removed
|
85
|
+
uso = Table.read_table("USO.csv")
|
86
|
+
dates = uso.apply(pd.to_datetime, "Date")
|
87
|
+
uso = uso.with_column("Date", dates)
|
88
|
+
uso.to_df().plot.line("Date", "Close", figsize=[15,7], legend=False)
|
89
|
+
plt.vlines(dt.datetime(2020, 3, 8), -5, 125, color="r")
|
90
|
+
plt.ylim(0, 120)
|
91
|
+
plt.xlim(min(uso.column("Date")), max(uso.column("Date")))
|
92
|
+
plt.ylabel("USO Closing Price");
|
93
|
+
```
|
94
|
+
|
95
|
+
The plot above marks the official start of the price war on March 8, 2020, in red. We see some precipitous drops both just before and for a while after the start of the price war, indicating the effect that it is having on oil prices. While there are some confounding variables here (hi there, COVID-19), we still see a serious drop in price that is not just attributable to the stock market volatility that experienced by the rest of the market in early 2020.
|
96
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
---
|
2
|
+
title: expected-utility
|
3
|
+
type: textbook
|
4
|
+
source_path: content/07-game-theory/expected-utility.ipynb
|
5
|
+
chapter: 7
|
6
|
+
---
|
7
|
+
|
8
|
+
# Expected Utility Theory
|
9
|
+
|
10
|
+
Imagine you're offered a choice between \$1 guaranteed or \$100 with probability $\frac{1}{80}$ (i.e. with probability $\frac{79}{80}$, you get \$0). Which would you choose?
|
11
|
+
|
12
|
+
In game theory, we consider rationality by examining the utility of different outcomes to individuals. To do so, we calculate the **expected utility** of a set of outcomes, which is the average of the utilities of those outcomes weighted by their probabilities. In the example above, there are two outcomes:
|
13
|
+
|
14
|
+
* \$1 guaranteed. This occurs with probability $p_1=1$ and we'll say has utility $u_1 = 1$.
|
15
|
+
* \$100 with probability $p_2 = \frac{1}{80}$. We'll say this has utility $u_2 = 100$.
|
16
|
+
|
17
|
+
The expected utility of the first choice would be $p_1 \cdot u_1 = 1$ because there is only one possible outcome and it has utility 1. The expected utility of the second choice would be $p_2 \cdot u_2 + (1 - p_2) \cdot 0 = 1.25$ because we obtain utility $u_2$ with probability $p_2$ and utility 0 with probability $1-p_2$. Notice that the expected utility of the second choice is higher! This means that, had you chosen the \$1 guaranteed, you would have made the irrational choice, because it is _expected_ that you would get \$1.25 with the second choice.
|
18
|
+
|
19
|
+
The idea that individuals, when making a gamble, will choose the option that maximizes the expected utility based on their preferences is called the **expected utility hypothesis**.
|
20
|
+
|
21
|
+
## Expected Utility
|
22
|
+
|
23
|
+
The expected utility is a calculated value based on two pieces of information: an individual's preferences for different outcomes and the probability of those outcomes occurring. Let's illustrate this with an example: Suppose Alice is deciding whether to attend lecture today and her professor is deciding whether to take attendance today. If Alice goes to lecture, she will be bored but get her attendance counted if it's taken. If she doesn't, she won't be bored, but she won't get her attendance point. We must define the utilities for Alice and her professor in order to construct a payoff matrix.
|
24
|
+
|
25
|
+

|
26
|
+
|
27
|
+
```{admonition} Reading a payoff matrix
|
28
|
+
:class: tip
|
29
|
+
|
30
|
+
A payoff matrix specifies the payoffs of two players. The 2-tuples in each cell define the payoff for both players according to the combination of strategies corresponding to the row and column. For example, the bottom right cell above corresponds to the payoffs for Alice not attending and the professor not taking attendance. The tuples are formatted as `(row player, column player)`, so the first element is Alice's payoff and the second is the professor's. The payoff of (5, 0) indicates that that outcome has a utility of 5 for Alice and 0 for the professor.
|
31
|
+
```
|
32
|
+
|
33
|
+
Let's say that we know the professor's strategy: he will take attendance randomly with probability 0.7. Then we can calculate the expected utility of Alice's two options (attending and not attending) by taking the expected utility of each:
|
34
|
+
|
35
|
+
$$\begin{aligned}
|
36
|
+
E[\text{attending}] &= 0.7 (0) + 0.3 (-2) \\
|
37
|
+
&= - 0.6 \\
|
38
|
+
E[\text{not attending}] &= 0.7 (-5) + 0.3 (5) \\
|
39
|
+
&= -2
|
40
|
+
\end{aligned}$$
|
41
|
+
|
42
|
+
By calculating out Alice's expected utilities, we see that her utility is maximized by attending, given that the professor's strategy is to take attendance with probability 0.7.
|
43
|
+
|
44
|
+
An important point here is that we rely on the professor's strategy for playing the game to determine how to maximize Alice's expected utility. If the professor had a different strategy, then it could be the case that not attending would be the better option.
|
45
|
+
|
46
|
+
Let's formalize our definition of the expected utility.
|
47
|
+
|
48
|
+
```{admonition} Definition
|
49
|
+
The **expected utility** of a set of $n$ outcomes $x_i$ is the average of the utility of each outcome $u(x_i)$ weighted by the probability of that outcome's occurrence $p_i$:
|
50
|
+
|
51
|
+
$$
|
52
|
+
E[u(x)] = \sum_{i=1}^n p_i u(x_i)
|
53
|
+
$$
|
54
|
+
```
|
55
|
+
|
56
|
+
### Strategies
|
57
|
+
|
58
|
+
One of the underpinnings of game theory is the idea of **strategies**, systematic methods of playing games. There are many different ways to conceptualize strategies, some of which we've already seen. The professor's randomness strategy from the last example is one such, maximizing expected utility is another. Strategies tell the players of a game what move to make based on available information, and can be conceived of as a probability distribution over a player's choices.
|
59
|
+
|
60
|
+
There are many different types of strategies. Any strategy that puts probability 1 on a single choice is called a **pure** strategy; all others are called **mixed** strategies. If Alice's strategy had been "never attend class," this would have been a pure strategy, because the probability of not attending was always 1. The professor's strategy was a mixed strategy, since there wasn't a single option with probability 1.
|
61
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
title: index
|
3
|
+
type: textbook
|
4
|
+
source_path: content/07-game-theory/index.md
|
5
|
+
chapter: 7
|
6
|
+
---
|
7
|
+
|
8
|
+
# Game Theory
|
9
|
+
|
10
|
+
**Game theory** is a branch of mathematics concerned with the study of strategic interaction among rational decision-makers. While inherently mathematical at its foundation, game theory has numerous applications in several social science disciplines, including economics. Game theory originated with the study of equilibria in zero-sum games by John von Neumann and has since expanded into many other paradigms, including applications such as a method of examining and strategizing for interactions between the US and the USSR during the Cold War and explaining the evolution and prevalence of 1:1 sex ratios in biology. In this chapter, we will study a few particular aspects of game theory and their application to economics.
|
11
|
+
|
12
|
+
There are many different ways to conceive of games and to divide them along different attributes.
|
13
|
+
|
14
|
+
* **Cooperative vs. non-cooperative:** A game is _cooperative_ if the players are able to form commitments that can be externally enforced. A game is _non-cooperative_ if the players cannot form agreements or if those agreements need to be self-enforced.
|
15
|
+
* **Symmetric vs. asymmetric:** A game is _symmetric_ if the payoffs depend only on the strategies used and not on the players using those strategies. It is _asymmetric_ if changing the identities of the players changes the payoffs.
|
16
|
+
* **Simultaneous vs. sequential:** A game is _simultaneous_ if players move at the same time without being aware of the other players' actions. A game is _sequential_ if moves occur one after the other and players have some knowledge of the earlier actions of their competitors.
|
17
|
+
* **Perfect vs. imperfect information:** Games of _perfect information_ occur when all players know the moves previously made by all other players. If this is not the case, the game is an _imperfect-information_ game.
|
18
|
+
|
19
|
+
In this chapter, we will concern ourselves with simultaneous games of imperfect information, examining both cooperative and non-cooperative games as well as symmetric and asymmetric ones. We will also discuss different theoretical aspects, like strategies and payoffs. We will look at various common game paradigms, including one of the most popular games: the prisoner's dilemma. Lastly, we will study the economic application of game theory, including topics like equilibria and oligopolies.
|
@@ -0,0 +1,340 @@
|
|
1
|
+
---
|
2
|
+
title: python-classes
|
3
|
+
type: textbook
|
4
|
+
source_path: content/07-game-theory/python-classes.ipynb
|
5
|
+
chapter: 7
|
6
|
+
---
|
7
|
+
|
8
|
+
# Python Classes
|
9
|
+
|
10
|
+
Because Python is an [**object-oriented** programming language](https://en.wikipedia.org/wiki/Object-oriented_programming), you can create custom structures for storing data and methods called **classes**. A class represents an object and stores variables related to and functions that operate on that object. You're already familiar with Python classes, even if you don't know it: the `Table`s you work with in Data 8 are Python classes, as are NumPy arrays.
|
11
|
+
|
12
|
+
We use classes because they allow us to store data in a rigorously structured way and provide standardized methods of accessing and interacting with that data. For example, let's say you want to create a program that manages a person's banking information. You need to store their name, account number, and balance. You might do something like create an array for each individual, where the first element is their name, the second is their account number, and the third is their balance:
|
13
|
+
|
14
|
+
```python
|
15
|
+
account1 = make_array("Jane Doe", 123456, 100)
|
16
|
+
account2 = make_array("John Doe", 234567, 80)
|
17
|
+
```
|
18
|
+
|
19
|
+
But what happens if you need to track more data? Or suppose the structure of this data changes? Then you need to go to _every_ place where you access an element of the array and update it! It's really easy to forget things like this or to have instances fall through the cracks. Instead, we might create an `Account` class, so that whenever we need to update the structure, we need only do so once. (This is a very simplified version of a complex topic called [data abstraction](https://www.composingprograms.com/pages/22-data-abstraction.html) that demonstrates the need for complex, templated data structures and methods of accessing their data without violating [abstraction barriers](https://www.composingprograms.com/pages/22-data-abstraction.html#abstraction-barriers).)
|
20
|
+
|
21
|
+
Some terminology: a **class** is the abstract definition of one such data structure, the definition from which class instances are created. When refer to an **instance**, we mean a single copy of one of these objects. It's kind-of like cookies and cookie cutters: the class is the cookie cutter, the template from which we make instances, the cookies. Think about tables: `Table` is the class from which we create table instances:
|
22
|
+
|
23
|
+
```python
|
24
|
+
Table # this is the class
|
25
|
+
tbl = Table() # this is an instance
|
26
|
+
```
|
27
|
+
|
28
|
+
Instances are created by calling the **constructor** (more below) as if it were a function (e.g. `Table()`).
|
29
|
+
|
30
|
+
## Creating Instances
|
31
|
+
|
32
|
+
Classes can be created using a `class` statement. Inside the statement, you put the variables and methods that define the class. The first and most important of these methods is the `__init__` method which is called when an instance of a class is created. `__init__` is an example of Python's [dunder (double-underscore) methods](https://www.geeksforgeeks.org/dunder-magic-methods-python/), which are used to allow classes to interact with built-in functions and operators.
|
33
|
+
|
34
|
+
The `__init__` method should take any arguments needed for the class and create all of the _instance variables_ that the instance tracks. Consider the `Car` class:
|
35
|
+
|
36
|
+
```python
|
37
|
+
class Car:
|
38
|
+
def __init__(self, make, model, year, color):
|
39
|
+
self.make = make
|
40
|
+
self.model = model
|
41
|
+
self.year = year
|
42
|
+
self.color = color
|
43
|
+
```
|
44
|
+
|
45
|
+
Note that the first argument to the `__init__` method is a variable called `self`; this argument will be filled by Python with the instance of class that is being called. For example, when we call an instance's **method** (a function included in the class), we might have something like:
|
46
|
+
|
47
|
+
```python
|
48
|
+
class Foo:
|
49
|
+
def bar(self):
|
50
|
+
return None
|
51
|
+
|
52
|
+
foo = Foo()
|
53
|
+
foo.bar()
|
54
|
+
```
|
55
|
+
|
56
|
+
When we run `foo.bar()`, the function `Foo.bar` is called and the first argument (`self`) is filled with the instance `foo`.
|
57
|
+
|
58
|
+
In the `__init__` method (or any method, for that matter), we create instance variables (variables tied to a single instance of a class) using `<instance>.<variable name>` syntax, e.g.
|
59
|
+
|
60
|
+
```python
|
61
|
+
self.some_variable = "some value"
|
62
|
+
```
|
63
|
+
|
64
|
+
If we're outside of a method, we can use the same syntax using the variable name:
|
65
|
+
|
66
|
+
```python
|
67
|
+
foo.some_variable = "some value"
|
68
|
+
```
|
69
|
+
|
70
|
+
When you create a `Car`, `Car.__init__` is called by Python. We can create a `Car` and access the values of its instance variables using the dot syntax.
|
71
|
+
|
72
|
+
```python
|
73
|
+
car = Car("Honda", "Civic", 2018, "blue")
|
74
|
+
car.make
|
75
|
+
```
|
76
|
+
|
77
|
+
## Class Representations
|
78
|
+
|
79
|
+
Now let's see what our `car` object (an instance of the `Car` class) looks like.
|
80
|
+
|
81
|
+
```python
|
82
|
+
car
|
83
|
+
```
|
84
|
+
|
85
|
+
Hmm, that representation isn't very descriptive. Another dunder method of Python's is `__repr__`, which defines a string representation of an object. Let's define one for our `Car` class.
|
86
|
+
|
87
|
+
```python
|
88
|
+
class Car:
|
89
|
+
def __init__(self, make, model, year, color):
|
90
|
+
self.make = make
|
91
|
+
self.model = model
|
92
|
+
self.year = year
|
93
|
+
self.color = color
|
94
|
+
|
95
|
+
def __repr__(self):
|
96
|
+
return self.color + " " + str(self.year) + " " +self.make + " " + self.model
|
97
|
+
```
|
98
|
+
|
99
|
+
Now that we have defined `Car.__repr__`, we can get a nicer representation of `car`.
|
100
|
+
|
101
|
+
```python
|
102
|
+
car = Car("Honda", "Civic", 2018, "blue")
|
103
|
+
car
|
104
|
+
```
|
105
|
+
|
106
|
+
## Operators
|
107
|
+
|
108
|
+
Now let's create two of the same cars and compare them. They should be equal, right...?
|
109
|
+
|
110
|
+
```python
|
111
|
+
car_1 = Car("Honda", "Civic", 2018, "blue")
|
112
|
+
car_2 = Car("Honda", "Civic", 2018, "blue")
|
113
|
+
|
114
|
+
car_1 == car_2
|
115
|
+
```
|
116
|
+
|
117
|
+
They aren't equal! That's because, by default, the custom classes are only equal if they are the *same instance*, so `car_1 == car_1` is `True` but `car_1 == car_2` is `False`. For this reason, we need to define the `__eq__` dunder method of `Car` which Python will call when we use the `==` operator on a `Car`. We'll say and object is equal to a `Car` if the other object is also a `Car` (determined using the `isinstance` function) and has the same four attributes as the current car.
|
118
|
+
|
119
|
+
```python
|
120
|
+
class Car:
|
121
|
+
def __init__(self, make, model, year, color):
|
122
|
+
self.make = make
|
123
|
+
self.model = model
|
124
|
+
self.year = year
|
125
|
+
self.color = color
|
126
|
+
|
127
|
+
def __repr__(self):
|
128
|
+
return f"{self.color} {self.year} {self.make} {self.model}"
|
129
|
+
|
130
|
+
def __eq__(self, other):
|
131
|
+
if isinstance(other, Car):
|
132
|
+
return self.make == other.make and self.model == other.model and \
|
133
|
+
self.year == other.year and self.color == other.color
|
134
|
+
return False
|
135
|
+
```
|
136
|
+
|
137
|
+
Now our call from above will work:
|
138
|
+
|
139
|
+
```python
|
140
|
+
car_1 = Car("Honda", "Civic", 2018, "blue")
|
141
|
+
car_2 = Car("Honda", "Civic", 2018, "blue")
|
142
|
+
|
143
|
+
car_1 == car_2
|
144
|
+
```
|
145
|
+
|
146
|
+
Other important dunder methods include
|
147
|
+
|
148
|
+
| Method Name | Description |
|
149
|
+
|-----|-----|
|
150
|
+
| `__str__` | the string representation of an object |
|
151
|
+
| `__len__` | length of an object (`len(obj)` |
|
152
|
+
| `__lt__`, `__gt__`, `__lte__`, `__gte__` | less than, greater than, less than or equal to, and greater than or equal to operators, resp. |
|
153
|
+
| `__hash__` | [hash function](https://en.wikipedia.org/wiki/Hash_function) value (`hash(obj)`) |
|
154
|
+
| `__getitem__`, `__setitem__` | getter and setter (resp.) for indexes (`obj[idx]`) |
|
155
|
+
| `__getattr__`, `__setattr__` | getter and setter (resp.) for dot syntax (`obj.attr`) |
|
156
|
+
|
157
|
+
Note that when using comparison operators the object to the **left** of the operator has its comparison operator method called. In the below example, the first comparison calls `point_1.__lt__` and the second calls `point_2.__lt__`.
|
158
|
+
|
159
|
+
```python
|
160
|
+
point_1 = Point()
|
161
|
+
point_2 = Point()
|
162
|
+
|
163
|
+
point_1 < point_2 # calls point_1.__lt__
|
164
|
+
point_2 < point_1 # calls point_2.__lt__
|
165
|
+
```
|
166
|
+
|
167
|
+
## Instance Methods
|
168
|
+
|
169
|
+
Now let's define some methods for a `Car`. We'll add a few more instance variables:
|
170
|
+
|
171
|
+
* `car.mileage` is the number of miles driven by the car
|
172
|
+
* `car.gas` is number of gallons of gas in the tank
|
173
|
+
* `car.mpg` is the number of miles to a gallon that the car gets.
|
174
|
+
|
175
|
+
Note that `car.mileage` and `car.gas` are initialized to 0 when we create the car in `__init__`. We'll first define the `fill_tank` method, which fills the gas tank to 10 gallons.
|
176
|
+
|
177
|
+
```python
|
178
|
+
class Car:
|
179
|
+
def __init__(self, make, model, year, color, mpg):
|
180
|
+
self.make = make
|
181
|
+
self.model = model
|
182
|
+
self.year = year
|
183
|
+
self.color = color
|
184
|
+
self.mpg = mpg
|
185
|
+
self.mileage = 0
|
186
|
+
self.gas = 0
|
187
|
+
|
188
|
+
def __repr__(self):
|
189
|
+
return f"{self.color} {self.year} {self.make} {self.model}"
|
190
|
+
|
191
|
+
def __eq__(self, other):
|
192
|
+
if isinstance(other, Car):
|
193
|
+
return self.make == other.make and self.model == other.model and \
|
194
|
+
self.year == other.year and self.color == other.color
|
195
|
+
return False
|
196
|
+
|
197
|
+
def fill_tank(self):
|
198
|
+
self.gas = 10
|
199
|
+
```
|
200
|
+
|
201
|
+
We can create a car and fill its take by calling `car.fill_tank`.
|
202
|
+
|
203
|
+
```python
|
204
|
+
car = Car("Honda", "Civic", 2018, "blue", 18)
|
205
|
+
car.fill_tank()
|
206
|
+
car.gas
|
207
|
+
```
|
208
|
+
|
209
|
+
### Assertions
|
210
|
+
|
211
|
+
Now we'll define the `car.drive` method that drives `miles` miles and ensures that we have enough gas to drive that far by throwing an `AssertionError` if we don't.
|
212
|
+
|
213
|
+
We throw assertion errors using an `assert` statement which takes two arguments: a boolean expression and a string telling the user what caused the error. For example, if we want to make sure that a string has no spaces, we might write
|
214
|
+
|
215
|
+
```python
|
216
|
+
assert " " not in string, "Spaces found in string"
|
217
|
+
```
|
218
|
+
|
219
|
+
Then, if `string` has a space, the user would see:
|
220
|
+
|
221
|
+
```python
|
222
|
+
string = "some string"
|
223
|
+
assert " " not in string, "Spaces found in string"
|
224
|
+
```
|
225
|
+
|
226
|
+
### Reassignment Operators
|
227
|
+
|
228
|
+
Another new syntax needed for the `Car.drive` method is `+=` and `-=`. An operator followed by `=` tells Python to perform the operation combining the values on the left and right sides of the operator and then reassigns this value to the variable on the left side. This means that the expression `x += 2` is the exact same as `x = x + 2`.
|
229
|
+
|
230
|
+
```python
|
231
|
+
x = 2
|
232
|
+
|
233
|
+
x += 1
|
234
|
+
print(x) # x is now 3
|
235
|
+
|
236
|
+
x -= 4
|
237
|
+
print(x) # x is now -1
|
238
|
+
|
239
|
+
x *= 100
|
240
|
+
print(x) # x is now -100
|
241
|
+
|
242
|
+
x /= -100
|
243
|
+
print(x) # x is now 1
|
244
|
+
```
|
245
|
+
|
246
|
+
Now let's define `Car.drive`.
|
247
|
+
|
248
|
+
```python
|
249
|
+
class Car:
|
250
|
+
def __init__(self, make, model, year, color, mpg):
|
251
|
+
self.make = make
|
252
|
+
self.model = model
|
253
|
+
self.year = year
|
254
|
+
self.color = color
|
255
|
+
self.mpg = mpg
|
256
|
+
self.mileage = 0
|
257
|
+
self.gas = 0
|
258
|
+
|
259
|
+
def __repr__(self):
|
260
|
+
return f"{self.color} {self.year} {self.make} {self.model}"
|
261
|
+
|
262
|
+
def __eq__(self, other):
|
263
|
+
if isinstance(other, Car):
|
264
|
+
return self.make == other.make and self.model == other.model and \
|
265
|
+
self.year == other.year and self.color == other.color
|
266
|
+
return False
|
267
|
+
|
268
|
+
def fill_tank(self):
|
269
|
+
self.gas = 10
|
270
|
+
|
271
|
+
def drive(self, miles):
|
272
|
+
assert miles <= self.gas * self.mpg, f"not enough gas to drive {self.miles} miles"
|
273
|
+
self.mileage += miles
|
274
|
+
self.gas -= miles / self.mpg
|
275
|
+
```
|
276
|
+
|
277
|
+
Let's drive our `Car` 100 miles.
|
278
|
+
|
279
|
+
```python
|
280
|
+
car = Car("Honda", "Civic", 2018, "blue", 18)
|
281
|
+
car.fill_tank()
|
282
|
+
car.drive(100)
|
283
|
+
car.mileage, car.gas
|
284
|
+
```
|
285
|
+
|
286
|
+
Now let's see how many miles we have left to drive by defining `Car.miles_to_empty`.
|
287
|
+
|
288
|
+
```python
|
289
|
+
class Car:
|
290
|
+
def __init__(self, make, model, year, color, mpg):
|
291
|
+
self.make = make
|
292
|
+
self.model = model
|
293
|
+
self.year = year
|
294
|
+
self.color = color
|
295
|
+
self.mpg = mpg
|
296
|
+
self.mileage = 0
|
297
|
+
self.gas = 0
|
298
|
+
|
299
|
+
def __repr__(self):
|
300
|
+
return f"{self.color} {self.year} {self.make} {self.model}"
|
301
|
+
|
302
|
+
def __eq__(self, other):
|
303
|
+
if isinstance(other, Car):
|
304
|
+
return self.make == other.make and self.model == other.model and \
|
305
|
+
self.year == other.year and self.color == other.color
|
306
|
+
return False
|
307
|
+
|
308
|
+
def fill_tank(self):
|
309
|
+
self.gas = 10
|
310
|
+
|
311
|
+
def drive(self, miles):
|
312
|
+
assert miles <= self.gas * self.mpg, f"not enough gas to drive {self.mileage} miles"
|
313
|
+
self.mileage += miles
|
314
|
+
self.gas -= miles / self.mpg
|
315
|
+
|
316
|
+
def miles_to_empty(self):
|
317
|
+
return self.gas * self.mpg
|
318
|
+
|
319
|
+
car = Car("Honda", "Civic", 2018, "blue", 18)
|
320
|
+
car.fill_tank()
|
321
|
+
car.drive(100)
|
322
|
+
car.miles_to_empty()
|
323
|
+
```
|
324
|
+
|
325
|
+
We have 80 miles left before we're empty, so we see that if we try to drive 90 miles, the car will thrown an error:
|
326
|
+
|
327
|
+
```python
|
328
|
+
car.drive(90)
|
329
|
+
```
|
330
|
+
|
331
|
+
For more information on Python classes, check out [Sections 2.5-2.7 of Composing Programs](https://www.composingprograms.com/pages/25-object-oriented-programming.html), the CS 61A/CS 88 textbook.
|
332
|
+
|
333
|
+
```python
|
334
|
+
|
335
|
+
```
|
336
|
+
|
337
|
+
```python
|
338
|
+
|
339
|
+
```
|
340
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
---
|
2
|
+
title: index
|
3
|
+
type: textbook
|
4
|
+
source_path: content/08-development/index.md
|
5
|
+
chapter: 8
|
6
|
+
---
|
7
|
+
|
8
|
+
# Development
|
9
|
+
|
10
|
+
A fundamental aspect of inferential thinking and statistical measurement is how to design experiments in order to be measuring causation instead of correlation. An intervention can be thought of as some sort of change that is thought to bring about some desired outcome. Correlation between two measurements can be due to many underlying factors besides the intervention being studied. A properly designed experiment can isolate the effect of the intervention being studied.
|
11
|
+
|
12
|
+
The main idea is to take an overall population, create two subsets and randomly assign which of the subsets of the population gets an intervention (called *treatment*) and another subset who does not get an intervention ( called *control*). The population can be studied before and after an intervention is rolled out. The application of this methodology in Development Economics has caused a revolution in how the field measures the impacts of different development interventions.
|
13
|
+
|
14
|
+
Historically many of the early statistical models came from agriculture, where a scientist might be looking to increase the yield of a crop being planted. The experiment might be to plant two fields side by side with the same seeds, but one field gets two times the fertilizer of the second field. The amount that the yield increases due to fertilizer can be measured by the yield on the treated field (more fertilizer) minus the yield on the control field with baseline fertilizer. (*And an economist would then balance the cost of the extra fertilizer against the revenue from the additional crop yield*)
|
15
|
+
|
16
|
+
More recently, most people are familiar with drug trials, where new medicines are evaluated using an experimental design. In 2020 the whole world waited for the results of randomized controlled trials of the COVID-19 vaccines to be carried out before the vaccines could be used. In these trials, 30,000 - 40,000 volunteers were recruited from a diverse set of ages and ethnicities and randomized into two groups, treatment and control. In the treatment groups the volunteers received the vaccine, in the control groups the volunteers received an injection of a neutral saline solution. The study continued until a certain number of people in the control group had gotten COVID-19, and the number of people in the two study arms were compared.
|
17
|
+
|
18
|
+
In the current construction of the internet as we use it, A/B testing is a very common tool for UX design, and a very common work for data scientists working in internet companies. Every time you surf the web or visit an internet site you may be unknowingly part of a test of the size or color of a button, flow of the page, or other details. The internet companies constantly divide site visitors into treatment and control groups and measure site engagement metrics to calibrate changes to their site. A manager of any site, no matter how small, has tools such as Google Analytics that can allow them to measure changes in site design on user interaction metrics.
|
19
|
+
|
20
|
+
In the world of Development Economics, this has taken the form of evaluating interventions that are usually aimed at reducing poverty, or improving health and education outcomes. This field is generally called Randomized Controlled Trials (RCTs), or also sometimes Impact Evaluation. In many cases these are pilot programs for new interventions that can be measured well in a pilot case, and if measured well and a strong effect is found, can be used as evidence to make the case for a broader rollout. In many cases the pilot study may only have resources to provide the intervention to a subset of the overall population and this could lead naturally to a control subset and treatment subset, where the control subset will eventually get the treatment in future time periods.
|
21
|
+
|
22
|
+
Some examples of treatments that were tested out in pilot RCT are:
|
23
|
+
* Malaria bednets to reduce childhood malaria
|
24
|
+
* Household water treatment to reduce child diarrhea
|
25
|
+
* Clean cooking stoves to reduce child respiratory illness
|
26
|
+
* Conditional payments to incentivize health clinic visits
|
27
|
+
* Payments for completion of school to incentivize girls schooling
|
28
|
+
|
29
|
+
In each of these we can think of reasons that randomization can be needed to screen out confounding factors. For example if malaria bednets were just sold at the store, it might be households with more wealth, more connected with social capital, or more education who might be the ones to purchase and use them. These *confounding factors* would make it hard for researchers to know what the effect of bednets were alone.
|
30
|
+
|
31
|
+
[One seminal RCT was a study of deworming](http://emiguel.econ.berkeley.edu/research/worms-identifying-impacts-on-education-and-health-in-the-presence-of-treatment-externalities) - giving out an anti-helminthic pill to kill intestinal parasites - to primary school children in Rural Kenya. This study was carried out to help a local non-profit that was working on increasing the rate of primary school attendance where there was high absenteeism due to childhood illness. The economics professors who carried this study out (and actually continue to carry it out) are Edward Miguel and Michael Kremer. Edward Miguel is now a Professor at UC Berkeley who teaches the Economics of Development Course (ECON 172) and Michael Kremer, Miguel's PhD thesis advisor at Harvard, won the Nobel Prize for Economics in 2019. The randomization of populations was more elaborate than just two groups and the comparison of students who got the deworming pill and who did not showed positive health and school attendance effects not just for the students who got it, but also for students at the same school who didn't get it and students who just happened to live in nearby villages to where the deworming was carried out. The researchers were also able to carefully document these effects using the correct study design and thus argue for the expansion of the program, which has since been carried out nationally in Kenya and in [as can be seen on the Deworm the World project page](https://www.evidenceaction.org/dewormtheworld/) "with over 1 billion treatments delivered since 2014 and 280 million treatments in 2019"
|
32
|
+
|
33
|
+
The researchers involve in this seminal study later moved on to study other interventions that could reduce the burden of childhood diseases by focusing on water-borne diseases such as diarrhea. Water-borne diarrhea is a leading cause of mortality in sub-Saharan Africa but is fatal primarily in infants under 5 years old. So the target of these studies was measuring health outcomes in children under 5. These interventions included the protection of water sources, *[Spring Cleaning](http://emiguel.econ.berkeley.edu/research/spring-cleaning-rural-water-impacts-valuation-and-property-rights-institutions)*, and the [as can be seen in the Social Engineering: Evidence from a Suite of Take-up Experiments in Kenya](http://emiguel.econ.berkeley.edu/research/social-engineering-evidence-from-a-suite-of-take-up-experiments-in-kenya), sold in Kenya as *Water Guard* to purify drinking water. A subset of this study is the focus of this week's lab.
|
34
|
+
|
35
|
+
The pedagogical purpose of this week's lab is also for students to think about the process that goes on behind the scenes of an economics journal article. The researchers work with the local NGO to map a set of villages where Spring Protection or Water Guard Promotion are going to be carried out. The populations are divided into a control arm, which will get the intervention in a future time period, and a set of comparable populations who get different treatment interventions, or even combinations of interventions. The NGO employs surveyors, who visit the households at baseline, before the intervention begins, and at various intervals later on after the intervention has been deployed. This household survey data is used to create a data set that is used to measure the effects of the intervention.
|