diff --git a/.RData b/.RData new file mode 100644 index 000000000..0b1a9aeed Binary files /dev/null and b/.RData differ diff --git a/.Rhistory b/.Rhistory new file mode 100644 index 000000000..672f44eed --- /dev/null +++ b/.Rhistory @@ -0,0 +1,15 @@ +install.packages('tidymodels') +install.packages("tidymodels") +install.packages("tidymodels") +install.packages("tidymodels") +install.packages("tidymodels") +install.packages('tidyverse') +install.packages("tidyverse") +install.packages("tidyverse") +install.packages("tidyverse") +install.packages('tidyverse') +install.packages("tidyverse") +install.packages("tidyverse") +unloadNamespace("dplyr") +detach(package:dplyr) +unloadNamespace("dplyr") diff --git a/.gitignore b/.gitignore index 56a48b66f..01ed90e05 100644 --- a/.gitignore +++ b/.gitignore @@ -355,3 +355,4 @@ MigrationBackup/ # Mac-specific .DS_Store +.Rproj.user diff --git a/2-Regression/1-Tools/solution/R/lesson_1.html b/2-Regression/1-Tools/solution/R/lesson_1.html new file mode 100644 index 000000000..d0048cec6 --- /dev/null +++ b/2-Regression/1-Tools/solution/R/lesson_1.html @@ -0,0 +1,3390 @@ + + + + + + + + + + + + + +Build a regression model: Get started with R and Tidymodels for regression models + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+
+ +
+ + + + + + + +
+

Introduction to Regression - Lesson 1

+
+

Putting it into perspective

+

✅ There are many types of regression methods, and which one you pick +depends on the answer you’re looking for. If you want to predict the +probable height for a person of a given age, you’d use +linear regression, as you’re seeking a numeric +value. If you’re interested in discovering whether a type of +cuisine should be considered vegan or not, you’re looking for a +category assignment so you would use +logistic regression. You’ll learn more about logistic +regression later. Think a bit about some questions you can ask of data, +and which of these methods would be more appropriate.

+

In this section, you will work with a small +dataset about diabetes. Imagine that you wanted to test a treatment +for diabetic patients. Machine Learning models might help you determine +which patients would respond better to the treatment, based on +combinations of variables. Even a very basic regression model, when +visualized, might show information about variables that would help you +organize your theoretical clinical trials.

+

That said, let’s get started on this task!

+
+ +

Artwork by @allison_horst

+
+
+
+
+

1. Loading up our tool set

+

For this task, we’ll require the following packages:

+ +

You can have them installed as:

+

install.packages(c("tidyverse", "tidymodels"))

+

The script below checks whether you have the packages required to +complete this module and installs them for you in case they are +missing.

+
if (!require("pacman")) install.packages("pacman")
+pacman::p_load(tidyverse, tidymodels)
+

Now, let’s load these awesome packages and make them available in our +current R session. (This is for mere illustration, +pacman::p_load() already did that for you)

+
# load the core Tidyverse packages
+library(tidyverse)
+
+# load the core Tidymodels packages
+library(tidymodels)
+
+
+

2. The diabetes dataset

+

In this exercise, we’ll put our regression skills into display by +making predictions on a diabetes dataset. The diabetes +dataset includes 442 samples of data around diabetes, +with 10 predictor feature variables, age, sex, +body mass index, average blood pressure, and +six blood serum measurements as well as an outcome variable +y: a quantitative measure of disease progression one year +after baseline.

+ ++++ + + + + + + + + + + + + + + + + + + + + +
Number of observations442
Number of predictorsFirst 10 columns are numeric predictive values
Outcome/TargetColumn 11 is a quantitative measure of disease progression one year +after baseline
Predictor Information
    +
  • age age in years
  • +
  • sex
  • +
  • bmi body mass index
  • +
  • bp average blood pressure
  • +
  • s1 tc, total serum cholesterol
  • +
  • s2 ldl, low-density lipoproteins
  • +
  • s3 hdl, high-density lipoproteins
  • +
  • s4 tch, total cholesterol / HDL
  • +
  • s5 ltg, possibly log of serum triglycerides level
  • +
  • s6 glu, blood sugar level
  • +
+
+

🎓 Remember, this is supervised learning, and we need a named ‘y’ +target.

+
+

Before you can manipulate data with R, you need to import the data +into R’s memory, or build a connection to the data that R can use to +access the data remotely.
+

+
+

The readr package, which +is part of the Tidyverse, provides a fast and friendly way to read +rectangular data into R.

+
+

Now, let’s load the diabetes dataset provided in this source URL: https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html

+

Also, we’ll perform a sanity check on our data using +glimpse() and dsiplay the first 5 rows using +slice().

+

Before going any further, let’s introduce something you will +encounter quite often in R code: the pipe operator +%>%

+

The pipe operator (%>%) performs operations in +logical sequence by passing an object forward into a function or call +expression. You can think of the pipe operator as saying “and then” in +your code.
+

+
# Import the data set
+diabetes <- read_table2(file = "https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt")
+
+
+# Get a glimpse and dimensions of the data
+glimpse(diabetes)
+
## Rows: 442
+## Columns: 11
+## $ age <dbl> 0.038075906, -0.001882017, 0.085298906, -0.089062939, 0.005383060,~
+## $ sex <dbl> 0.05068012, -0.04464164, 0.05068012, -0.04464164, -0.04464164, -0.~
+## $ bmi <dbl> 0.061696207, -0.051474061, 0.044451213, -0.011595015, -0.036384692~
+## $ map <dbl> 0.021872355, -0.026327835, -0.005670611, -0.036656447, 0.021872355~
+## $ tc  <dbl> -0.044223498, -0.008448724, -0.045599451, 0.012190569, 0.003934852~
+## $ ldl <dbl> -3.482076e-02, -1.916334e-02, -3.419447e-02, 2.499059e-02, 1.55961~
+## $ hdl <dbl> -0.043400846, 0.074411564, -0.032355932, -0.036037570, 0.008142084~
+## $ tch <dbl> -0.002592262, -0.039493383, -0.002592262, 0.034308859, -0.00259226~
+## $ ltg <dbl> 0.019908421, -0.068329744, 0.002863771, 0.022692023, -0.031991445,~
+## $ glu <dbl> -0.017646125, -0.092204050, -0.025930339, -0.009361911, -0.0466408~
+## $ y   <dbl> 151, 75, 141, 206, 135, 97, 138, 63, 110, 310, 101, 69, 179, 185, ~
+
# Select the first 5 rows of the data
+diabetes %>% 
+  slice(1:5)
+
+ +
+

