{"action":"created","comment":{"url":"https://api.github.com/repos/DS-100/textbook/pulls/comments/197616809","pull_request_review_id":131399683,"id":197616809,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDE5NzYxNjgwOQ==","diff_hunk":"@@ -0,0 +1,792 @@\n+\n+\n+```python\n+# HIDDEN\n+import numpy as np\n+import matplotlib.pyplot as plt\n+import pandas as pd\n+import seaborn as sns\n+from sklearn.linear_model import LinearRegression\n+%matplotlib inline\n+\n+sns.set()\n+sns.set_context('talk')\n+pd.options.display.max_rows = 7\n+pd.options.display.max_columns = 7\n+np.set_printoptions(precision=2, suppress=True)\n+```\n+\n+\n+```python\n+# HIDDEN\n+\"\"\"\n+def minimize(cost_fn, grad_cost_fn, X, y, alpha=0.2, progress=True):\n+    '''\n+    Uses gradient descent to minimize cost_fn. Returns the minimizing value of\n+    theta once theta changes less than 0.001 between iterations.\n+    '''\n+    theta = np.zeros(X.shape[1])\n+    old_cost = 10000000\n+    while True:\n+        if progress:\n+            print(f'theta: {theta} | cost: {cost_fn(theta, X, y):.2f}')\n+        gradient = grad_cost_fn(theta, X, y)\n+        new_theta = theta - alpha * gradient\n+        cost = cost_fn(theta, X, y)\n+        if abs(old_cost - cost) < 10:\n+            return new_theta\n+        old_cost = cost\n+        \n+        theta = new_theta\n+        \n+\"\"\"\n+        \n+from scipy.optimize import minimize as sci_min\n+\n+def minimize(cost_fn, grad_cost_fn, X, y, progress=True):\n+    '''\n+    Uses scipy.minimize to minimize cost_fn using a form of gradient descent.\n+    '''\n+    theta = np.zeros(X.shape[1])\n+    iters = 0\n+    \n+    def objective(theta):\n+        return cost_fn(theta, X, y)\n+    def gradient(theta):\n+        return grad_cost_fn(theta, X, y)\n+    def print_theta(theta):\n+        nonlocal iters\n+        if progress and iters % progress == 0:\n+            print(f'theta: {theta} | cost: {cost_fn(theta, X, y):.2f}')\n+        iters += 1\n+        \n+    print_theta(theta)\n+    return sci_min(\n+        objective, theta, method='BFGS', jac=gradient, callback=print_theta,\n+        tol=1e-7\n+    ).x\n+```\n+\n+## Linear Regression Case Study\n+\n+In this section, we will perform an end-to-end case study of the application of a linear regression model to a dataset.\n+\n+The dataset we will be working with is a record of the population and drinking data in various states. The dataset is from this website: http://people.sc.fsu.edu/~jburkardt/datasets/regression/x20.txt, with some properties of the dataset changed for didactical purposes.\n+\n+Our task in this section: fit a good linear regression model to this dataset in order to predict the cirrhosis death rate.\n+\n+## Exploring the Dataset\n+\n+As in any data science project, we're going to begin by doing some exploratory data analysis.\n+\n+We'll start by reading in the dataset using `pandas`.\n+\n+\n+```python\n+drinking_data = pd.read_csv(\"drinking.csv\")\n+```\n+\n+It's always a good idea to look at _how much_ data we have by looking at the number of columns and the number of rows in our dataset.\n+\n+\n+```python\n+drinking_data.shape\n+```\n+\n+\n+\n+\n+    (46, 6)\n+\n+\n+\n+We have 46 rows of observations and 6 columns. The dataset is a pretty small one. Let's look at what columns we have available to us.\n+\n+\n+```python\n+drinking_data.columns.values\n+```\n+\n+\n+\n+\n+    array(['Bias', 'Urban population (percentage)',\n+           'Late births (reciprocal * 100)', 'Wine consumption per capita',\n+           'Liquor consumption per capita', 'Cirrhosis death rate'], dtype=object)\n+\n+\n+\n+But what do any of these column names mean? Looking at the documentation provided by the source of the dataset, we can create a table describing each column, sometimes referred to as a data dictionary:\n+\n+| Column        | Description   \n+| :------------- |:-------------|\n+|`'Bias'`| a column of all 1's |\n+|`'Urban population (percentage)'`| the size of the urban population | \n+|`'Late births (reciprocal * 100)'`| the reciprocal of the number of births to women between 45 to 49, times 100 |\n+|`'Wine consumption per capita'`| the consumption of wine per capita|\n+|`'Liquor consumption per capita'`| the consumption of hard liquor per capita|\n+|`'Cirrhosis death rate'`| the death rate from cirrhosis |\n+\n+At this point, we may want to look up words we do not understand. For example, a quick Google search reveals that cirrhosis is chronic liver disease and can be caused by chronic alcohol abuse. Some of these column names are really long, so it may be convenient to rename some of them later.\n+\n+Now that we have a good understanding of each of the columns, we can actually start to look at the data. Let's take a quick look at the first few rows of our dataset using the `head` function. \n+\n+\n+```python\n+drinking_data.head()\n+```\n+\n+\n+\n+\n+<div>\n+<style>\n+    .dataframe thead tr:only-child th {\n+        text-align: right;\n+    }\n+\n+    .dataframe thead th {\n+        text-align: left;\n+    }\n+\n+    .dataframe tbody tr th {\n+        vertical-align: top;\n+    }\n+</style>\n+<table border=\"1\" class=\"dataframe\">\n+  <thead>\n+    <tr style=\"text-align: right;\">\n+      <th></th>\n+      <th>Bias</th>\n+      <th>Urban population (percentage)</th>\n+      <th>Late births (reciprocal * 100)</th>\n+      <th>Wine consumption per capita</th>\n+      <th>Liquor consumption per capita</th>\n+      <th>Cirrhosis death rate</th>\n+    </tr>\n+  </thead>\n+  <tbody>\n+    <tr>\n+      <th>0</th>\n+      <td>1</td>\n+      <td>44.0</td>\n+      <td>33.2</td>\n+      <td>5</td>\n+      <td>30</td>\n+      <td>41.2</td>\n+    </tr>\n+    <tr>\n+      <th>1</th>\n+      <td>1</td>\n+      <td>43.0</td>\n+      <td>33.8</td>\n+      <td>4</td>\n+      <td>41</td>\n+      <td>31.7</td>\n+    </tr>\n+    <tr>\n+      <th>2</th>\n+      <td>1</td>\n+      <td>48.0</td>\n+      <td>40.6</td>\n+      <td>3</td>\n+      <td>38</td>\n+      <td>39.4</td>\n+    </tr>\n+    <tr>\n+      <th>3</th>\n+      <td>1</td>\n+      <td>52.0</td>\n+      <td>39.2</td>\n+      <td>7</td>\n+      <td>48</td>\n+      <td>57.5</td>\n+    </tr>\n+    <tr>\n+      <th>4</th>\n+      <td>1</td>\n+      <td>71.0</td>\n+      <td>45.5</td>\n+      <td>11</td>\n+      <td>53</td>\n+      <td>74.8</td>\n+    </tr>\n+  </tbody>\n+</table>\n+</div>\n+\n+\n+\n+Although we cannot see any null values from the first 5 rows of the dataset, there may be some present in our dataset that we will need to deal with. We can write code to loop through every column of the dataset and tell us if there are null values present using the pandas `isnull` function.\n+\n+\n+```python\n+for cname in drinking_data.columns.values:\n+    column = drinking_data[cname] # Get the column corresponding to that column name\n+    null_mask = column.isnull() # Get a mask that is True if there is a null value present, False otherwise\n+    nulls_series = column[null_mask] # Get only values where the null value was detected\n+    if len(nulls_series) > 0: # If a null value was detected\n+        print(nulls_series)\n+```\n+\n+    35   NaN\n+    Name: Urban population (percentage), dtype: float64\n+    \n+\n+It appears that there is a null value present in row 35 of our dataset in the `Urban population (percentage)` column. Let's examine that row more closely:\n+\n+\n+```python\n+drinking_data.iloc[35]\n+```\n+\n+\n+\n+\n+    Bias                                1.0\n+    Urban population (percentage)       NaN\n+    Late births (reciprocal * 100)     53.0\n+    Wine consumption per capita        28.0\n+    Liquor consumption per capita     149.0\n+    Cirrhosis death rate              122.5\n+    Name: 35, dtype: float64\n+\n+\n+\n+With null values, we have two options: either drop the row with the null value or try to impute a value in the place of the null. Since we only have one null value in our dataset and it may not be a good idea to try to guess a value because it may negatively influence our linear regression model, we can just drop the row.\n+\n+## Data Cleaning\n+\n+Let's rename the column names to shorter names. It will make our code look cleaner and easier to read. We can make a new list of column names and assign `drinking_data.columns` to this list.\n+\n+\n+```python\n+new_column_names = ['Bias', 'Urban population', 'Late births', 'Wine', 'Liquor', 'Cirrhosis']\n+drinking_data.columns = new_column_names \n+```\n+\n+\n+```python\n+drinking_data\n+```\n+\n+\n+\n+\n+<div>\n+<style>\n+    .dataframe thead tr:only-child th {\n+        text-align: right;\n+    }\n+\n+    .dataframe thead th {\n+        text-align: left;\n+    }\n+\n+    .dataframe tbody tr th {\n+        vertical-align: top;\n+    }\n+</style>\n+<table border=\"1\" class=\"dataframe\">\n+  <thead>\n+    <tr style=\"text-align: right;\">\n+      <th></th>\n+      <th>Bias</th>\n+      <th>Urban population</th>\n+      <th>Late births</th>\n+      <th>Wine</th>\n+      <th>Liquor</th>\n+      <th>Cirrhosis</th>\n+    </tr>\n+  </thead>\n+  <tbody>\n+    <tr>\n+      <th>0</th>\n+      <td>1</td>\n+      <td>44.0</td>\n+      <td>33.2</td>\n+      <td>5</td>\n+      <td>30</td>\n+      <td>41.2</td>\n+    </tr>\n+    <tr>\n+      <th>1</th>\n+      <td>1</td>\n+      <td>43.0</td>\n+      <td>33.8</td>\n+      <td>4</td>\n+      <td>41</td>\n+      <td>31.7</td>\n+    </tr>\n+    <tr>\n+      <th>2</th>\n+      <td>1</td>\n+      <td>48.0</td>\n+      <td>40.6</td>\n+      <td>3</td>\n+      <td>38</td>\n+      <td>39.4</td>\n+    </tr>\n+    <tr>\n+      <th>...</th>\n+      <td>...</td>\n+      <td>...</td>\n+      <td>...</td>\n+      <td>...</td>\n+      <td>...</td>\n+      <td>...</td>\n+    </tr>\n+    <tr>\n+      <th>43</th>\n+      <td>1</td>\n+      <td>44.0</td>\n+      <td>35.3</td>\n+      <td>3</td>\n+      <td>32</td>\n+      <td>51.6</td>\n+    </tr>\n+    <tr>\n+      <th>44</th>\n+      <td>1</td>\n+      <td>63.0</td>\n+      <td>39.3</td>\n+      <td>8</td>\n+      <td>40</td>\n+      <td>55.7</td>\n+    </tr>\n+    <tr>\n+      <th>45</th>\n+      <td>1</td>\n+      <td>58.0</td>\n+      <td>43.8</td>\n+      <td>13</td>\n+      <td>57</td>\n+      <td>55.5</td>\n+    </tr>\n+  </tbody>\n+</table>\n+<p>46 rows × 6 columns</p>\n+</div>\n+\n+\n+\n+Let's deal with that pesky null value. We can use the `dropna` function for this purpose.\n+\n+\n+```python\n+drinking_data = drinking_data.dropna()\n+drinking_data\n+```\n+\n+\n+\n+\n+<div>\n+<style>\n+    .dataframe thead tr:only-child th {\n+        text-align: right;\n+    }\n+\n+    .dataframe thead th {\n+        text-align: left;\n+    }\n+\n+    .dataframe tbody tr th {\n+        vertical-align: top;\n+    }\n+</style>\n+<table border=\"1\" class=\"dataframe\">\n+  <thead>\n+    <tr style=\"text-align: right;\">\n+      <th></th>\n+      <th>Bias</th>\n+      <th>Urban population</th>\n+      <th>Late births</th>\n+      <th>Wine</th>\n+      <th>Liquor</th>\n+      <th>Cirrhosis</th>\n+    </tr>\n+  </thead>\n+  <tbody>\n+    <tr>\n+      <th>0</th>\n+      <td>1</td>\n+      <td>44.0</td>\n+      <td>33.2</td>\n+      <td>5</td>\n+      <td>30</td>\n+      <td>41.2</td>\n+    </tr>\n+    <tr>\n+      <th>1</th>\n+      <td>1</td>\n+      <td>43.0</td>\n+      <td>33.8</td>\n+      <td>4</td>\n+      <td>41</td>\n+      <td>31.7</td>\n+    </tr>\n+    <tr>\n+      <th>2</th>\n+      <td>1</td>\n+      <td>48.0</td>\n+      <td>40.6</td>\n+      <td>3</td>\n+      <td>38</td>\n+      <td>39.4</td>\n+    </tr>\n+    <tr>\n+      <th>...</th>\n+      <td>...</td>\n+      <td>...</td>\n+      <td>...</td>\n+      <td>...</td>\n+      <td>...</td>\n+      <td>...</td>\n+    </tr>\n+    <tr>\n+      <th>43</th>\n+      <td>1</td>\n+      <td>44.0</td>\n+      <td>35.3</td>\n+      <td>3</td>\n+      <td>32</td>\n+      <td>51.6</td>\n+    </tr>\n+    <tr>\n+      <th>44</th>\n+      <td>1</td>\n+      <td>63.0</td>\n+      <td>39.3</td>\n+      <td>8</td>\n+      <td>40</td>\n+      <td>55.7</td>\n+    </tr>\n+    <tr>\n+      <th>45</th>\n+      <td>1</td>\n+      <td>58.0</td>\n+      <td>43.8</td>\n+      <td>13</td>\n+      <td>57</td>\n+      <td>55.5</td>\n+    </tr>\n+  </tbody>\n+</table>\n+<p>45 rows × 6 columns</p>\n+</div>\n+\n+\n+\n+Looks like it worked! We now have 45 rows instead of 46 rows. \n+\n+## Data Visualization\n+\n+If we are going to try to create a _linear_ model, we should make sure that all of our predictor variables have a somewhat linear relationship with the target variable of Cirrhosis. Let's plot every predictor variable individually against Cirrhosis.  \n+\n+\n+```python\n+# HIDDEN\n+plt.scatter(drinking_data['Urban population'], drinking_data['Cirrhosis'])\n+plt.title(\"Urban population vs. Cirrhosis\")\n+plt.xlabel(\"Urban population\")\n+plt.ylabel(\"Cirrhosis\");\n+```\n+\n+\n+![png](LR_Case_Study_files/LR_Case_Study_25_0.png)\n+\n+\n+This looks like a reasonably linear relationship.\n+\n+\n+```python\n+# HIDDEN\n+plt.scatter(drinking_data['Late births'], drinking_data['Cirrhosis'])\n+plt.title(\"Late births vs. Cirrhosis\")\n+plt.xlabel(\"Late births\")\n+plt.ylabel(\"Cirrhosis\");\n+```\n+\n+\n+![png](LR_Case_Study_files/LR_Case_Study_27_0.png)\n+\n+\n+It looks like we have an outlier for late births values. Late births and cirrhosis seem to have a pretty strong linear relationship, but because this point is not close to the linear trend at all, this outlier would negatively affect our linear regression model. Thus, we should take this row out of our dataset and investigate later whether this was an error in our dataset or an actual recorded value (not in this notebook). \n+\n+Since we can easily see that this lates births value is less than 10, we can just filter our dataset by selecting only rows where late births is over 10.\n+\n+\n+```python\n+drinking_data = drinking_data[drinking_data['Late births'] >= 10]\n+drinking_data\n+```\n+\n+\n+\n+\n+<div>\n+<style>\n+    .dataframe thead tr:only-child th {\n+        text-align: right;\n+    }\n+\n+    .dataframe thead th {\n+        text-align: left;\n+    }\n+\n+    .dataframe tbody tr th {\n+        vertical-align: top;\n+    }\n+</style>\n+<table border=\"1\" class=\"dataframe\">\n+  <thead>\n+    <tr style=\"text-align: right;\">\n+      <th></th>\n+      <th>Bias</th>\n+      <th>Urban population</th>\n+      <th>Late births</th>\n+      <th>Wine</th>\n+      <th>Liquor</th>\n+      <th>Cirrhosis</th>\n+    </tr>\n+  </thead>\n+  <tbody>\n+    <tr>\n+      <th>0</th>\n+      <td>1</td>\n+      <td>44.0</td>\n+      <td>33.2</td>\n+      <td>5</td>\n+      <td>30</td>\n+      <td>41.2</td>\n+    </tr>\n+    <tr>\n+      <th>1</th>\n+      <td>1</td>\n+      <td>43.0</td>\n+      <td>33.8</td>\n+      <td>4</td>\n+      <td>41</td>\n+      <td>31.7</td>\n+    </tr>\n+    <tr>\n+      <th>2</th>\n+      <td>1</td>\n+      <td>48.0</td>\n+      <td>40.6</td>\n+      <td>3</td>\n+      <td>38</td>\n+      <td>39.4</td>\n+    </tr>\n+    <tr>\n+      <th>...</th>\n+      <td>...</td>\n+      <td>...</td>\n+      <td>...</td>\n+      <td>...</td>\n+      <td>...</td>\n+      <td>...</td>\n+    </tr>\n+    <tr>\n+      <th>43</th>\n+      <td>1</td>\n+      <td>44.0</td>\n+      <td>35.3</td>\n+      <td>3</td>\n+      <td>32</td>\n+      <td>51.6</td>\n+    </tr>\n+    <tr>\n+      <th>44</th>\n+      <td>1</td>\n+      <td>63.0</td>\n+      <td>39.3</td>\n+      <td>8</td>\n+      <td>40</td>\n+      <td>55.7</td>\n+    </tr>\n+    <tr>\n+      <th>45</th>\n+      <td>1</td>\n+      <td>58.0</td>\n+      <td>43.8</td>\n+      <td>13</td>\n+      <td>57</td>\n+      <td>55.5</td>\n+    </tr>\n+  </tbody>\n+</table>\n+<p>44 rows × 6 columns</p>\n+</div>\n+\n+\n+\n+How does our scatterplot look now without that outlier?\n+\n+\n+```python\n+# HIDDEN\n+plt.scatter(drinking_data['Late births'], drinking_data['Cirrhosis'])\n+plt.title(\"Late births vs. Cirrhosis\")\n+plt.xlabel(\"Late births\")\n+plt.ylabel(\"Cirrhosis\");\n+```\n+\n+\n+![png](LR_Case_Study_files/LR_Case_Study_31_0.png)\n+\n+\n+Much better!\n+\n+\n+```python\n+# HIDDEN\n+plt.scatter(drinking_data['Wine'], drinking_data['Cirrhosis'])\n+plt.title(\"Wine vs. Cirrhosis\")\n+plt.xlabel(\"Wine\")\n+plt.ylabel(\"Cirrhosis\");\n+```\n+\n+\n+![png](LR_Case_Study_files/LR_Case_Study_33_0.png)\n+\n+\n+This looks like a pretty strong linear relationship between wine and cirrhosis.\n+\n+\n+```python\n+# HIDDEN\n+plt.scatter(drinking_data['Liquor'], drinking_data['Cirrhosis'])\n+plt.title(\"Liquor vs. Cirrhosis\")\n+plt.xlabel(\"Liquor\")\n+plt.ylabel(\"Cirrhosis\");\n+```\n+\n+\n+![png](LR_Case_Study_files/LR_Case_Study_35_0.png)\n+\n+\n+There seems to be a somewhat linear relationship between liquor and cirrhosis, though it is definitely not as strong as that between wine and cirrhosis.\n+\n+## Linear Regression Model\n+\n+Since all variables seem to have a linear relationship with cirrhosis, we can just include all of them in our model. \n+\n+Our model looks like this:\n+\n+$$\n+f_\\hat{\\theta} (x) = \\hat{\\theta_0} + \\hat{\\theta_1} (Urban population) + \\hat{\\theta_2} (Late births) + \\hat{\\theta_3} (Wine) + \\hat{\\theta_3} (Liquor)\n+$$\n+\n+Remember, the $\\hat{\\theta_0}$ is accounted for due to the bias column in our dataframe.\n+\n+Here are the functions we defined earlier in the multiple linear regression section, which we will use again:\n+\n+\n+```python\n+def linear_model(thetas, X):\n+    '''Returns predictions by a linear model on x_vals.'''\n+    return X @ thetas\n+\n+def mse_cost(thetas, X, y):\n+    return np.mean((y - linear_model(thetas, X)) ** 2)\n+\n+def grad_mse_cost(thetas, X, y):\n+    n = len(X)\n+    return -2 / n * (X.T @ y  - X.T @ X @ thetas)\n+```\n+\n+In order to use the above functions, we need `X`, and `y`. `thetas` is actually set to be an array of all 1's in the body of the `minimize` function. We can get these from our dataframe. Remember that `X` and `y` have to be numpy matrices in order to be able to multiply them with `@` notation.\n+\n+`X` consists of all columns of the dataframe except for the target column, `Cirrhosis`. Note that we also need to call `as_matrix()` so that `X` is a matrix.\n+\n+\n+\n+```python\n+X = (drinking_data\n+     .loc[:, ['Bias', 'Urban population', 'Late births', 'Wine', 'Liquor' ]]\n+     .as_matrix())\n+```\n+\n+`y` consists of the `Cirrhosis` column of our dataset.\n+\n+\n+```python\n+y = drinking_data['Cirrhosis'].as_matrix()\n+```\n+\n+Now we just need to call the `minimize` function defined in a previous section.\n+\n+\n+```python\n+thetas = minimize(mse_cost, grad_mse_cost, X, y)\n+```\n+\n+    theta: [ 0.  0.  0.  0.  0.] | cost: 4217.20\n+    theta: [ 0.01  0.64  0.45  0.14  0.63] | cost: 999.01\n+    theta: [ 0.    1.    0.39  0.59  0.21] | cost: 955.60\n+    theta: [-0.02  0.86  0.1   1.58  0.34] | cost: 902.97\n+    theta: [-0.01  0.41  0.82  2.13  0.13] | cost: 809.45\n+    theta: [-0.08  0.55  0.54  1.86  0.19] | cost: 634.59\n+    theta: [-0.33  0.43  0.63  1.86  0.11] | cost: 339.56\n+    theta: [-1.26  0.22  0.76  1.8  -0.01] | cost: 98.33\n+    theta: [-3.18  0.2   0.85  1.81 -0.02] | cost: 97.67\n+    theta: [-7.49  0.17  1.01  1.81 -0.04] | cost: 96.69\n+    theta: [-11.19   0.14   1.16   1.81  -0.05] | cost: 96.43\n+    theta: [-11.19   0.14   1.16   1.81  -0.05] | cost: 96.43\n+    theta: [-11.19   0.14   1.16   1.81  -0.05] | cost: 96.43\n+    theta: [-11.19   0.14   1.16   1.81  -0.05] | cost: 96.43\n+    \n+\n+Looks like gradient descent converged to those theta values! Thus, our linear model is:\n+\n+$y = -11.19 + 0.14x_1 + 1.16x_2 + 1.81x_3 - 0.05x_4$\n+\n+Let's compare this equation that we obtained to the one we would get if we had used `sklearn`'s LinearRegression model instead.\n+\n+\n+```python\n+model = LinearRegression()\n+model.fit(X, y)\n+model.coef_\n+```\n+\n+\n+\n+\n+    array([ 0.  ,  0.14,  1.16,  1.81, -0.05])","path":"notebooks/ch12/LR_Case_Study.md","position":758,"original_position":758,"commit_id":"90fde3c00a0d0978a95214c06ab2a845e07fee27","original_commit_id":"90fde3c00a0d0978a95214c06ab2a845e07fee27","user":{"login":"ashleychien","id":22417757,"node_id":"MDQ6VXNlcjIyNDE3NzU3","avatar_url":"https://avatars3.githubusercontent.com/u/22417757?v=4","gravatar_id":"","url":"https://api.github.com/users/ashleychien","html_url":"https://github.com/ashleychien","followers_url":"https://api.github.com/users/ashleychien/followers","following_url":"https://api.github.com/users/ashleychien/following{/other_user}","gists_url":"https://api.github.com/users/ashleychien/gists{/gist_id}","starred_url":"https://api.github.com/users/ashleychien/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ashleychien/subscriptions","organizations_url":"https://api.github.com/users/ashleychien/orgs","repos_url":"https://api.github.com/users/ashleychien/repos","events_url":"https://api.github.com/users/ashleychien/events{/privacy}","received_events_url":"https://api.github.com/users/ashleychien/received_events","type":"User","site_admin":false},"body":"i honestly have no idea why this happened >_>","created_at":"2018-06-23T16:34:51Z","updated_at":"2018-06-23T16:34:51Z","html_url":"https://github.com/DS-100/textbook/pull/40#discussion_r197616809","pull_request_url":"https://api.github.com/repos/DS-100/textbook/pulls/40","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/DS-100/textbook/pulls/comments/197616809"},"html":{"href":"https://github.com/DS-100/textbook/pull/40#discussion_r197616809"},"pull_request":{"href":"https://api.github.com/repos/DS-100/textbook/pulls/40"}},"in_reply_to_id":197333573},"pull_request":{"url":"https://api.github.com/repos/DS-100/textbook/pulls/40","id":195700361,"node_id":"MDExOlB1bGxSZXF1ZXN0MTk1NzAwMzYx","html_url":"https://github.com/DS-100/textbook/pull/40","diff_url":"https://github.com/DS-100/textbook/pull/40.diff","patch_url":"https://github.com/DS-100/textbook/pull/40.patch","issue_url":"https://api.github.com/repos/DS-100/textbook/issues/40","number":40,"state":"open","locked":false,"title":"Ch12 LR Case Study","user":{"login":"ashleychien","id":22417757,"node_id":"MDQ6VXNlcjIyNDE3NzU3","avatar_url":"https://avatars3.githubusercontent.com/u/22417757?v=4","gravatar_id":"","url":"https://api.github.com/users/ashleychien","html_url":"https://github.com/ashleychien","followers_url":"https://api.github.com/users/ashleychien/followers","following_url":"https://api.github.com/users/ashleychien/following{/other_user}","gists_url":"https://api.github.com/users/ashleychien/gists{/gist_id}","starred_url":"https://api.github.com/users/ashleychien/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ashleychien/subscriptions","organizations_url":"https://api.github.com/users/ashleychien/orgs","repos_url":"https://api.github.com/users/ashleychien/repos","events_url":"https://api.github.com/users/ashleychien/events{/privacy}","received_events_url":"https://api.github.com/users/ashleychien/received_events","type":"User","site_admin":false},"body":"Not for actually merging yet, just for the review of the Jupyter Notebook for the LR Case Study I added","created_at":"2018-06-19T03:04:48Z","updated_at":"2018-06-23T16:34:51Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6c38e68327865c703bc597feede6db189b73cef5","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/DS-100/textbook/pulls/40/commits","review_comments_url":"https://api.github.com/repos/DS-100/textbook/pulls/40/comments","review_comment_url":"https://api.github.com/repos/DS-100/textbook/pulls/comments{/number}","comments_url":"https://api.github.com/repos/DS-100/textbook/issues/40/comments","statuses_url":"https://api.github.com/repos/DS-100/textbook/statuses/90fde3c00a0d0978a95214c06ab2a845e07fee27","head":{"label":"DS-100:ch12-lr-casestudy","ref":"ch12-lr-casestudy","sha":"90fde3c00a0d0978a95214c06ab2a845e07fee27","user":{"login":"DS-100","id":22970565,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIyOTcwNTY1","avatar_url":"https://avatars3.githubusercontent.com/u/22970565?v=4","gravatar_id":"","url":"https://api.github.com/users/DS-100","html_url":"https://github.com/DS-100","followers_url":"https://api.github.com/users/DS-100/followers","following_url":"https://api.github.com/users/DS-100/following{/other_user}","gists_url":"https://api.github.com/users/DS-100/gists{/gist_id}","starred_url":"https://api.github.com/users/DS-100/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DS-100/subscriptions","organizations_url":"https://api.github.com/users/DS-100/orgs","repos_url":"https://api.github.com/users/DS-100/repos","events_url":"https://api.github.com/users/DS-100/events{/privacy}","received_events_url":"https://api.github.com/users/DS-100/received_events","type":"Organization","site_admin":false},"repo":{"id":116552199,"node_id":"MDEwOlJlcG9zaXRvcnkxMTY1NTIxOTk=","name":"textbook","full_name":"DS-100/textbook","owner":{"login":"DS-100","id":22970565,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIyOTcwNTY1","avatar_url":"https://avatars3.githubusercontent.com/u/22970565?v=4","gravatar_id":"","url":"https://api.github.com/users/DS-100","html_url":"https://github.com/DS-100","followers_url":"https://api.github.com/users/DS-100/followers","following_url":"https://api.github.com/users/DS-100/following{/other_user}","gists_url":"https://api.github.com/users/DS-100/gists{/gist_id}","starred_url":"https://api.github.com/users/DS-100/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DS-100/subscriptions","organizations_url":"https://api.github.com/users/DS-100/orgs","repos_url":"https://api.github.com/users/DS-100/repos","events_url":"https://api.github.com/users/DS-100/events{/privacy}","received_events_url":"https://api.github.com/users/DS-100/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/DS-100/textbook","description":"Textbook for DS100 at UC Berkeley","fork":false,"url":"https://api.github.com/repos/DS-100/textbook","forks_url":"https://api.github.com/repos/DS-100/textbook/forks","keys_url":"https://api.github.com/repos/DS-100/textbook/keys{/key_id}","collaborators_url":"https://api.github.com/repos/DS-100/textbook/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/DS-100/textbook/teams","hooks_url":"https://api.github.com/repos/DS-100/textbook/hooks","issue_events_url":"https://api.github.com/repos/DS-100/textbook/issues/events{/number}","events_url":"https://api.github.com/repos/DS-100/textbook/events","assignees_url":"https://api.github.com/repos/DS-100/textbook/assignees{/user}","branches_url":"https://api.github.com/repos/DS-100/textbook/branches{/branch}","tags_url":"https://api.github.com/repos/DS-100/textbook/tags","blobs_url":"https://api.github.com/repos/DS-100/textbook/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/DS-100/textbook/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/DS-100/textbook/git/refs{/sha}","trees_url":"https://api.github.com/repos/DS-100/textbook/git/trees{/sha}","statuses_url":"https://api.github.com/repos/DS-100/textbook/statuses/{sha}","languages_url":"https://api.github.com/repos/DS-100/textbook/languages","stargazers_url":"https://api.github.com/repos/DS-100/textbook/stargazers","contributors_url":"https://api.github.com/repos/DS-100/textbook/contributors","subscribers_url":"https://api.github.com/repos/DS-100/textbook/subscribers","subscription_url":"https://api.github.com/repos/DS-100/textbook/subscription","commits_url":"https://api.github.com/repos/DS-100/textbook/commits{/sha}","git_commits_url":"https://api.github.com/repos/DS-100/textbook/git/commits{/sha}","comments_url":"https://api.github.com/repos/DS-100/textbook/comments{/number}","issue_comment_url":"https://api.github.com/repos/DS-100/textbook/issues/comments{/number}","contents_url":"https://api.github.com/repos/DS-100/textbook/contents/{+path}","compare_url":"https://api.github.com/repos/DS-100/textbook/compare/{base}...{head}","merges_url":"https://api.github.com/repos/DS-100/textbook/merges","archive_url":"https://api.github.com/repos/DS-100/textbook/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/DS-100/textbook/downloads","issues_url":"https://api.github.com/repos/DS-100/textbook/issues{/number}","pulls_url":"https://api.github.com/repos/DS-100/textbook/pulls{/number}","milestones_url":"https://api.github.com/repos/DS-100/textbook/milestones{/number}","notifications_url":"https://api.github.com/repos/DS-100/textbook/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/DS-100/textbook/labels{/name}","releases_url":"https://api.github.com/repos/DS-100/textbook/releases{/id}","deployments_url":"https://api.github.com/repos/DS-100/textbook/deployments","created_at":"2018-01-07T09:10:32Z","updated_at":"2018-06-21T21:46:02Z","pushed_at":"2018-06-23T16:05:50Z","git_url":"git://github.com/DS-100/textbook.git","ssh_url":"git@github.com:DS-100/textbook.git","clone_url":"https://github.com/DS-100/textbook.git","svn_url":"https://github.com/DS-100/textbook","homepage":"https://www.textbook.ds100.org/","size":35306,"stargazers_count":12,"watchers_count":12,"language":"Jupyter Notebook","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":6,"mirror_url":null,"archived":false,"open_issues_count":9,"license":null,"forks":6,"open_issues":9,"watchers":12,"default_branch":"master"}},"base":{"label":"DS-100:master","ref":"master","sha":"ac3f65da49bf6906f0f9eb805c95a04688834d4d","user":{"login":"DS-100","id":22970565,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIyOTcwNTY1","avatar_url":"https://avatars3.githubusercontent.com/u/22970565?v=4","gravatar_id":"","url":"https://api.github.com/users/DS-100","html_url":"https://github.com/DS-100","followers_url":"https://api.github.com/users/DS-100/followers","following_url":"https://api.github.com/users/DS-100/following{/other_user}","gists_url":"https://api.github.com/users/DS-100/gists{/gist_id}","starred_url":"https://api.github.com/users/DS-100/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DS-100/subscriptions","organizations_url":"https://api.github.com/users/DS-100/orgs","repos_url":"https://api.github.com/users/DS-100/repos","events_url":"https://api.github.com/users/DS-100/events{/privacy}","received_events_url":"https://api.github.com/users/DS-100/received_events","type":"Organization","site_admin":false},"repo":{"id":116552199,"node_id":"MDEwOlJlcG9zaXRvcnkxMTY1NTIxOTk=","name":"textbook","full_name":"DS-100/textbook","owner":{"login":"DS-100","id":22970565,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIyOTcwNTY1","avatar_url":"https://avatars3.githubusercontent.com/u/22970565?v=4","gravatar_id":"","url":"https://api.github.com/users/DS-100","html_url":"https://github.com/DS-100","followers_url":"https://api.github.com/users/DS-100/followers","following_url":"https://api.github.com/users/DS-100/following{/other_user}","gists_url":"https://api.github.com/users/DS-100/gists{/gist_id}","starred_url":"https://api.github.com/users/DS-100/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DS-100/subscriptions","organizations_url":"https://api.github.com/users/DS-100/orgs","repos_url":"https://api.github.com/users/DS-100/repos","events_url":"https://api.github.com/users/DS-100/events{/privacy}","received_events_url":"https://api.github.com/users/DS-100/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/DS-100/textbook","description":"Textbook for DS100 at UC Berkeley","fork":false,"url":"https://api.github.com/repos/DS-100/textbook","forks_url":"https://api.github.com/repos/DS-100/textbook/forks","keys_url":"https://api.github.com/repos/DS-100/textbook/keys{/key_id}","collaborators_url":"https://api.github.com/repos/DS-100/textbook/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/DS-100/textbook/teams","hooks_url":"https://api.github.com/repos/DS-100/textbook/hooks","issue_events_url":"https://api.github.com/repos/DS-100/textbook/issues/events{/number}","events_url":"https://api.github.com/repos/DS-100/textbook/events","assignees_url":"https://api.github.com/repos/DS-100/textbook/assignees{/user}","branches_url":"https://api.github.com/repos/DS-100/textbook/branches{/branch}","tags_url":"https://api.github.com/repos/DS-100/textbook/tags","blobs_url":"https://api.github.com/repos/DS-100/textbook/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/DS-100/textbook/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/DS-100/textbook/git/refs{/sha}","trees_url":"https://api.github.com/repos/DS-100/textbook/git/trees{/sha}","statuses_url":"https://api.github.com/repos/DS-100/textbook/statuses/{sha}","languages_url":"https://api.github.com/repos/DS-100/textbook/languages","stargazers_url":"https://api.github.com/repos/DS-100/textbook/stargazers","contributors_url":"https://api.github.com/repos/DS-100/textbook/contributors","subscribers_url":"https://api.github.com/repos/DS-100/textbook/subscribers","subscription_url":"https://api.github.com/repos/DS-100/textbook/subscription","commits_url":"https://api.github.com/repos/DS-100/textbook/commits{/sha}","git_commits_url":"https://api.github.com/repos/DS-100/textbook/git/commits{/sha}","comments_url":"https://api.github.com/repos/DS-100/textbook/comments{/number}","issue_comment_url":"https://api.github.com/repos/DS-100/textbook/issues/comments{/number}","contents_url":"https://api.github.com/repos/DS-100/textbook/contents/{+path}","compare_url":"https://api.github.com/repos/DS-100/textbook/compare/{base}...{head}","merges_url":"https://api.github.com/repos/DS-100/textbook/merges","archive_url":"https://api.github.com/repos/DS-100/textbook/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/DS-100/textbook/downloads","issues_url":"https://api.github.com/repos/DS-100/textbook/issues{/number}","pulls_url":"https://api.github.com/repos/DS-100/textbook/pulls{/number}","milestones_url":"https://api.github.com/repos/DS-100/textbook/milestones{/number}","notifications_url":"https://api.github.com/repos/DS-100/textbook/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/DS-100/textbook/labels{/name}","releases_url":"https://api.github.com/repos/DS-100/textbook/releases{/id}","deployments_url":"https://api.github.com/repos/DS-100/textbook/deployments","created_at":"2018-01-07T09:10:32Z","updated_at":"2018-06-21T21:46:02Z","pushed_at":"2018-06-23T16:05:50Z","git_url":"git://github.com/DS-100/textbook.git","ssh_url":"git@github.com:DS-100/textbook.git","clone_url":"https://github.com/DS-100/textbook.git","svn_url":"https://github.com/DS-100/textbook","homepage":"https://www.textbook.ds100.org/","size":35306,"stargazers_count":12,"watchers_count":12,"language":"Jupyter Notebook","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":6,"mirror_url":null,"archived":false,"open_issues_count":9,"license":null,"forks":6,"open_issues":9,"watchers":12,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/DS-100/textbook/pulls/40"},"html":{"href":"https://github.com/DS-100/textbook/pull/40"},"issue":{"href":"https://api.github.com/repos/DS-100/textbook/issues/40"},"comments":{"href":"https://api.github.com/repos/DS-100/textbook/issues/40/comments"},"review_comments":{"href":"https://api.github.com/repos/DS-100/textbook/pulls/40/comments"},"review_comment":{"href":"https://api.github.com/repos/DS-100/textbook/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/DS-100/textbook/pulls/40/commits"},"statuses":{"href":"https://api.github.com/repos/DS-100/textbook/statuses/90fde3c00a0d0978a95214c06ab2a845e07fee27"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"ashleychien"}}