glimpse() shows us that this data has 442 rows and 11 +columns with all the columns being of data type double

+
+

glimpse() and slice() are functions in dplyr. Dplyr, part +of the Tidyverse, is a grammar of data manipulation that provides a +consistent set of verbs that help you solve the most common data +manipulation challenges

+
+

Now that we have the data, let’s narrow down to one feature +(bmi) to target for this exercise. This will require us to +select the desired columns. So, how do we do this?

+

dplyr::select() +allows us to select (and optionally rename) columns in a data +frame.

+
# Select predictor feature `bmi` and outcome `y`
+diabetes_select <- diabetes %>% 
+  select(c(bmi, y))
+
+# Print the first 5 rows
+diabetes_select %>% 
+  slice(1:5)
+
+ +
+
+
+

3. Training and Testing data

+

It’s common practice in supervised learning to split the +data into two subsets; a (typically larger) set with which to train the +model, and a smaller “hold-back” set with which to see how the model +performed.

+

Now that we have data ready, we can see if a machine can help +determine a logical split between the numbers in this dataset. We can +use the rsample +package, which is part of the Tidymodels framework, to create an object +that contains the information on how to split the data, and +then two more rsample functions to extract the created training and +testing sets:

+
set.seed(2056)
+# Split 67% of the data for training and the rest for testing
+diabetes_split <- diabetes_select %>% 
+  initial_split(prop = 0.67)
+
+# Extract the resulting train and test sets
+diabetes_train <- training(diabetes_split)
+diabetes_test <- testing(diabetes_split)
+
+# Print the first 3 rows of the training set
+diabetes_train %>% 
+  slice(1:3)
+
+ +
+
+
+

4. Train a linear regression model with Tidymodels

+

Now we are ready to train our model!

+

In Tidymodels, you specify models using parsnip() by +specifying three concepts:

+
    +
  • Model type differentiates models such as linear +regression, logistic regression, decision tree models, and so +forth.

  • +
  • Model mode includes common options like +regression and classification; some model types support either of these +while some only have one mode.

  • +
  • Model engine is the computational tool which +will be used to fit the model. Often these are R packages, such as +"lm" or +"ranger"

  • +
+

This modeling information is captured in a model specification, so +let’s build one!

+
# Build a linear model specification
+lm_spec <- 
+  # Type
+  linear_reg() %>% 
+  # Engine
+  set_engine("lm") %>% 
+  # Mode
+  set_mode("regression")
+
+
+# Print the model specification
+lm_spec
+
## Linear Regression Model Specification (regression)
+## 
+## Computational engine: lm
+

After a model has been specified, the model can be +estimated or trained using the fit() +function, typically using a formula and some data.

+

y ~ . means we’ll fit y as the predicted +quantity/target, explained by all the predictors/features ie, +. (in this case, we only have one predictor: +bmi )

+
# Build a linear model specification
+lm_spec <- linear_reg() %>% 
+  set_engine("lm") %>%
+  set_mode("regression")
+
+
+# Train a linear regression model
+lm_mod <- lm_spec %>% 
+  fit(y ~ ., data = diabetes_train)
+
+# Print the model
+lm_mod
+
## parsnip model object
+## 
+## 
+## Call:
+## stats::lm(formula = y ~ ., data = data)
+## 
+## Coefficients:
+## (Intercept)          bmi  
+##       154.7        996.3
+

From the model output, we can see the coefficients learned during +training. They represent the coefficients of the line of best fit that +gives us the lowest overall error between the actual and predicted +variable.

+
+
+

5. Make predictions on the test set

+

Now that we’ve trained a model, we can use it to predict the disease +progression y for the test dataset using parsnip::predict(). +This will be used to draw the line between data groups.

+
# Make predictions for the test set
+predictions <- lm_mod %>% 
+  predict(new_data = diabetes_test)
+
+# Print out some of the predictions
+predictions %>% 
+  slice(1:5)
+
+ +
+

Woohoo! 💃🕺 We just trained a model and used it to make +predictions!

+

When making predictions, the tidymodels convention is to always +produce a tibble/data frame of results with standardized column names. +This makes it easy to combine the original data and the predictions in a +usable format for subsequent operations such as plotting.

+

dplyr::bind_cols() efficiently binds multiple data +frames column.

+
# Combine the predictions and the original test set
+results <- diabetes_test %>% 
+  bind_cols(predictions)
+
+
+results %>% 
+  slice(1:5)
+
+ +
+
+
+

6. Plot modelling results

+

Now, its time to see this visually 📈. We’ll create a scatter plot of +all the y and bmi values of the test set, then +use the predictions to draw a line in the most appropriate place, +between the model’s data groupings.

+

R has several systems for making graphs, but ggplot2 is +one of the most elegant and most versatile. This allows you to compose +graphs by combining independent components.

+
# Set a theme for the plot
+theme_set(theme_light())
+# Create a scatter plot
+results %>% 
+  ggplot(aes(x = bmi)) +
+  # Add a scatter plot
+  geom_point(aes(y = y), size = 1.6) +
+  # Add a line plot
+  geom_line(aes(y = .pred), color = "blue", size = 1.5)
+

+
+

✅ Think a bit about what’s going on here. A straight line is running +through many small dots of data, but what is it doing exactly? Can you +see how you should be able to use this line to predict where a new, +unseen data point should fit in relationship to the plot’s y axis? Try +to put into words the practical use of this model.

+
+

Congratulations, you built your first linear regression model, +created a prediction with it, and displayed it in a plot!

+
+ +
LS0tDQp0aXRsZTogJ0J1aWxkIGEgcmVncmVzc2lvbiBtb2RlbDogR2V0IHN0YXJ0ZWQgd2l0aCBSIGFuZCBUaWR5bW9kZWxzIGZvciByZWdyZXNzaW9uIG1vZGVscycNCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICB0aGVtZTogZmxhdGx5DQogICAgaGlnaGxpZ2h0OiBicmVlemVkYXJrDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KLS0tDQoNCiMjIEludHJvZHVjdGlvbiB0byBSZWdyZXNzaW9uIC0gTGVzc29uIDENCg0KIyMjIyBQdXR0aW5nIGl0IGludG8gcGVyc3BlY3RpdmUNCg0K4pyFIFRoZXJlIGFyZSBtYW55IHR5cGVzIG9mIHJlZ3Jlc3Npb24gbWV0aG9kcywgYW5kIHdoaWNoIG9uZSB5b3UgcGljayBkZXBlbmRzIG9uIHRoZSBhbnN3ZXIgeW91J3JlIGxvb2tpbmcgZm9yLiBJZiB5b3Ugd2FudCB0byBwcmVkaWN0IHRoZSBwcm9iYWJsZSBoZWlnaHQgZm9yIGEgcGVyc29uIG9mIGEgZ2l2ZW4gYWdlLCB5b3UnZCB1c2UgYGxpbmVhciByZWdyZXNzaW9uYCwgYXMgeW91J3JlIHNlZWtpbmcgYSAqKm51bWVyaWMgdmFsdWUqKi4gSWYgeW91J3JlIGludGVyZXN0ZWQgaW4gZGlzY292ZXJpbmcgd2hldGhlciBhIHR5cGUgb2YgY3Vpc2luZSBzaG91bGQgYmUgY29uc2lkZXJlZCB2ZWdhbiBvciBub3QsIHlvdSdyZSBsb29raW5nIGZvciBhICoqY2F0ZWdvcnkgYXNzaWdubWVudCoqIHNvIHlvdSB3b3VsZCB1c2UgYGxvZ2lzdGljIHJlZ3Jlc3Npb25gLiBZb3UnbGwgbGVhcm4gbW9yZSBhYm91dCBsb2dpc3RpYyByZWdyZXNzaW9uIGxhdGVyLiBUaGluayBhIGJpdCBhYm91dCBzb21lIHF1ZXN0aW9ucyB5b3UgY2FuIGFzayBvZiBkYXRhLCBhbmQgd2hpY2ggb2YgdGhlc2UgbWV0aG9kcyB3b3VsZCBiZSBtb3JlIGFwcHJvcHJpYXRlLg0KDQpJbiB0aGlzIHNlY3Rpb24sIHlvdSB3aWxsIHdvcmsgd2l0aCBhIFtzbWFsbCBkYXRhc2V0IGFib3V0IGRpYWJldGVzXShodHRwczovL3d3dzQuc3RhdC5uY3N1LmVkdS9+Ym9vcy92YXIuc2VsZWN0L2RpYWJldGVzLmh0bWwpLiBJbWFnaW5lIHRoYXQgeW91IHdhbnRlZCB0byB0ZXN0IGEgdHJlYXRtZW50IGZvciBkaWFiZXRpYyBwYXRpZW50cy4gTWFjaGluZSBMZWFybmluZyBtb2RlbHMgbWlnaHQgaGVscCB5b3UgZGV0ZXJtaW5lIHdoaWNoIHBhdGllbnRzIHdvdWxkIHJlc3BvbmQgYmV0dGVyIHRvIHRoZSB0cmVhdG1lbnQsIGJhc2VkIG9uIGNvbWJpbmF0aW9ucyBvZiB2YXJpYWJsZXMuIEV2ZW4gYSB2ZXJ5IGJhc2ljIHJlZ3Jlc3Npb24gbW9kZWwsIHdoZW4gdmlzdWFsaXplZCwgbWlnaHQgc2hvdyBpbmZvcm1hdGlvbiBhYm91dCB2YXJpYWJsZXMgdGhhdCB3b3VsZCBoZWxwIHlvdSBvcmdhbml6ZSB5b3VyIHRoZW9yZXRpY2FsIGNsaW5pY2FsIHRyaWFscy4NCg0KVGhhdCBzYWlkLCBsZXQncyBnZXQgc3RhcnRlZCBvbiB0aGlzIHRhc2shDQoNCiFbQXJ0d29yayBieSBcQGFsbGlzb25faG9yc3RdKC4uLy4uL2ltYWdlcy9lbmNvdVJhZ2UuanBnKXt3aWR0aD0iNjMwIn0NCg0KIyMgMS4gTG9hZGluZyB1cCBvdXIgdG9vbCBzZXQNCg0KRm9yIHRoaXMgdGFzaywgd2UnbGwgcmVxdWlyZSB0aGUgZm9sbG93aW5nIHBhY2thZ2VzOg0KDQotICAgYHRpZHl2ZXJzZWA6IFRoZSBbdGlkeXZlcnNlXShodHRwczovL3d3dy50aWR5dmVyc2Uub3JnLykgaXMgYSBbY29sbGVjdGlvbiBvZiBSIHBhY2thZ2VzXShodHRwczovL3d3dy50aWR5dmVyc2Uub3JnL3BhY2thZ2VzKSBkZXNpZ25lZCB0byBtYWtlcyBkYXRhIHNjaWVuY2UgZmFzdGVyLCBlYXNpZXIgYW5kIG1vcmUgZnVuIQ0KDQotICAgYHRpZHltb2RlbHNgOiBUaGUgW3RpZHltb2RlbHNdKGh0dHBzOi8vd3d3LnRpZHltb2RlbHMub3JnLykgZnJhbWV3b3JrIGlzIGEgW2NvbGxlY3Rpb24gb2YgcGFja2FnZXNdKGh0dHBzOi8vd3d3LnRpZHltb2RlbHMub3JnL3BhY2thZ2VzLykgZm9yIG1vZGVsaW5nIGFuZCBtYWNoaW5lIGxlYXJuaW5nLg0KDQpZb3UgY2FuIGhhdmUgdGhlbSBpbnN0YWxsZWQgYXM6DQoNCmBpbnN0YWxsLnBhY2thZ2VzKGMoInRpZHl2ZXJzZSIsICJ0aWR5bW9kZWxzIikpYA0KDQpUaGUgc2NyaXB0IGJlbG93IGNoZWNrcyB3aGV0aGVyIHlvdSBoYXZlIHRoZSBwYWNrYWdlcyByZXF1aXJlZCB0byBjb21wbGV0ZSB0aGlzIG1vZHVsZSBhbmQgaW5zdGFsbHMgdGhlbSBmb3IgeW91IGluIGNhc2UgdGhleSBhcmUgbWlzc2luZy4NCg0KYGBge3IsIG1lc3NhZ2U9Riwgd2FybmluZz1GfQ0KaWYgKCFyZXF1aXJlKCJwYWNtYW4iKSkgaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikNCnBhY21hbjo6cF9sb2FkKHRpZHl2ZXJzZSwgdGlkeW1vZGVscykNCmBgYA0KDQpOb3csIGxldCdzIGxvYWQgdGhlc2UgYXdlc29tZSBwYWNrYWdlcyBhbmQgbWFrZSB0aGVtIGF2YWlsYWJsZSBpbiBvdXIgY3VycmVudCBSIHNlc3Npb24uIChUaGlzIGlzIGZvciBtZXJlIGlsbHVzdHJhdGlvbiwgYHBhY21hbjo6cF9sb2FkKClgIGFscmVhZHkgZGlkIHRoYXQgZm9yIHlvdSkNCg0KYGBge3IgbG9hZF90aWR5X3ZlcnNlX21vZGVscywgbWVzc2FnZT1GLCB3YXJuaW5nPUZ9DQojIGxvYWQgdGhlIGNvcmUgVGlkeXZlcnNlIHBhY2thZ2VzDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCg0KIyBsb2FkIHRoZSBjb3JlIFRpZHltb2RlbHMgcGFja2FnZXMNCmxpYnJhcnkodGlkeW1vZGVscykNCg0KDQpgYGANCg0KIyMgMi4gVGhlIGRpYWJldGVzIGRhdGFzZXQNCg0KSW4gdGhpcyBleGVyY2lzZSwgd2UnbGwgcHV0IG91ciByZWdyZXNzaW9uIHNraWxscyBpbnRvIGRpc3BsYXkgYnkgbWFraW5nIHByZWRpY3Rpb25zIG9uIGEgZGlhYmV0ZXMgZGF0YXNldC4gVGhlIFtkaWFiZXRlcyBkYXRhc2V0XShodHRwczovL3d3dzQuc3RhdC5uY3N1LmVkdS9+Ym9vcy92YXIuc2VsZWN0L2RpYWJldGVzLnJ3cml0ZTEudHh0KSBpbmNsdWRlcyBgNDQyIHNhbXBsZXNgIG9mIGRhdGEgYXJvdW5kIGRpYWJldGVzLCB3aXRoIDEwIHByZWRpY3RvciBmZWF0dXJlIHZhcmlhYmxlcywgYGFnZWAsIGBzZXhgLCBgYm9keSBtYXNzIGluZGV4YCwgYGF2ZXJhZ2UgYmxvb2QgcHJlc3N1cmVgLCBhbmQgYHNpeCBibG9vZCBzZXJ1bSBtZWFzdXJlbWVudHNgIGFzIHdlbGwgYXMgYW4gb3V0Y29tZSB2YXJpYWJsZSBgeWA6IGEgcXVhbnRpdGF0aXZlIG1lYXN1cmUgb2YgZGlzZWFzZSBwcm9ncmVzc2lvbiBvbmUgeWVhciBhZnRlciBiYXNlbGluZS4NCg0KKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKw0KfCAqKk51bWJlciBvZiBvYnNlcnZhdGlvbnMqKiB8ICoqNDQyKiogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KKz09PT09PT09PT09PT09PT09PT09PT09PT09PT0rPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Kw0KfCAqKk51bWJlciBvZiBwcmVkaWN0b3JzKiogICB8IEZpcnN0IDEwIGNvbHVtbnMgYXJlIG51bWVyaWMgcHJlZGljdGl2ZSB2YWx1ZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKw0KfCAqKk91dGNvbWUvVGFyZ2V0KiogICAgICAgICB8IENvbHVtbiAxMSBpcyBhIHF1YW50aXRhdGl2ZSBtZWFzdXJlIG9mIGRpc2Vhc2UgcHJvZ3Jlc3Npb24gb25lIHllYXIgYWZ0ZXIgYmFzZWxpbmUgfA0KKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKw0KfCAqKlByZWRpY3RvciBJbmZvcm1hdGlvbioqICB8IC0gICBhZ2UgYWdlIGluIHllYXJzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IC0gICBzZXggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IC0gICBibWkgYm9keSBtYXNzIGluZGV4ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IC0gICBicCBhdmVyYWdlIGJsb29kIHByZXNzdXJlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IC0gICBzMSB0YywgdG90YWwgc2VydW0gY2hvbGVzdGVyb2wgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IC0gICBzMiBsZGwsIGxvdy1kZW5zaXR5IGxpcG9wcm90ZWlucyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IC0gICBzMyBoZGwsIGhpZ2gtZGVuc2l0eSBsaXBvcHJvdGVpbnMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IC0gICBzNCB0Y2gsIHRvdGFsIGNob2xlc3Rlcm9sIC8gSERMICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IC0gICBzNSBsdGcsIHBvc3NpYmx5IGxvZyBvZiBzZXJ1bSB0cmlnbHljZXJpZGVzIGxldmVsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IC0gICBzNiBnbHUsIGJsb29kIHN1Z2FyIGxldmVsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKw0KDQo+IPCfjpMgUmVtZW1iZXIsIHRoaXMgaXMgc3VwZXJ2aXNlZCBsZWFybmluZywgYW5kIHdlIG5lZWQgYSBuYW1lZCAneScgdGFyZ2V0Lg0KDQpCZWZvcmUgeW91IGNhbiBtYW5pcHVsYXRlIGRhdGEgd2l0aCBSLCB5b3UgbmVlZCB0byBpbXBvcnQgdGhlIGRhdGEgaW50byBSJ3MgbWVtb3J5LCBvciBidWlsZCBhIGNvbm5lY3Rpb24gdG8gdGhlIGRhdGEgdGhhdCBSIGNhbiB1c2UgdG8gYWNjZXNzIHRoZSBkYXRhIHJlbW90ZWx5LlwNCg0KPiBUaGUgW3JlYWRyXShodHRwczovL3JlYWRyLnRpZHl2ZXJzZS5vcmcvKSBwYWNrYWdlLCB3aGljaCBpcyBwYXJ0IG9mIHRoZSBUaWR5dmVyc2UsIHByb3ZpZGVzIGEgZmFzdCBhbmQgZnJpZW5kbHkgd2F5IHRvIHJlYWQgcmVjdGFuZ3VsYXIgZGF0YSBpbnRvIFIuDQoNCk5vdywgbGV0J3MgbG9hZCB0aGUgZGlhYmV0ZXMgZGF0YXNldCBwcm92aWRlZCBpbiB0aGlzIHNvdXJjZSBVUkw6IDxodHRwczovL3d3dzQuc3RhdC5uY3N1LmVkdS9+Ym9vcy92YXIuc2VsZWN0L2RpYWJldGVzLmh0bWw+DQoNCkFsc28sIHdlJ2xsIHBlcmZvcm0gYSBzYW5pdHkgY2hlY2sgb24gb3VyIGRhdGEgdXNpbmcgYGdsaW1wc2UoKWAgYW5kIGRzaXBsYXkgdGhlIGZpcnN0IDUgcm93cyB1c2luZyBgc2xpY2UoKWAuDQoNCkJlZm9yZSBnb2luZyBhbnkgZnVydGhlciwgbGV0J3MgaW50cm9kdWNlIHNvbWV0aGluZyB5b3Ugd2lsbCBlbmNvdW50ZXIgcXVpdGUgb2Z0ZW4gaW4gUiBjb2RlOiB0aGUgcGlwZSBvcGVyYXRvciBgJT4lYA0KDQpUaGUgcGlwZSBvcGVyYXRvciAoYCU+JWApIHBlcmZvcm1zIG9wZXJhdGlvbnMgaW4gbG9naWNhbCBzZXF1ZW5jZSBieSBwYXNzaW5nIGFuIG9iamVjdCBmb3J3YXJkIGludG8gYSBmdW5jdGlvbiBvciBjYWxsIGV4cHJlc3Npb24uIFlvdSBjYW4gdGhpbmsgb2YgdGhlIHBpcGUgb3BlcmF0b3IgYXMgc2F5aW5nICJhbmQgdGhlbiIgaW4geW91ciBjb2RlLlwNCg0KYGBge3IgbG9hZF9kYXRhc2V0LCBtZXNzYWdlPUYsIHdhcm5pbmc9Rn0NCiMgSW1wb3J0IHRoZSBkYXRhIHNldA0KZGlhYmV0ZXMgPC0gcmVhZF90YWJsZTIoZmlsZSA9ICJodHRwczovL3d3dzQuc3RhdC5uY3N1LmVkdS9+Ym9vcy92YXIuc2VsZWN0L2RpYWJldGVzLnJ3cml0ZTEudHh0IikNCg0KDQojIEdldCBhIGdsaW1wc2UgYW5kIGRpbWVuc2lvbnMgb2YgdGhlIGRhdGENCmdsaW1wc2UoZGlhYmV0ZXMpDQoNCg0KIyBTZWxlY3QgdGhlIGZpcnN0IDUgcm93cyBvZiB0aGUgZGF0YQ0KZGlhYmV0ZXMgJT4lIA0KICBzbGljZSgxOjUpDQoNCmBgYA0KDQpgZ2xpbXBzZSgpYCBzaG93cyB1cyB0aGF0IHRoaXMgZGF0YSBoYXMgNDQyIHJvd3MgYW5kIDExIGNvbHVtbnMgd2l0aCBhbGwgdGhlIGNvbHVtbnMgYmVpbmcgb2YgZGF0YSB0eXBlIGBkb3VibGVgDQoNCj4gZ2xpbXBzZSgpIGFuZCBzbGljZSgpIGFyZSBmdW5jdGlvbnMgaW4gW2BkcGx5cmBdKGh0dHBzOi8vZHBseXIudGlkeXZlcnNlLm9yZy8pLiBEcGx5ciwgcGFydCBvZiB0aGUgVGlkeXZlcnNlLCBpcyBhIGdyYW1tYXIgb2YgZGF0YSBtYW5pcHVsYXRpb24gdGhhdCBwcm92aWRlcyBhIGNvbnNpc3RlbnQgc2V0IG9mIHZlcmJzIHRoYXQgaGVscCB5b3Ugc29sdmUgdGhlIG1vc3QgY29tbW9uIGRhdGEgbWFuaXB1bGF0aW9uIGNoYWxsZW5nZXMNCg0KTm93IHRoYXQgd2UgaGF2ZSB0aGUgZGF0YSwgbGV0J3MgbmFycm93IGRvd24gdG8gb25lIGZlYXR1cmUgKGBibWlgKSB0byB0YXJnZXQgZm9yIHRoaXMgZXhlcmNpc2UuIFRoaXMgd2lsbCByZXF1aXJlIHVzIHRvIHNlbGVjdCB0aGUgZGVzaXJlZCBjb2x1bW5zLiBTbywgaG93IGRvIHdlIGRvIHRoaXM/DQoNCltgZHBseXI6OnNlbGVjdCgpYF0oaHR0cHM6Ly9kcGx5ci50aWR5dmVyc2Uub3JnL3JlZmVyZW5jZS9zZWxlY3QuaHRtbCkgYWxsb3dzIHVzIHRvICpzZWxlY3QqIChhbmQgb3B0aW9uYWxseSByZW5hbWUpIGNvbHVtbnMgaW4gYSBkYXRhIGZyYW1lLg0KDQpgYGB7ciBzZWxlY3QsIG1lc3NhZ2U9Riwgd2FybmluZz1GfQ0KIyBTZWxlY3QgcHJlZGljdG9yIGZlYXR1cmUgYGJtaWAgYW5kIG91dGNvbWUgYHlgDQpkaWFiZXRlc19zZWxlY3QgPC0gZGlhYmV0ZXMgJT4lIA0KICBzZWxlY3QoYyhibWksIHkpKQ0KDQojIFByaW50IHRoZSBmaXJzdCA1IHJvd3MNCmRpYWJldGVzX3NlbGVjdCAlPiUgDQogIHNsaWNlKDE6NSkNCmBgYA0KDQojIyAzLiBUcmFpbmluZyBhbmQgVGVzdGluZyBkYXRhDQoNCkl0J3MgY29tbW9uIHByYWN0aWNlIGluIHN1cGVydmlzZWQgbGVhcm5pbmcgdG8gKnNwbGl0KiB0aGUgZGF0YSBpbnRvIHR3byBzdWJzZXRzOyBhICh0eXBpY2FsbHkgbGFyZ2VyKSBzZXQgd2l0aCB3aGljaCB0byB0cmFpbiB0aGUgbW9kZWwsIGFuZCBhIHNtYWxsZXIgImhvbGQtYmFjayIgc2V0IHdpdGggd2hpY2ggdG8gc2VlIGhvdyB0aGUgbW9kZWwgcGVyZm9ybWVkLg0KDQpOb3cgdGhhdCB3ZSBoYXZlIGRhdGEgcmVhZHksIHdlIGNhbiBzZWUgaWYgYSBtYWNoaW5lIGNhbiBoZWxwIGRldGVybWluZSBhIGxvZ2ljYWwgc3BsaXQgYmV0d2VlbiB0aGUgbnVtYmVycyBpbiB0aGlzIGRhdGFzZXQuIFdlIGNhbiB1c2UgdGhlIFtyc2FtcGxlXShodHRwczovL3RpZHltb2RlbHMuZ2l0aHViLmlvL3JzYW1wbGUvKSBwYWNrYWdlLCB3aGljaCBpcyBwYXJ0IG9mIHRoZSBUaWR5bW9kZWxzIGZyYW1ld29yaywgdG8gY3JlYXRlIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIHRoZSBpbmZvcm1hdGlvbiBvbiAqaG93KiB0byBzcGxpdCB0aGUgZGF0YSwgYW5kIHRoZW4gdHdvIG1vcmUgcnNhbXBsZSBmdW5jdGlvbnMgdG8gZXh0cmFjdCB0aGUgY3JlYXRlZCB0cmFpbmluZyBhbmQgdGVzdGluZyBzZXRzOg0KDQpgYGB7ciBzcGxpdCwgbWVzc2FnZT1GLCB3YXJuaW5nPUZ9DQpzZXQuc2VlZCgyMDU2KQ0KIyBTcGxpdCA2NyUgb2YgdGhlIGRhdGEgZm9yIHRyYWluaW5nIGFuZCB0aGUgcmVzdCBmb3IgdGVzdGluZw0KZGlhYmV0ZXNfc3BsaXQgPC0gZGlhYmV0ZXNfc2VsZWN0ICU+JSANCiAgaW5pdGlhbF9zcGxpdChwcm9wID0gMC42NykNCg0KIyBFeHRyYWN0IHRoZSByZXN1bHRpbmcgdHJhaW4gYW5kIHRlc3Qgc2V0cw0KZGlhYmV0ZXNfdHJhaW4gPC0gdHJhaW5pbmcoZGlhYmV0ZXNfc3BsaXQpDQpkaWFiZXRlc190ZXN0IDwtIHRlc3RpbmcoZGlhYmV0ZXNfc3BsaXQpDQoNCiMgUHJpbnQgdGhlIGZpcnN0IDMgcm93cyBvZiB0aGUgdHJhaW5pbmcgc2V0DQpkaWFiZXRlc190cmFpbiAlPiUgDQogIHNsaWNlKDE6MykNCg0KYGBgDQoNCiMjIDQuIFRyYWluIGEgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgd2l0aCBUaWR5bW9kZWxzDQoNCk5vdyB3ZSBhcmUgcmVhZHkgdG8gdHJhaW4gb3VyIG1vZGVsIQ0KDQpJbiBUaWR5bW9kZWxzLCB5b3Ugc3BlY2lmeSBtb2RlbHMgdXNpbmcgYHBhcnNuaXAoKWAgYnkgc3BlY2lmeWluZyB0aHJlZSBjb25jZXB0czoNCg0KLSAgIE1vZGVsICoqdHlwZSoqIGRpZmZlcmVudGlhdGVzIG1vZGVscyBzdWNoIGFzIGxpbmVhciByZWdyZXNzaW9uLCBsb2dpc3RpYyByZWdyZXNzaW9uLCBkZWNpc2lvbiB0cmVlIG1vZGVscywgYW5kIHNvIGZvcnRoLg0KDQotICAgTW9kZWwgKiptb2RlKiogaW5jbHVkZXMgY29tbW9uIG9wdGlvbnMgbGlrZSByZWdyZXNzaW9uIGFuZCBjbGFzc2lmaWNhdGlvbjsgc29tZSBtb2RlbCB0eXBlcyBzdXBwb3J0IGVpdGhlciBvZiB0aGVzZSB3aGlsZSBzb21lIG9ubHkgaGF2ZSBvbmUgbW9kZS4NCg0KLSAgIE1vZGVsICoqZW5naW5lKiogaXMgdGhlIGNvbXB1dGF0aW9uYWwgdG9vbCB3aGljaCB3aWxsIGJlIHVzZWQgdG8gZml0IHRoZSBtb2RlbC4gT2Z0ZW4gdGhlc2UgYXJlIFIgcGFja2FnZXMsIHN1Y2ggYXMgKipgImxtImAqKiBvciAqKmAicmFuZ2VyImAqKg0KDQpUaGlzIG1vZGVsaW5nIGluZm9ybWF0aW9uIGlzIGNhcHR1cmVkIGluIGEgbW9kZWwgc3BlY2lmaWNhdGlvbiwgc28gbGV0J3MgYnVpbGQgb25lIQ0KDQpgYGB7ciBsbV9tb2RlbF9zcGVjLCBtZXNzYWdlPUYsIHdhcm5pbmc9Rn0NCiMgQnVpbGQgYSBsaW5lYXIgbW9kZWwgc3BlY2lmaWNhdGlvbg0KbG1fc3BlYyA8LSANCiAgIyBUeXBlDQogIGxpbmVhcl9yZWcoKSAlPiUgDQogICMgRW5naW5lDQogIHNldF9lbmdpbmUoImxtIikgJT4lIA0KICAjIE1vZGUNCiAgc2V0X21vZGUoInJlZ3Jlc3Npb24iKQ0KDQoNCiMgUHJpbnQgdGhlIG1vZGVsIHNwZWNpZmljYXRpb24NCmxtX3NwZWMNCg0KYGBgDQoNCkFmdGVyIGEgbW9kZWwgaGFzIGJlZW4gKnNwZWNpZmllZCosIHRoZSBtb2RlbCBjYW4gYmUgYGVzdGltYXRlZGAgb3IgYHRyYWluZWRgIHVzaW5nIHRoZSBbYGZpdCgpYF0oaHR0cHM6Ly9wYXJzbmlwLnRpZHltb2RlbHMub3JnL3JlZmVyZW5jZS9maXQuaHRtbCkgZnVuY3Rpb24sIHR5cGljYWxseSB1c2luZyBhIGZvcm11bGEgYW5kIHNvbWUgZGF0YS4NCg0KYHkgfiAuYCBtZWFucyB3ZSdsbCBmaXQgYHlgIGFzIHRoZSBwcmVkaWN0ZWQgcXVhbnRpdHkvdGFyZ2V0LCBleHBsYWluZWQgYnkgYWxsIHRoZSBwcmVkaWN0b3JzL2ZlYXR1cmVzIGllLCBgLmAgKGluIHRoaXMgY2FzZSwgd2Ugb25seSBoYXZlIG9uZSBwcmVkaWN0b3I6IGBibWlgICkNCg0KYGBge3IgdHJhaW4sIG1lc3NhZ2U9Riwgd2FybmluZz1GfQ0KIyBCdWlsZCBhIGxpbmVhciBtb2RlbCBzcGVjaWZpY2F0aW9uDQpsbV9zcGVjIDwtIGxpbmVhcl9yZWcoKSAlPiUgDQogIHNldF9lbmdpbmUoImxtIikgJT4lDQogIHNldF9tb2RlKCJyZWdyZXNzaW9uIikNCg0KDQojIFRyYWluIGEgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwNCmxtX21vZCA8LSBsbV9zcGVjICU+JSANCiAgZml0KHkgfiAuLCBkYXRhID0gZGlhYmV0ZXNfdHJhaW4pDQoNCiMgUHJpbnQgdGhlIG1vZGVsDQpsbV9tb2QNCmBgYA0KDQpGcm9tIHRoZSBtb2RlbCBvdXRwdXQsIHdlIGNhbiBzZWUgdGhlIGNvZWZmaWNpZW50cyBsZWFybmVkIGR1cmluZyB0cmFpbmluZy4gVGhleSByZXByZXNlbnQgdGhlIGNvZWZmaWNpZW50cyBvZiB0aGUgbGluZSBvZiBiZXN0IGZpdCB0aGF0IGdpdmVzIHVzIHRoZSBsb3dlc3Qgb3ZlcmFsbCBlcnJvciBiZXR3ZWVuIHRoZSBhY3R1YWwgYW5kIHByZWRpY3RlZCB2YXJpYWJsZS4NCg0KIyMgNS4gTWFrZSBwcmVkaWN0aW9ucyBvbiB0aGUgdGVzdCBzZXQNCg0KTm93IHRoYXQgd2UndmUgdHJhaW5lZCBhIG1vZGVsLCB3ZSBjYW4gdXNlIGl0IHRvIHByZWRpY3QgdGhlIGRpc2Vhc2UgcHJvZ3Jlc3Npb24geSBmb3IgdGhlIHRlc3QgZGF0YXNldCB1c2luZyBbcGFyc25pcDo6cHJlZGljdCgpXShodHRwczovL3BhcnNuaXAudGlkeW1vZGVscy5vcmcvcmVmZXJlbmNlL3ByZWRpY3QubW9kZWxfZml0Lmh0bWwpLiBUaGlzIHdpbGwgYmUgdXNlZCB0byBkcmF3IHRoZSBsaW5lIGJldHdlZW4gZGF0YSBncm91cHMuDQoNCmBgYHtyIHRlc3QsIG1lc3NhZ2U9Riwgd2FybmluZz1GfQ0KIyBNYWtlIHByZWRpY3Rpb25zIGZvciB0aGUgdGVzdCBzZXQNCnByZWRpY3Rpb25zIDwtIGxtX21vZCAlPiUgDQogIHByZWRpY3QobmV3X2RhdGEgPSBkaWFiZXRlc190ZXN0KQ0KDQojIFByaW50IG91dCBzb21lIG9mIHRoZSBwcmVkaWN0aW9ucw0KcHJlZGljdGlvbnMgJT4lIA0KICBzbGljZSgxOjUpDQpgYGANCg0KV29vaG9vISDwn5KD8J+VuiBXZSBqdXN0IHRyYWluZWQgYSBtb2RlbCBhbmQgdXNlZCBpdCB0byBtYWtlIHByZWRpY3Rpb25zIQ0KDQpXaGVuIG1ha2luZyBwcmVkaWN0aW9ucywgdGhlIHRpZHltb2RlbHMgY29udmVudGlvbiBpcyB0byBhbHdheXMgcHJvZHVjZSBhIHRpYmJsZS9kYXRhIGZyYW1lIG9mIHJlc3VsdHMgd2l0aCBzdGFuZGFyZGl6ZWQgY29sdW1uIG5hbWVzLiBUaGlzIG1ha2VzIGl0IGVhc3kgdG8gY29tYmluZSB0aGUgb3JpZ2luYWwgZGF0YSBhbmQgdGhlIHByZWRpY3Rpb25zIGluIGEgdXNhYmxlIGZvcm1hdCBmb3Igc3Vic2VxdWVudCBvcGVyYXRpb25zIHN1Y2ggYXMgcGxvdHRpbmcuDQoNCmBkcGx5cjo6YmluZF9jb2xzKClgIGVmZmljaWVudGx5IGJpbmRzIG11bHRpcGxlIGRhdGEgZnJhbWVzIGNvbHVtbi4NCg0KYGBge3IgdGVzdF9wcmVkLCBtZXNzYWdlPUYsIHdhcm5pbmc9Rn0NCiMgQ29tYmluZSB0aGUgcHJlZGljdGlvbnMgYW5kIHRoZSBvcmlnaW5hbCB0ZXN0IHNldA0KcmVzdWx0cyA8LSBkaWFiZXRlc190ZXN0ICU+JSANCiAgYmluZF9jb2xzKHByZWRpY3Rpb25zKQ0KDQoNCnJlc3VsdHMgJT4lIA0KICBzbGljZSgxOjUpDQpgYGANCg0KIyMgNi4gUGxvdCBtb2RlbGxpbmcgcmVzdWx0cw0KDQpOb3csIGl0cyB0aW1lIHRvIHNlZSB0aGlzIHZpc3VhbGx5IPCfk4guIFdlJ2xsIGNyZWF0ZSBhIHNjYXR0ZXIgcGxvdCBvZiBhbGwgdGhlIGB5YCBhbmQgYGJtaWAgdmFsdWVzIG9mIHRoZSB0ZXN0IHNldCwgdGhlbiB1c2UgdGhlIHByZWRpY3Rpb25zIHRvIGRyYXcgYSBsaW5lIGluIHRoZSBtb3N0IGFwcHJvcHJpYXRlIHBsYWNlLCBiZXR3ZWVuIHRoZSBtb2RlbCdzIGRhdGEgZ3JvdXBpbmdzLg0KDQpSIGhhcyBzZXZlcmFsIHN5c3RlbXMgZm9yIG1ha2luZyBncmFwaHMsIGJ1dCBgZ2dwbG90MmAgaXMgb25lIG9mIHRoZSBtb3N0IGVsZWdhbnQgYW5kIG1vc3QgdmVyc2F0aWxlLiBUaGlzIGFsbG93cyB5b3UgdG8gY29tcG9zZSBncmFwaHMgYnkgKipjb21iaW5pbmcgaW5kZXBlbmRlbnQgY29tcG9uZW50cyoqLg0KDQpgYGB7ciBwbG90X3ByZWQsIG1lc3NhZ2U9Riwgd2FybmluZz1GfQ0KIyBTZXQgYSB0aGVtZSBmb3IgdGhlIHBsb3QNCnRoZW1lX3NldCh0aGVtZV9saWdodCgpKQ0KIyBDcmVhdGUgYSBzY2F0dGVyIHBsb3QNCnJlc3VsdHMgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBibWkpKSArDQogICMgQWRkIGEgc2NhdHRlciBwbG90DQogIGdlb21fcG9pbnQoYWVzKHkgPSB5KSwgc2l6ZSA9IDEuNikgKw0KICAjIEFkZCBhIGxpbmUgcGxvdA0KICBnZW9tX2xpbmUoYWVzKHkgPSAucHJlZCksIGNvbG9yID0gImJsdWUiLCBzaXplID0gMS41KQ0KICANCmBgYA0KDQo+IOKchSBUaGluayBhIGJpdCBhYm91dCB3aGF0J3MgZ29pbmcgb24gaGVyZS4gQSBzdHJhaWdodCBsaW5lIGlzIHJ1bm5pbmcgdGhyb3VnaCBtYW55IHNtYWxsIGRvdHMgb2YgZGF0YSwgYnV0IHdoYXQgaXMgaXQgZG9pbmcgZXhhY3RseT8gQ2FuIHlvdSBzZWUgaG93IHlvdSBzaG91bGQgYmUgYWJsZSB0byB1c2UgdGhpcyBsaW5lIHRvIHByZWRpY3Qgd2hlcmUgYSBuZXcsIHVuc2VlbiBkYXRhIHBvaW50IHNob3VsZCBmaXQgaW4gcmVsYXRpb25zaGlwIHRvIHRoZSBwbG90J3MgeSBheGlzPyBUcnkgdG8gcHV0IGludG8gd29yZHMgdGhlIHByYWN0aWNhbCB1c2Ugb2YgdGhpcyBtb2RlbC4NCg0KQ29uZ3JhdHVsYXRpb25zLCB5b3UgYnVpbHQgeW91ciBmaXJzdCBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbCwgY3JlYXRlZCBhIHByZWRpY3Rpb24gd2l0aCBpdCwgYW5kIGRpc3BsYXllZCBpdCBpbiBhIHBsb3QhDQo=
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + diff --git a/ML-For-Beginners.Rproj b/ML-For-Beginners.Rproj new file mode 100644 index 000000000..8e3c2ebc9 --- /dev/null +++ b/ML-For-Beginners.Rproj @@ -0,0 +1,13 @@ +Version: 1.0 + +RestoreWorkspace: Default +SaveWorkspace: Default +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX diff --git a/README.md b/README.md index c5bf3ad3a..9e6622efc 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ By ensuring that the content aligns with projects, the process is made more enga | 02 | The History of machine learning | [Introduction](1-Introduction/README.md) | Learn the history underlying this field | [Lesson](1-Introduction/2-history-of-ML/README.md) | Jen and Amy | | 03 | Fairness and machine learning | [Introduction](1-Introduction/README.md) | What are the important philosophical issues around fairness that students should consider when building and applying ML models? | [Lesson](1-Introduction/3-fairness/README.md) | Tomomi | | 04 | Techniques for machine learning | [Introduction](1-Introduction/README.md) | What techniques do ML researchers use to build ML models? | [Lesson](1-Introduction/4-techniques-of-ML/README.md) | Chris and Jen | -| 05 | Introduction to regression | [Regression](2-Regression/README.md) | Get started with Python and Scikit-learn for regression models | | | +| 05 | Introduction to regression | [Regression](2-Regression/README.md) | Get started with Python and Scikit-learn for regression models | | | | 06 | North American pumpkin prices 🎃 | [Regression](2-Regression/README.md) | Visualize and clean data in preparation for ML | | | | 07 | North American pumpkin prices 🎃 | [Regression](2-Regression/README.md) | Build linear and polynomial regression models | | | | 08 | North American pumpkin prices 🎃 | [Regression](2-Regression/README.md) | Build a logistic regression model | | |