|
Machine Learning with R Basel R Bootcamp |
from Medium.com
By the end of this practical you will know how to:
In this section, we will again predict college graduation rates Grad_Rate
from the college_train
and college_test
datasets.
Open your BaselRBootcamp
R project. It should already have the folders 1_Data
and 2_Code
. Make sure that the data file(s) listed in the Datasets
section are in your 1_Data
folder.
Open a new R script. At the top of the script, using comments, write your name and the date. Save it as a new file called Prediction_College_practical.R
in the 2_Code
folder.
Using library()
load the set of packages for this practical listed in the packages section above.
# Load packages necessary for this script
library(tidyverse)
library(caret)
library(party)
library(partykit)
Datasets
as new objects.# College data
college_train <- read_csv(file = "1_Data/college_train.csv")
college_test <- read_csv(file = "1_Data/college_test.csv")
# Print dataframes to the console
college_train
# A tibble: 500 x 18
Private Apps Accept Enroll Top10perc Top25perc F.Undergrad P.Undergrad
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Yes 1202 1054 326 18 44 1410 299
2 Yes 1415 714 338 18 52 1345 44
3 Yes 4778 2767 678 50 89 2587 120
4 Yes 1220 974 481 28 67 1964 623
5 Yes 1981 1541 514 18 36 1927 1084
6 Yes 1217 1088 496 36 69 1773 884
7 No 8579 5561 3681 25 50 17880 1673
8 No 833 669 279 3 13 1224 345
9 No 10706 7219 2397 12 37 14826 1979
10 Yes 938 864 511 29 62 1715 103
# … with 490 more rows, and 10 more variables: Outstate <dbl>,
# Room.Board <dbl>, Books <dbl>, Personal <dbl>, PhD <dbl>,
# Terminal <dbl>, S.F.Ratio <dbl>, perc.alumni <dbl>, Expend <dbl>,
# Grad.Rate <dbl>
college_test
# A tibble: 277 x 18
Private Apps Accept Enroll Top10perc Top25perc F.Undergrad P.Undergrad
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 No 9251 7333 3076 14 45 13699 1213
2 Yes 1480 1257 452 6 25 2961 572
3 No 2336 1725 1043 10 27 5438 4058
4 Yes 1262 1102 276 14 40 978 98
5 Yes 959 771 351 23 48 1662 209
6 Yes 331 331 225 15 36 1100 166
7 Yes 804 632 281 29 72 840 68
8 No 285 280 208 21 43 1140 473
9 Yes 323 278 122 31 51 393 4
10 Yes 504 482 185 10 36 550 84
# … with 267 more rows, and 10 more variables: Outstate <dbl>,
# Room.Board <dbl>, Books <dbl>, Personal <dbl>, PhD <dbl>,
# Terminal <dbl>, S.F.Ratio <dbl>, perc.alumni <dbl>, Expend <dbl>,
# Grad.Rate <dbl>
dim()
function.# Print numbers of rows and columns
dim(XXX)
dim(XXX)
dim(college_train)
[1] 500 18
dim(college_test)
[1] 277 18
names()
function.# Print the names of each dataframe
names(XXX)
names(XXX)
names(college_train)
[1] "Private" "Apps" "Accept" "Enroll" "Top10perc"
[6] "Top25perc" "F.Undergrad" "P.Undergrad" "Outstate" "Room.Board"
[11] "Books" "Personal" "PhD" "Terminal" "S.F.Ratio"
[16] "perc.alumni" "Expend" "Grad.Rate"
names(college_test)
[1] "Private" "Apps" "Accept" "Enroll" "Top10perc"
[6] "Top25perc" "F.Undergrad" "P.Undergrad" "Outstate" "Room.Board"
[11] "Books" "Personal" "PhD" "Terminal" "S.F.Ratio"
[16] "perc.alumni" "Expend" "Grad.Rate"
View()
. Do they look ok?# Open each dataset in a window.
View(XXX)
View(XXX)
# Convert all character columns to factor
college_train <- college_train %>%
mutate_if(is.character, factor)
college_test <- college_test %>%
mutate_if(is.character, factor)
Your goal in this set of tasks is again to fit models predicting Grad.Rate
, the percentage of attendees who graduate from each college.
trainControl()
, set your training control method to "none"
. Save your object as ctrl_none
.# Set training method to "none" for simple fitting
# Note: This is for demonstration purposes, you would almost
# never do this for a 'real' prediction task!
ctrl_none <- trainControl(method = "XXX")
ctrl_none <- trainControl(method = "none")
train()
fit a regression model called grad_glm
predicting Grad.Rate
as a function of all features. Specifically,…form
argument, use Grad.Rate ~ .
.data
argument, use college_train
in the data argument.method
argument, use method = "glm"
for regression.trControl
argument, use your ctrl_none
object you created before.grad_glm <- train(form = XX ~ .,
data = XX,
method = "XXX",
trControl = ctrl_none)
grad_glm <- train(form = Grad.Rate ~ .,
data = college_train,
method = "glm",
trControl = ctrl_none)
grad_glm
object by looking at grad_glm$finalModel
and using summary()
, what do you find?grad_glm$XXX
summary(XXX)
grad_glm$finalModel
Call: NULL
Coefficients:
(Intercept) PrivateYes Apps Accept Enroll
31.010972 1.701840 0.001926 -0.001754 0.005550
Top10perc Top25perc F.Undergrad P.Undergrad Outstate
-0.049727 0.206252 -0.001069 -0.001294 0.001782
Room.Board Books Personal PhD Terminal
0.000871 -0.000932 -0.001457 0.104743 -0.101789
S.F.Ratio perc.alumni Expend
0.275943 0.219944 -0.000683
Degrees of Freedom: 499 Total (i.e. Null); 482 Residual
Null Deviance: 142000
Residual Deviance: 74600 AIC: 3960
summary(grad_glm)
Call:
NULL
Deviance Residuals:
Min 1Q Median 3Q Max
-38.10 -7.24 -0.58 7.51 47.10
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 31.010972 5.911481 5.25 2.3e-07 ***
PrivateYes 1.701840 2.114677 0.80 0.42135
Apps 0.001926 0.000572 3.37 0.00082 ***
Accept -0.001754 0.001046 -1.68 0.09417 .
Enroll 0.005550 0.002872 1.93 0.05387 .
Top10perc -0.049727 0.086281 -0.58 0.56466
Top25perc 0.206252 0.066972 3.08 0.00219 **
F.Undergrad -0.001069 0.000461 -2.32 0.02068 *
P.Undergrad -0.001294 0.000444 -2.92 0.00369 **
Outstate 0.001782 0.000297 6.01 3.7e-09 ***
Room.Board 0.000871 0.000721 1.21 0.22790
Books -0.000932 0.004089 -0.23 0.81988
Personal -0.001457 0.000998 -1.46 0.14494
PhD 0.104743 0.071027 1.47 0.14095
Terminal -0.101789 0.076321 -1.33 0.18293
S.F.Ratio 0.275943 0.191423 1.44 0.15008
perc.alumni 0.219944 0.061576 3.57 0.00039 ***
Expend -0.000683 0.000202 -3.39 0.00077 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for gaussian family taken to be 155)
Null deviance: 141641 on 499 degrees of freedom
Residual deviance: 74595 on 482 degrees of freedom
AIC: 3960
Number of Fisher Scoring iterations: 2
predict()
save the fitted values of grad_glm
object as glm_fit
.# Save fitted values of regression model
glm_fit <- predict(XXX)
glm_fit <- predict(grad_glm)
glm_fit
object, look at summary statistics with summary(glm_fit)
, and create a histogram with hist()
do they make sense?# Explore regression model fits
XXX
summary(XXX)
hist(XXX)
glm_fit[1:10] # Only printing first 10
1 2 3 4 5 6 7 8 9 10
71.8 56.4 91.8 62.9 69.2 68.5 57.4 52.0 57.4 71.0
summary(glm_fit)
Min. 1st Qu. Median Mean 3rd Qu. Max.
33.0 57.3 64.1 65.6 73.3 102.8
hist(glm_fit)
train()
, fit a decision tree model called grad_rpart
. Specifically,…form
argument, use Grad.Rate ~ .
.data
argument, use college_train
.method
argument, use method = "rpart"
to create decision trees.trControl
argument, use your ctrl_none
object you created before.tuneGrid
argument, use cp = 0.01
to specify the value of the complexity parameter. This is a pretty low value which means your trees will be, relatively, complex, i.e., deep.grad_rpart <- train(form = XX ~ .,
data = XXX,
method = "XX",
trControl = XX,
tuneGrid = expand.grid(cp = XX)) # Set complexity parameter
grad_rpart <- train(form = Grad.Rate ~ .,
data = college_train,
method = "rpart",
trControl = ctrl_none,
tuneGrid = expand.grid(cp = .01)) # Set complexity parameter
grad_rpart
object by looking at grad_rpart$finalModel
and plotting it with plot(as.party(grad_rpart$finalModel))
, what do you find?grad_rpart$finalModel
n= 500
node), split, n, deviance, yval
* denotes terminal node
1) root 500 142000 65.6
2) Outstate< 1.06e+04 292 69000 58.0
4) Top25perc< 47.5 135 34100 53.3
8) Outstate< 8.56e+03 86 20000 48.9
16) Expend>=6.97e+03 26 6430 41.9 *
17) Expend< 6.97e+03 60 11700 52.0
34) Books>=388 53 9310 50.0 *
35) Books< 388 7 639 66.7 *
9) Outstate>=8.56e+03 49 9520 61.1 *
5) Top25perc>=47.5 157 29600 61.9
10) Top10perc< 51.5 147 26100 61.0
20) perc.alumni< 24.5 110 16700 58.9 *
21) perc.alumni>=24.5 37 7500 67.2 *
11) Top10perc>=51.5 10 1570 75.3 *
3) Outstate>=1.06e+04 208 31500 76.4
6) Outstate< 1.68e+04 158 21500 73.3
12) perc.alumni< 22.5 55 8180 68.7 *
13) perc.alumni>=22.5 103 11500 75.8
26) F.Undergrad< 1.42e+03 55 4770 71.2 *
27) F.Undergrad>=1.42e+03 48 4200 81.1 *
7) Outstate>=1.68e+04 50 4040 85.9 *
plot(as.party(grad_rpart$finalModel))
predict()
, save the fitted values of grad_rpart
object as rpart_predfit
.# Save fitted values of decision tree model
rpart_predfit <- predict(XXX)
rpart_predfit <- predict(grad_rpart)
rpart_predfit
object, look at summary statistics with summary(rpart_predfit)
, and create a histogram with hist()
. Do they make sense?# Explore decision tree fits
XXX
summary(XXX)
hist(XXX)
rpart_predfit[1:10] # Only first 10
1 2 3 4 5 6 7 8 9 10
71.2 58.9 85.9 58.9 68.7 81.1 58.9 50.0 50.0 81.1
summary(rpart_predfit)
Min. 1st Qu. Median Mean 3rd Qu. Max.
41.9 58.9 67.2 65.6 71.2 85.9
hist(rpart_predfit)
train()
, fit a random forest model called grad_rf
. Speicifically,…form
argument, use Grad.Rate ~ .
.data
argument, use college_train
.method
argument, use method = "rf"
to fit random forests.trControl
argument, use your ctrl_none
object you created before.mtry
parameter, use mtry
= 2. This is a relatively low value, so the forest will be very diverse.grad_rf <- train(form = XX ~ ., # Predict grad
data = XX,
method = "XX",
trControl = XX,
tuneGrid = expand.grid(mtry = XX)) # Set number of features randomly selected
grad_rf <- train(form = Grad.Rate ~ ., # Predict grad
data = college_train,
method = "rf",
trControl = ctrl_none,
tuneGrid = expand.grid(mtry = 2)) # Set number of features randomly selected
predict()
, save the fitted values of grad_rf
object as rf_fit
.# Save fitted values of random forest model
rf_fit <- predict(XXX)
rf_fit <- predict(grad_rf)
rf_fit
object, look at summary statistics with summary(rf_fit)
, and create a histogram with hist()
. Do they make sense?# Explore random forest fits
XXX
summary(XXX)
hist(XXX)
rf_fit[1:10] # Only first 10
1 2 3 4 5 6 7 8 9 10
68.6 64.1 85.1 55.8 76.1 67.3 58.0 43.6 58.5 72.6
summary(rf_fit)
Min. 1st Qu. Median Mean 3rd Qu. Max.
31.4 56.7 65.7 65.6 74.9 96.8
hist(rf_fit)
college_train$Grad.Rate
) as a vector called criterion_train
.# Save training criterion values
criterion_train <- XXX$XXX
criterion_train <- college_train$Grad.Rate
postResample()
, determine the fitting performance of each of your models separately. Make sure to set your criterion_train
values to the obs
argument, and your true model fits XX_fit
to the pred
argument.# Calculate fitting accuracies of each model
# pred = XX_fit
# obs = criterion_train
# Regression
postResample(pred = XXX, obs = XXX)
# Decision Trees
postResample(pred = XXX, obs = XXX)
# Random Forests
postResample(pred = XXX, obs = XXX)
# Regression
postResample(pred = glm_fit, obs = criterion_train)
RMSE Rsquared MAE
12.214 0.473 9.250
# Decision Trees
postResample(pred = rpart_predfit, obs = criterion_train)
RMSE Rsquared MAE
12.072 0.486 9.536
# Random Forests
postResample(pred = rf_fit, obs = criterion_train)
RMSE Rsquared MAE
5.736 0.928 4.346
(Optional). If you’d like to, try visualizing the fitting results using the plotting code shown in the Examples tab above. Ask for help if you need it!
accuracy <- tibble(criterion_train = criterion_train,
Regression = glm_fit,
DecisionTrees = rpart_predfit,
RandomForest = rf_fit) %>%
gather(model, prediction, -criterion_train) %>%
# Add error measures
mutate(se = prediction - criterion_train,
ae = abs(prediction - criterion_train))
# Calculate summaries
accuracy_agg <- accuracy %>%
group_by(model) %>%
summarise(mae = mean(ae)) # Calculate MAE (mean absolute error)
# Plot A) Scatterplot of truth versus predictions
ggplot(data = accuracy,
aes(x = criterion_train, y = prediction)) +
geom_point(alpha = .5) +
geom_abline(slope = 1, intercept = 0) +
facet_wrap(~ model) +
labs(title = "Predicting college_train$Grad.Rate",
subtitle = "Black line indicates perfect performance")
# Plot B) Violin plot of absolute errors
ggplot(data = accuracy,
aes(x = model, y = ae, fill = model)) +
geom_violin() +
geom_jitter(width = .05, alpha = .2) +
labs(title = "Prediction Absolute Errors",
subtitle = "Numbers indicate means",
x = "Model",
y = "Absolute Error") +
guides(fill = FALSE) +
annotate(geom = "label",
x = accuracy_agg$model,
y = accuracy_agg$mae,
label = round(accuracy_agg$mae, 2))
college_test$Grad.Rate
as a new vector called criterion_test
.# Save criterion values
criterion_test <- XXX$XXX
# Save criterion values
criterion_test <- college_test$Grad.Rate
predict()
, save the predicted values of each model for the test data college_test
as glm_pred
, rpart_pred
and rf_pred
.# Save model predictions for test data
# newdata = college_test
# Regression
glm_pred <- predict(XXX, newdata = XXX)
# Decision Trees
rpart_pred <- predict(XXX, newdata = XXX)
# Random Forests
rf_pred <- predict(XXX, newdata = XXX)
# Save model predictions for test data
# newdata = college_test
# Regression
glm_pred <- predict(grad_glm, newdata = college_test)
# Decision Trees
rpart_pred <- predict(grad_rpart, newdata = college_test)
# Random Forests
rf_pred <- predict(grad_rf, newdata = college_test)
postResample()
, determine the prediction performance of each of your models against the test criterion criterion_test
.# Calculate prediction accuracies of each model
# obs = criterion_test
# pred = XX_pred
# Regression
postResample(pred = XXX, obs = XXX)
# Decision Trees
postResample(pred = XXX, obs = XXX)
# Random Forests
postResample(pred = XXX, obs = XXX)
# Calculate prediction accuracies of each model
# obs = criterion_test
# pred = XX_pred
# Regression
postResample(pred = glm_pred, obs = criterion_test)
RMSE Rsquared MAE
13.727 0.404 9.964
# Decision Trees
postResample(pred = rpart_pred, obs = criterion_test)
RMSE Rsquared MAE
14.741 0.321 11.104
# Random Forests
postResample(pred = rf_pred, obs = criterion_test)
RMSE Rsquared MAE
13.25 0.46 9.75
XXX_test
data) compare to its fitting or training performance (on the XXX_train
data)? Is it worse? Better? The same? What does the change tell you about the models?# The regression goodness of fit stayed the most constant. The random forest one droped considerably.
# The random forest predictions are still the most accurate.
If you had to use one of these three models in the real-world, which one would it be? Why?
If someone came to you and asked “If I use your model in the future to predict the graduation rate of a new college, how accurate do you think it would be?”, what would you say?
In this section, we will work with a different data set. Specifically, we will predict the prices of houses in King County Washington (home of Seattle, which you can thank for this) using the house_train
and house_test
datasets.
Make sure you are still working in your BaselRBootcamp
R project, with the folders 1_Data
and 2_Code
. Make sure that the data file(s) listed in the Datasets
section above are in your 1_Data
folder
Open a new R script. At the top of the script, using comments, write your name and the date. Save it as a new file called Prediction_HousePrices_practical.R
in the 2_Code
folder.
Using library()
load the set of packages for this practical listed in the packages section above.
# Load packages necessary for this script
library(tidyverse)
library(caret)
library(party)
library(partykit)
Datasets
as new objects.# house data
house_train <- read_csv(file = "1_Data/house_train.csv")
house_test <- read_csv(file = "1_Data/house_test.csv")
Take a look at the first few rows of each dataframe by printing them to the console.
Print the numbers of rows and columns of each dataset using the dim()
function.
# Print numbers of rows and columns
dim(XXX)
dim(XXX)
names()
function.# Print the names of each dataframe
names(XXX)
names(XXX)
View()
. Do they look ok?# Open each dataset in a window.
View(XXX)
View(XXX)
# Convert all character columns to factor
house_train <- house_train %>%
mutate_if(is.character, factor)
house_test <- house_test %>%
mutate_if(is.character, factor)
Your goal in the following models is to predict price
, the selling price of homes in King County WA.
trainControl()
, set your training control method to "none"
. Save your object as ctrl_none
.# Set training method to "none" for simple fitting
# Note: This is for demonstration purposes, you would almost
# never do this for a 'real' prediction task!
ctrl_none <- trainControl(method = "XXX")
ctrl_none <- trainControl(method = "none")
train()
, fit a regression model called price_glm
predicting price
using all features in house_train
. Specifically,…form
argument, use price ~ .
.data
argument, use house_train
.method
argument, use method = "glm"
for regression.trControl
argument, use your ctrl_none
object you created before.price_glm <- train(form = XX ~ .,
data = XX,
method = "XXX",
trControl = ctrl_none)
price_glm <- train(form = price ~ .,
data = house_train,
method = "glm",
trControl = ctrl_none)
price_glm
object by looking at price_glm$finalModel
and using summary()
. What do you find?price_glm$XXX
summary(XXX)
price_glm$finalModel
Call: NULL
Coefficients:
(Intercept) bedrooms bathrooms sqft_living sqft_lot
1.07e+05 -4.64e+04 5.35e+04 1.47e+02 2.31e-01
floors waterfront view condition grade
5.03e+03 6.40e+05 5.84e+04 3.03e+04 9.74e+04
sqft_above sqft_basement yr_built yr_renovated zipcode
2.40e+01 NA -2.61e+03 4.31e+00 -5.42e+02
lat long sqft_living15 sqft_lot15
6.14e+05 -2.32e+05 2.71e+01 -2.63e-01
Degrees of Freedom: 4999 Total (i.e. Null); 4982 Residual
Null Deviance: 6.81e+14
Residual Deviance: 2.02e+14 AIC: 136000
summary(price_glm)
Call:
NULL
Deviance Residuals:
Min 1Q Median 3Q Max
-1114590 -98269 -10834 76308 4063119
Coefficients: (1 not defined because of singularities)
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.07e+05 6.13e+06 0.02 0.98603
bedrooms -4.64e+04 4.14e+03 -11.19 < 2e-16 ***
bathrooms 5.35e+04 7.00e+03 7.65 2.4e-14 ***
sqft_living 1.47e+02 9.33e+00 15.73 < 2e-16 ***
sqft_lot 2.31e-01 1.02e-01 2.26 0.02360 *
floors 5.03e+03 7.62e+03 0.66 0.50982
waterfront 6.40e+05 3.53e+04 18.14 < 2e-16 ***
view 5.84e+04 4.52e+03 12.94 < 2e-16 ***
condition 3.03e+04 4.82e+03 6.28 3.6e-10 ***
grade 9.74e+04 4.43e+03 21.99 < 2e-16 ***
sqft_above 2.40e+01 9.25e+00 2.60 0.00935 **
sqft_basement NA NA NA NA
yr_built -2.61e+03 1.54e+02 -16.92 < 2e-16 ***
yr_renovated 4.31e+00 7.99e+00 0.54 0.58986
zipcode -5.42e+02 6.84e+01 -7.92 3.0e-15 ***
lat 6.14e+05 2.25e+04 27.28 < 2e-16 ***
long -2.32e+05 2.71e+04 -8.55 < 2e-16 ***
sqft_living15 2.71e+01 7.12e+00 3.81 0.00014 ***
sqft_lot15 -2.63e-01 1.60e-01 -1.64 0.10008
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for gaussian family taken to be 4.06e+10)
Null deviance: 6.8104e+14 on 4999 degrees of freedom
Residual deviance: 2.0203e+14 on 4982 degrees of freedom
AIC: 136339
Number of Fisher Scoring iterations: 2
predict()
, save the fitted values of price_glm
object as glm_fit
.# Save fitted values of regression model
glm_fit <- predict(XXX)
# Save fitted values of regression model
glm_fit <- predict(price_glm)
glm_fit
object, look at summary statistics with summary(glm_fit)
, and create a histogram with hist()
. Do they make sense?# Explore regression model fits
XXX
summary(XXX)
hist(XXX)
glm_fit[1:10] # Only first 10
1 2 3 4 5 6 7 8 9 10
47648<PHONE_NUMBER>14 95201<PHONE_NUMBER>18<PHONE_NUMBER>35 -2308 654493
summary(glm_fit)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-414135<PHONE_NUMBER>81<PHONE_NUMBER>15 2821881
hist(glm_fit)
train()
, fit a decision tree model called price_rpart
predicting price
using all features in house_train
. Specifically,…form
argument, use price ~ .
.data
argument, use house_train
.method
argument, use method = "rpart"
to create decision trees.trControl
argument, use your ctrl_none
object you created before.tuneGrid
argument, use cp = 0.01
to specify the value of the complexity parameter. This is a pretty low value which means your trees will be, relatively, complex.price_rpart <- train(form = XX ~ .,
data = XXX,
method = "XX",
trControl = XX,
tuneGrid = expand.grid(cp = XX)) # Set complexity parameter
price_rpart <- train(form = price ~ .,
data = house_train,
method = "rpart",
trControl = ctrl_none,
tuneGrid = expand.grid(cp = .01)) # Set complexity parameter
price_rpart
object by looking at price_rpart$finalModel
and plotting it with plot(as.party(price_rpart$finalModel))
. What do you find?price_rpart$finalModel
n= 5000
node), split, n, deviance, yval
* denotes terminal node
1) root 5000 6.81e+14 537000
2) sqft_living< 3.40e+03 4596 2.49e+14 475000
4) lat< 47.5 1805 2.85e+13 324000
8) sqft_living< 1.95e+03 1075 6.91e+12 268000 *
9) sqft_living>=1.95e+03 730 1.31e+13 408000 *
5) lat>=47.5 2791 1.53e+14 572000
10) sqft_living< 2.28e+03 1981 5.01e+13 492000
20) sqft_living< 1.53e+03 947 1.57e+13 425000 *
21) sqft_living>=1.53e+03 1034 2.62e+13 554000 *
11) sqft_living>=2.28e+03 810 5.91e+13 767000
22) grade< 8.5 450 1.64e+13 675000 *
23) grade>=8.5 360 3.39e+13 883000
46) long>=-122 237 8.10e+12 774000 *
47) long< -122 123 1.76e+13 1090000 *
3) sqft_living>=3.40e+03 404 2.12e+14 1250000
6) sqft_living< 6.28e+03 393 1.42e+14 1190000
12) waterfront< 0.5 378 1.10e+14 1140000
24) grade< 10.5 287 5.38e+13 1010000
48) lat< 47.5 65 1.74e+12 626000 *
49) lat>=47.5 222 3.99e+13 1120000
98) long>=-122 119 4.78e+12 922000 *
99) long< -122 103 2.53e+13 1340000 *
25) grade>=10.5 91 3.55e+13 1550000
50) long>=-122 57 6.47e+12 1250000 *
51) long< -122 34 1.44e+13 2070000 *
13) waterfront>=0.5 15 3.52e+12 2550000 *
7) sqft_living>=6.28e+03 11 2.85e+13 3140000 *
plot(as.party(price_rpart$finalModel))
predict()
save the fitted values of price_rpart
object as rpart_predfit
.# Save fitted values of decision tree model
rpart_predfit <- predict(XXX)
rpart_predfit <- predict(price_rpart)
rpart_predfit
object, look at summary statistics with summary(rpart_predfit)
, and create a histogram with hist()
. Do they make sense?# Explore decision tree fits
XXX
summary(XXX)
hist(XXX)
rpart_predfit[1:10] # Only first 10 values
1 2 3 4 5 6 7 8 9 10
267637<PHONE_NUMBER>45<PHONE_NUMBER>58<PHONE_NUMBER>49<PHONE_NUMBER>37 674757
summary(rpart_predfit)
Min. 1st Qu. Median Mean 3rd Qu. Max.
267637<PHONE_NUMBER>48<PHONE_NUMBER>58 3144305
hist(rpart_predfit)
train()
, fit a random forest model called price_rf
predicting price
using all features in house_train
. Specifically,…form
argument, use price ~ .
.data
argument, use house_train
in the data argument.method
argument, use method = "rf"
to fit random forests.trControl
argument, use your ctrl_none
object you created before.mtry
parameter, use mtry
= 2. This is a relatively low value, so the forest will be very diverse.price_rf <- train(form = XX ~ .,
data = XX,
method = "XX",
trControl = XX,
tuneGrid = expand.grid(mtry = XX)) # Set number of features randomly selected
price_rf <- train(form = price ~ .,
data = house_train,
method = "rf",
trControl = ctrl_none,
tuneGrid = expand.grid(mtry = 2)) # Set number of features randomly selected
predict()
save the fitted values of price_rf
object as rf_fit
.# Save fitted values of random forest model
rf_fit <- predict(XXX)
rf_fit <- predict(price_rf)
rf_fit
object, look at summary statistics with summary(rf_fit)
, and create a histogram with hist()
. Do they make sense?# Explore random forest fits
XXX
summary(XXX)
hist(XXX)
rf_fit[1:10] # Only first 10 cases
1 2 3 4 5 6 7 8 9 10
193646<PHONE_NUMBER>68<PHONE_NUMBER>95<PHONE_NUMBER>19<PHONE_NUMBER>02 674959
summary(rf_fit)
Min. 1st Qu. Median Mean 3rd Qu. Max.
149191<PHONE_NUMBER>93<PHONE_NUMBER>00 5081078
hist(rf_fit)
house_train$price
) as a vector called criterion_train
.# Save training criterion values
criterion_train <- XXX$XXX
criterion_train <- house_train$price
postResample()
, determine the fitting performance of each of your models separately. Make sure to set your criterion_train
values to the obs
argument, and your true model fits XX_fit
to the pred
argument.# Calculate fitting accuracies of each model
# pred = XX_fit
# obs = criterion_train
# Regression
postResample(pred = XXX, obs = XXX)
# Decision Trees
postResample(pred = XXX, obs = XXX)
# Random Forests
postResample(pred = XXX, obs = XXX)
# Calculate fitting accuracies of each model
# pred = XX_fit
# obs = criterion_train
# Regression
postResample(pred = glm_fit, obs = criterion_train)
RMSE Rsquared MAE
2.01e+05 7.03e-01 1.25e+05
# Decision Trees
postResample(pred = rpart_predfit, obs = criterion_train)
RMSE Rsquared MAE
1.94e+05 7.23e-01 1.19e+05
# Random Forests
postResample(pred = rf_fit, obs = criterion_train)
RMSE Rsquared MAE
7.86e+04 9.67e-01 4.35e+04
(Optional). If you’d like to, try visualizing the fitting results using the plotting code shown in the Examples tab above. Ask for help if you need it!
# Tidy competition results
accuracy <- tibble(criterion_train = criterion_train,
Regression = glm_fit,
DecisionTrees = rpart_predfit,
RandomForest = rf_fit) %>%
gather(model, prediction, -criterion_train) %>%
# Add error measures
mutate(se = prediction - criterion_train,
ae = abs(prediction - criterion_train))
# Calculate summaries
accuracy_agg <- accuracy %>%
group_by(model) %>%
summarise(mae = mean(ae)) # Calculate MAE (mean absolute error)
# Plot A) Scatterplot of truth versus predictions
ggplot(data = accuracy,
aes(x = criterion_train, y = prediction, col = model)) +
geom_point(alpha = .5) +
geom_abline(slope = 1, intercept = 0) +
labs(title = "Predicting Housing Prices",
subtitle = "Black line indicates perfect performance")
# Plot B) Violin plot of absolute errors
ggplot(data = accuracy,
aes(x = model, y = ae, fill = model)) +
geom_violin() +
geom_jitter(width = .05, alpha = .2) +
labs(title = "Prediction Absolute Errors",
subtitle = "Numbers indicate means",
x = "Model",
y = "Absolute Error") +
guides(fill = FALSE) +
annotate(geom = "label",
x = accuracy_agg$model,
y = accuracy_agg$mae,
label = round(accuracy_agg$mae, 2))
house_test$price
as a new vector called criterion_test
.# Save criterion values
criterion_test <- XXX$XXX
criterion_test <- house_test$price
predict()
, save the predicted values of each model for the test data house_test
as glm_pred
, rpart_pred
and rf_pred
.# Save model predictions for test data
# object: price_XXX
# newdata: house_test
# Regression
glm_pred <- predict(XXX, newdata = XXX)
# Decision Trees
rpart_pred <- predict(XXX, newdata = XXX)
# Random Forests
rf_pred <- predict(XXX, newdata = XXX)
# Regression
glm_pred <- predict(price_glm,
newdata = house_test)
# Decision Trees
rpart_pred <- predict(price_rpart,
newdata = house_test)
# Random Forests
rf_pred <- predict(price_rf,
newdata = house_test)
postResample()
, determine the prediction performance of each of your models against the test criterion criterion_test
.# Calculate prediction accuracies of each model
# obs = criterion_test
# pred = XX_pred
# Regression
postResample(pred = XXX, obs = XXX)
# Decision Trees
postResample(pred = XXX, obs = XXX)
# Random Forests
postResample(pred = XXX, obs = XXX)
# Regression
postResample(pred = glm_pred, obs = criterion_test)
RMSE Rsquared MAE
1.92e+05 7.03e-01 1.26e+05
# Decision Trees
postResample(pred = rpart_pred, obs = criterion_test)
RMSE Rsquared MAE
1.84e+05 7.25e-01 1.22e+05
# Random Forests
postResample(pred = rf_pred, obs = criterion_test)
RMSE Rsquared MAE
1.41e+05 8.58e-01 8.05e+04
How does each model’s prediction or test performance (on the XXX_test
data) compare to its fitting or training performance (on the XXX_train
data)? Is it worse? Better? The same? What does the change tell you about the models?
Which of the three models has the best prediction performance?
If you had to use one of these three models in the real-world, which one would it be? Why?
If someone came to you and asked “If I use your model in the future to predict the price of a new house, how accurate do you think it would be?”, what would you say?
In all of your decision tree models so far, you have been setting the complexity parameter to 0.01. Try setting it to a larger value of 0.2 and see how your decision trees change (by plotting them using plot(as.party(XXX_rpart$finalModel))
). Do they get more or less complicated? How does increasing this value affect fitting and prediction performance? If you are interested in learning more about this parameter, look at the help menu with ?rpart.control
.
In each of your random forest models, you have been setting the mtry
argument to 2. Try setting it to a larger value such as 5 and re-run your models. How does increasing this value affect fitting and prediction performance? If you are interested in learning more about this parameter, look at the help menu with ?randomForest
.
By default, the train()
function uses 500 trees for method = "rf"
. How do the number of trees affect performance? To answer this, try setting the number of trees to 1,000 (see example below) and re-evaluating your model’s training and test performance. What do you find? What if you set the number of trees to just 10?
# Create random forest model with 1000 trees
mod <- train(form = price ~ .l,
data = house_train,
method = "rf",
trControl = ctrl_none,
ntree = 1000, # use 1000 trees! (Instead of the default value of 500)
tuneGrid = expand.grid(mtry = 2))
bedrooms
, bathrooms
, and sqft_living
. Which of your models should I use and how accurate will they be? How would you answer that question? Use your modelling techniques to find out!price_glm <- train(form = price ~ bedrooms + bathrooms + sqft_living,
data = house_train,
method = "glm",
trControl = ctrl_none)
glm_fit <- predict(price_glm)
price_rpart <- train(form = price ~ bedrooms + bathrooms + sqft_living,
data = house_train,
method = "rpart",
trControl = ctrl_none,
tuneGrid = expand.grid(cp = .01))
rpart_predfit <- predict(price_rpart)
price_rf <- train(form = price ~ bedrooms + bathrooms + sqft_living,
data = house_train,
method = "rf",
trControl = ctrl_none,
tuneGrid = expand.grid(mtry = 2))
rf_fit <- predict(price_rf)
# Get goodness of fit indices for training set
# Regression
postResample(pred = glm_fit, obs = criterion_train)
RMSE Rsquared MAE
2.63e+05 4.92e-01 1.72e+05
# Decision Trees
postResample(pred = rpart_predfit, obs = criterion_train)
RMSE Rsquared MAE
2.58e+05 5.13e-01 1.69e+05
# Random Forests
postResample(pred = rf_fit, obs = criterion_train)
RMSE Rsquared MAE
1.76e+05 7.82e-01 1.22e+05
# Get predictions
# Regression
glm_pred <- predict(price_glm,
newdata = house_test)
# Decision Trees
rpart_pred <- predict(price_rpart,
newdata = house_test)
# Random Forests
rf_pred <- predict(price_rf,
newdata = house_test)
# Get goodness of fit indices for test sets
# Regression
postResample(pred = glm_pred, obs = criterion_test)
RMSE Rsquared MAE
2.51e+05 4.91e-01 1.68e+05
# Decision Trees
postResample(pred = rpart_pred, obs = criterion_test)
RMSE Rsquared MAE
2.47e+05 5.06e-01 1.64e+05
# Random Forests
postResample(pred = rf_pred, obs = criterion_test)
RMSE Rsquared MAE
2.52e+05 5.01e-01 1.67e+05
million
in both your house_train
and house_test
datasets (the code below should help you). Then, use your best modelling techniques to make this prediction. How accurate are your models in predicting whether or not a house will sell for over $1,000,000? Don’t forget to use the confusionMatrix()
function instead of postResample()
to evaluate your model’s accuracy!# Add million column to house_train and house_test
# A factor indicating whether or not a house sells for
# over 1,000,0000
house_train <- house_train %>%
mutate(million = factor(price > 1000000))
house_test <- house_test %>%
mutate(million = factor(price > 1000000))
million_glm <- train(form = million ~ . -price,
data = house_train,
method = "glm",
trControl = ctrl_none)
glm_fit <- predict(million_glm)
million_rpart <- train(form = million ~ . -price,
data = house_train,
method = "rpart",
trControl = ctrl_none,
tuneGrid = expand.grid(cp = .01))
rpart_predfit <- predict(million_rpart)
million_rf <- train(form = million ~ . -price,
data = house_train,
method = "rf",
trControl = ctrl_none,
tuneGrid = expand.grid(mtry = 2))
rf_fit <- predict(million_rf)
criterion_train <- house_train$million
# Get goodness of fit indices for training set
# Regression
confusionMatrix(data = glm_fit, # This is the prediction!
reference = criterion_train) # This is the truth!
Confusion Matrix and Statistics
Reference
Prediction FALSE TRUE
FALSE 4618 125
TRUE 54 203
Accuracy : 0.964
95% CI : (0.959, 0.969)
No Information Rate : 0.934
P-Value [Acc > NIR] : < 2e-16
Kappa : 0.675
Mcnemar's Test P-Value : 1.68e-07
Sensitivity : 0.988
Specificity : 0.619
Pos Pred Value : 0.974
Neg Pred Value : 0.790
Prevalence : 0.934
Detection Rate : 0.924
Detection Prevalence : 0.949
Balanced Accuracy : 0.804
'Positive' Class : FALSE
# Decision Trees
confusionMatrix(data = rpart_predfit, # This is the prediction!
reference = criterion_train) # This is the truth!
Confusion Matrix and Statistics
Reference
Prediction FALSE TRUE
FALSE 4609 72
TRUE 63 256
Accuracy : 0.973
95% CI : (0.968, 0.977)
No Information Rate : 0.934
P-Value [Acc > NIR] : <2e-16
Kappa : 0.777
Mcnemar's Test P-Value : 0.491
Sensitivity : 0.987
Specificity : 0.780
Pos Pred Value : 0.985
Neg Pred Value : 0.803
Prevalence : 0.934
Detection Rate : 0.922
Detection Prevalence : 0.936
Balanced Accuracy : 0.884
'Positive' Class : FALSE
# Random Forests
confusionMatrix(data = rf_fit, # This is the prediction!
reference = criterion_train) # This is the truth!
Confusion Matrix and Statistics
Reference
Prediction FALSE TRUE
FALSE 4672 0
TRUE 0 328
Accuracy : 1
95% CI : (0.999, 1)
No Information Rate : 0.934
P-Value [Acc > NIR] : <2e-16
Kappa : 1
Mcnemar's Test P-Value : NA
Sensitivity : 1.000
Specificity : 1.000
Pos Pred Value : 1.000
Neg Pred Value : 1.000
Prevalence : 0.934
Detection Rate : 0.934
Detection Prevalence : 0.934
Balanced Accuracy : 1.000
'Positive' Class : FALSE
# Get predictions
# Regression
glm_pred <- predict(million_glm,
newdata = house_test)
# Decision Trees
rpart_pred <- predict(million_rpart,
newdata = house_test)
# Random Forests
rf_pred <- predict(million_rf,
newdata = house_test)
# Get goodness of fit indices for test sets
# create test criterion
criterion_test <- house_test$million
# Regression
confusionMatrix(data = glm_pred, # This is the prediction!
reference = criterion_test) # This is the truth!
Confusion Matrix and Statistics
Reference
Prediction FALSE TRUE
FALSE 927 23
TRUE 10 40
Accuracy : 0.967
95% CI : (0.954, 0.977)
No Information Rate : 0.937
P-Value [Acc > NIR] : 1.49e-05
Kappa : 0.691
Mcnemar's Test P-Value : 0.0367
Sensitivity : 0.989
Specificity : 0.635
Pos Pred Value : 0.976
Neg Pred Value : 0.800
Prevalence : 0.937
Detection Rate : 0.927
Detection Prevalence : 0.950
Balanced Accuracy : 0.812
'Positive' Class : FALSE
# Decision Trees
confusionMatrix(data = rpart_pred, # This is the prediction!
reference = criterion_test) # This is the truth!
Confusion Matrix and Statistics
Reference
Prediction FALSE TRUE
FALSE 923 14
TRUE 14 49
Accuracy : 0.972
95% CI : (0.96, 0.981)
No Information Rate : 0.937
P-Value [Acc > NIR] : 3.14e-07
Kappa : 0.763
Mcnemar's Test P-Value : 1
Sensitivity : 0.985
Specificity : 0.778
Pos Pred Value : 0.985
Neg Pred Value : 0.778
Prevalence : 0.937
Detection Rate : 0.923
Detection Prevalence : 0.937
Balanced Accuracy : 0.881
'Positive' Class : FALSE
# Random Forests
confusionMatrix(data = rf_pred, # This is the prediction!
reference = criterion_test) # This is the truth!
Confusion Matrix and Statistics
Reference
Prediction FALSE TRUE
FALSE 936 27
TRUE 1 36
Accuracy : 0.972
95% CI : (0.96, 0.981)
No Information Rate : 0.937
P-Value [Acc > NIR] : 3.14e-07
Kappa : 0.706
Mcnemar's Test P-Value : 2.31e-06
Sensitivity : 0.999
Specificity : 0.571
Pos Pred Value : 0.972
Neg Pred Value : 0.973
Prevalence : 0.937
Detection Rate : 0.936
Detection Prevalence : 0.963
Balanced Accuracy : 0.785
'Positive' Class : FALSE
# Fitting and evaluating regression, decision trees, and random forests
# Step 0: Load packages-----------
library(tidyverse) # Load tidyverse for dplyr and tidyr
library(caret) # For ML mastery
library(partykit) # For decision trees
library(party) # For decision trees
# Step 1: Load and Clean, and Explore Training data ----------------------
# training data
data_train <- read_csv("1_Data/mpg_train.csv")
# test data
data_test <- read_csv("1_Data/mpg_test.csv")
# Convert all characters to factor
# Some ML models require factors
data_train <- data_train %>%
mutate_if(is.character, factor)
data_test <- data_test %>%
mutate_if(is.character, factor)
# Explore training data
data_train # Print the dataset
View(data_train) # Open in a new spreadsheet-like window
dim(data_train) # Print dimensions
names(data_train) # Print the names
# Define criterion_train
# We'll use this later to evaluate model accuracy
criterion_train <- data_train$hwy
# Step 2: Define training control parameters -------------
# In this case, I will set method = "none" to fit to
# the entire dataset without any fancy methods
ctrl_none <- trainControl(method = "none")
# Step 3: Train model: -----------------------------
# Criterion: hwy
# Features: year, cyl, displ
# Regression --------------------------
hwy_glm <- train(form = hwy ~ year + cyl + displ,
data = data_train,
method = "glm",
trControl = ctrl_none)
# Look at summary information
hwy_glm$finalModel
summary(hwy_glm)
# Save fitted values
glm_fit <- predict(hwy_glm)
# Calculate fitting accuracies
postResample(pred = glm_fit,
obs = criterion_train)
# Decision Trees ----------------
hwy_rpart <- train(form = hwy ~ year + cyl + displ,
data = data_train,
method = "rpart",
trControl = ctrl_none,
tuneGrid = expand.grid(cp = .01)) # Set complexity parameter
# Look at summary information
hwy_rpart$finalModel
plot(as.party(hwy_rpart$finalModel)) # Visualise your trees
# Save fitted values
rpart_predfit <- predict(hwy_rpart)
# Calculate fitting accuracies
postResample(pred = rpart_predfit, obs = criterion_train)
# Random Forests -------------------------
hwy_rf <- train(form = hwy ~ year + cyl + displ,
data = data_train,
method = "rf",
trControl = ctrl_none,
tuneGrid = expand.grid(mtry = 2)) # Set number of features randomly selected
# Look at summary information
hwy_rf$finalModel
# Save fitted values
rf_fit <- predict(hwy_rf)
# Calculate fitting accuracies
postResample(pred = rf_fit, obs = criterion_train)
# Visualise Accuracy -------------------------
# Tidy competition results
accuracy <- tibble(criterion_train = criterion_train,
Regression = glm_fit,
DecisionTrees = rpart_predfit,
RandomForest = rf_fit) %>%
gather(model, prediction, -criterion_train) %>%
# Add error measures
mutate(se = prediction - criterion_train,
ae = abs(prediction - criterion_train))
# Calculate summaries
accuracy_agg <- accuracy %>%
group_by(model) %>%
summarise(mae = mean(ae)) # Calculate MAE (mean absolute error)
# Plot A) Scatterplot of truth versus predictions
ggplot(data = accuracy,
aes(x = criterion_train, y = prediction, col = model)) +
geom_point(alpha = .5) +
geom_abline(slope = 1, intercept = 0) +
labs(title = "Predicting mpg$hwy",
subtitle = "Black line indicates perfect performance")
# Plot B) Violin plot of absolute errors
ggplot(data = accuracy,
aes(x = model, y = ae, fill = model)) +
geom_violin() +
geom_jitter(width = .05, alpha = .2) +
labs(title = "Fitting Absolute Errors",
subtitle = "Numbers indicate means",
x = "Model",
y = "Absolute Error") +
guides(fill = FALSE) +
annotate(geom = "label",
x = accuracy_agg$model,
y = accuracy_agg$mae,
label = round(accuracy_agg$mae, 2))
# Step 5: Access prediction ------------------------------
# Define criterion_train
criterion_test <- data_test$hwy
# Save predicted values
glm_pred <- predict(hwy_glm, newdata = data_test)
rpart_pred <- predict(hwy_rpart, newdata = data_test)
rf_pred <- predict(hwy_rf, newdata = data_test)
# Calculate fitting accuracies
postResample(pred = glm_pred, obs = criterion_test)
postResample(pred = rpart_pred, obs = criterion_test)
postResample(pred = rf_pred, obs = criterion_test)
# Visualise Accuracy -------------------------
# Tidy competition results
accuracy <- tibble(criterion_test = criterion_test,
Regression = glm_pred,
DecisionTrees = rpart_pred,
RandomForest = rf_pred) %>%
gather(model, prediction, -criterion_test) %>%
# Add error measures
mutate(se = prediction - criterion_test,
ae = abs(prediction - criterion_test))
# Calculate summaries
accuracy_agg <- accuracy %>%
group_by(model) %>%
summarise(mae = mean(ae)) # Calculate MAE (mean absolute error)
# Plot A) Scatterplot of truth versus predictions
ggplot(data = accuracy,
aes(x = criterion_test, y = prediction, col = model)) +
geom_point(alpha = .5) +
geom_abline(slope = 1, intercept = 0) +
labs(title = "Predicting mpg$hwy",
subtitle = "Black line indicates perfect performance")
# Plot B) Violin plot of absolute errors
ggplot(data = accuracy,
aes(x = model, y = ae, fill = model)) +
geom_violin() +
geom_jitter(width = .05, alpha = .2) +
labs(title = "Prediction Absolute Errors",
subtitle = "Numbers indicate means",
x = "Model",
y = "Absolute Error") +
guides(fill = FALSE) +
annotate(geom = "label",
x = accuracy_agg$model,
y = accuracy_agg$mae,
label = round(accuracy_agg$mae, 2))
| File | Rows | Columns |
|---|---|---|
| college_train.csv | 500 | 18 |
| college_test.csv | 277 | 18 |
| house_train.csv | 5000 | 21 |
| house_test.csv | 1000 | 21 |
The college_train
and college_test
data are taken from the College
dataset in the ISLR
package. They contain statistics for a large number of US Colleges from the 1995 issue of US News and World Report.
The house_train
and house_test
data come from https://www.kaggle.com/harlfoxem/housesalesprediction
college_train
and college_test
| Name | Description |
|---|---|
Private |
A factor with levels No and Yes indicating private or public university. |
Apps |
Number of applications received. |
Accept |
Number of applications accepted. |
Enroll |
Number of new students enrolled. |
Top10perc |
Pct. new students from top 10% of H.S. class. |
Top25perc |
Pct. new students from top 25% of H.S. class. |
F.Undergrad |
Number of fulltime undergraduates. |
P.Undergrad |
Number of parttime undergraduates. |
Outstate |
Out-of-state tuition. |
Room.Board |
Room and board costs. |
Books |
Estimated book costs. |
Personal |
Estimated personal spending. |
PhD |
Pct. of faculty with Ph.D.’s. |
Terminal |
Pct. of faculty with terminal degree. |
S.F.Ratio |
Student/faculty ratio. |
perc.alumni |
Pct. alumni who donate. |
Expend |
Instructional expenditure per student. |
Grad.Rate |
Graduation rate. |
house_train
and house_test
| Name | Description |
|---|---|
price |
Price of the house in $. |
bedrooms |
Number of bedrooms. |
bathrooms |
Number of bathrooms. |
sqft_living |
Square footage of the home. |
sqft_lot |
Square footage of the lot. |
floors |
Total floors (levels) in house. |
waterfront |
House which has a view to a waterfront. |
view |
Has been viewed. |
condition |
How good the condition is (Overall). |
grade |
Overall grade given to the housing unit, based on King County grading system. |
sqft_above |
Square footage of house apart from basement. |
sqft_basement |
Square footage of the basement. |
yr_built |
Built Year. |
yr_renovated |
Year when house was renovated. |
zipcode |
Zip code. |
lat |
Latitude coordinate. |
long |
Longitude coordinate. |
sqft_living15 |
Living room area in 2015 (implies some renovations). This might or might not have affected the lotsize area. |
sqft_lot15 |
lot-size area in 2015 (implies some renovations). |
| Package | Installation |
|---|---|
tidyverse |
install.packages("tidyverse") |
caret |
install.packages("caret") |
partykit |
install.packages("partykit") |
party |
install.packages("party") |
| Function | Package | Description |
|---|---|---|
trainControl() |
caret |
Define modelling control parameters |
train() |
caret |
Train a model |
predict(object, newdata) |
stats |
Predict the criterion values of newdata based on object |
postResample() |
caret |
Calculate aggregate model performance in regression tasks |
confusionMatrix() |
caret |
Calculate aggregate model performance in classification tasks |


Connect
Previous/restart track
Play/pause track
Next track
Browse playlists
#
Title
Artist
Length
Provider
Source
Yes
No


WITNESS LIST Finance Committee January 29, 2003 - 9:00A Organizational Hearing ON: D'Souza, Anita General Counsel (Legislative Budget Board), Austin, TX Hamilton, Billy Deputy Comptroller (Comptroller of Public Accounts), Austin, TX Keel, John Director (Legislative Budget Board), Austin, TX Lebas, James Revenue Estimator (Comptroller of Public Accounts), Austin, TX Parks, Ursula Manager of Public Education (Legislative Budget Board), Austin, TX


CFileDirectory - This class gives you the capability to retrieve the names of files (complete full-path filenames) in a directory. You can fill in a CStringArray with the filenames or execute a callback function. You can process the files in a single directory or recurse through the subdirectories.
CServiceApplication - This class encapsulates all of the logic behind installing, removing and running from a command line (to make debugging easier) needed by a service application.
CVolume - This class let's you eject removable media (CD-ROM's JAZ drives, tapes, etc). It also let's you lock drives.
wfc_move_file_at_reboot - This function let's you schedule a file to be moved at the next reboot. This is how system DLL's are upgraded.
SetSize()
then you were probably
affected.
 I use a binary search but forgot to
compute where to go for the next comparison. The result was
and endless loop. ROOKIE MISTAKE!
CExtensibleMarkupLanguageElement -
Many thanks go to Johann Plank
<EMAIL_ADDRESS>for finding where I forgot to add code in CountChildren().
What kind of moron forgets to write code?? Geez...
CExtensibleMarkupLanguageElement -
Stephane Drouin
<EMAIL_ADDRESS>found an off-by-one error in parsing
CExtensibleMarkupLanguageElement -
Thanks to Mats Johnsson
<EMAIL_ADDRESS>adding a human readable error message capability. Now when Parse()
returns FALSE, you can get a string containing something fitting to show
to a human explaining what weny wrong.
CMicrosoftTape -
Yehuda Hahn
<EMAIL_ADDRESS>(ygh@cfsnet.com),
is on the Beta list for Visual C++ 6.0. It has a UINT64
data type now which collided with the UINT64 data type
defined in the
CNetwork - Fixed a bug, thanks to
Dirk Tolson
(dirk.tolson@srs.gov),
where I would go into an endless loop when there were
more user accounts than could be read in a single read.
This affected the Enumerate() method.
CSerialFile - Thanks go to
Fabio Angelini
<EMAIL_ADDRESS>or
CSystemTime - Added a method, thanks to
Dean Grimm
(dean@cortron.com),
that takes a TIMESTAMP_STRUCT data type from
Map2Def - I've added the removal of exporting
static strings. Map2Def converts MAP files to DEF files.
HTML - Robin Abecasis
<EMAIL_ADDRESS>Found a spot where I didn't finish renaming a variable. It
compiles now.
wfc_append_text_to_edit_control - C Function
that appends text to an edit control.
wfc_delete_oldest_file - C function
that deletes the oldest file in a directory. It will return TRUE if a file
was deleted or FALSE it a file was not deleted.
This is useful in a file cache management system.
wfc_get_directory_usage_percentage - C function
that returns an integer percentage of the space used on a volume by a directory.
This is useful in a file cache management system.
CreateFile
()
parameter values for CSerialFile. I
added them to CDummyFile instead.
<![CDATA[
sections in
the m_ParseCDATASection() method.
samth.h
header file. The
old UINT64 is now called SIXTY_FOUR_BIT_UNSIGNED_INTEGER.
Let's see Microsoft collide with that name!
CreateFile
().
sqltypes.h
in the Copy() method (and copy constructor). While doing this,
I uncovered a bug when copying from a CTime object. The day of week was
not getting set properly. It is fixed now.
Stuff I forgot to Document
Etcetera
Someone suggested that I separate WFC from its samples. I did this.
If you want the samples for the library, click
here
or here
Release 35 Notes


In pictures: Cian O'Sullivan and wife Danielle announce baby news 23 Nov 2019, 12:41 by Kayla Walsh (Image: Instagram/bex31188)


{{extend 'layout.html'}} {{block head}}
Fill in your details if you are looking for Software Engineering Jobs or Internships! We will contact you if we find a relevant job opportunity for you!


Summernote WYSIWYG Editor
Do you see any Teletubbies in here? Do you see a slender plastic tag clipped to my shirt with my name printed on it? Do you see a little Asian child with a blank expression on his face sitting outside on a mechanical helicopter that shakes when you put quarters in it? No? Well, that's what you see at a toy store. And you must think you're in a toy store, because you're here shopping for an infant named Jeb.
Do you see a little Asian child with a blank expression on his face sitting outside on a mechanical helicopter that shakes when you put quarters in it? No? Well, that's what you see at a toy store. And you must think you're in a toy store, because you're here shopping for an infant named Jeb.
Well, that's what you see at a toy store. And you must think you're in a toy store, because you're here shopping for an infant named Jeb. Do you see a slender plastic tag clipped to my shirt with my name printed on it? Do you see a little Asian child with a blank expression on his face sitting outside on a mechanical helicopter that shakes when you put quarters in it?


Left click to make a custom mass
Right click to make an orbiting mass
Show grid
Right click custom mass
Mass multiplier
Zoom camera
Calculation speed
WIPE SPACETIME
CYCLE FOCUS
GRAVITATIONAL
LAB
David Pham, Noah Ouna, and John Han


TargetP 1.1 predicts the subcellular location of eukaryotic proteins. The location assignment is based on the predicted presence of any of the N-terminal presequences: chloroplast transit peptide (cTP), mitochondrial targeting peptide (mTP) or secretory pathway signal peptide (SP). TargetP uses ChloroP and SignalP to predict cleavage sites for cTP and SP, respectively. For the sequences predicted to contain an N-terminal presequence a potential cleavage site is also predicted.
get_targetp(data, ...) # S3 method for character get_targetp( data, org_type = c("non_plant", "plant"), cutoffs = c("winner_takes_all", "spec95", "spec90", "custom"), tcut = NULL, pcut = NULL, scut = NULL, ocut = NULL, splitter = 1000, attempts = 2, progress = FALSE, ... ) # S3 method for data.frame get_targetp(data, sequence, id, ...) # S3 method for list get_targetp(data, ...) # S3 method for default get_targetp(data = NULL, sequence, id, ...) # S3 method for AAStringSet get_targetp(data, ...)
| data | A data frame with protein amino acid sequences as strings in one column and corresponding id's in another. Alternatively a path to a .fasta file with protein sequences. Alternatively a list with elements of class |
|---|---|
| ... | currently no additional arguments are accepted apart the ones documented bellow. |
| org_type | One of c("non_plant", "plant"), defaults to "plant". Which models should be used for prediction. |
| cutoffs | One of c("winner_takes_all", "spec95", "spec90", "custom"), defaults to "winner_takes_all". If "winner_takes_all" no cutoffs are specified, if "spec95" or "spec90" are selected, predefined set of cutoffs that yielded >0.95 or >0.9 specificity on the TargetP test sets. If "custom" specified user defined cutoffs should be specified in "tcut", "pcut", "scut", ocut". |
| tcut | A numeric value, with range 0 - 1, defaults to 0 (cutoff = "winner_takes_all"). mTP user specified cutoff. |
| pcut | A numeric value, with range 0 - 1, defaults to 0 (cutoff = "winner_takes_all"). cTP user specified cutoff. |
| scut | A numeric value, with range 0 - 1, defaults to 0 (cutoff = "winner_takes_all"). SP user specified cutoff. |
| ocut | A numeric value, with range 0 - 1, defaults to 0 (cutoff = "winner_takes_all"). User specified cutoff for "other" (not with mTP, cTP, SP). |
| splitter | An integer indicating the number of sequences to be in each .fasta file that is to be sent to the server. Defaults to 1000. Change only in case of a server side error. Accepted values are in range of 1 to 2000. |
| attempts | Integer, number of attempts if server unresponsive, at default set to 2. |
| progress | Boolean, whether to show the progress bar, at default set to FALSE. |
| sequence | A vector of strings representing protein amino acid sequences, or the appropriate column name if a data.frame is supplied to data argument. If .fasta file path, or list with elements of class "SeqFastaAA" provided to data, this should be left blank. |
| id | A vector of strings representing protein identifiers, or the appropriate column name if a data.frame is supplied to data argument. If .fasta file path, or list with elements of class "SeqFastaAA" provided to data, this should be left blank. |
https://services.healthtech.dtu.dk/service.php?TargetP-1.1
A data frame with columns:
Character, sequence name truncated to 20 characters
Integer, length of analyzed sequence
Numeric, final NN sequence score to contain a chloroplast transit peptide (cTP). ChloroP is used to predict cleavage sites for cTP
Numeric, final NN sequence score to contain a mitochondrial targeting peptide (mTP).
Numeric, final NN sequence score to contain a secretory pathway signal peptide (SP). SignalP is used to predict cleavage sites for SP
Numeric, final NN sequence score of a sequence not to contain mTP, SP or cTP
Character, one of C (chloroplast), M (mitochondrion), S (secretory pathway), - (any other location) or * ("don't know"; indicates that cutoff restrictions were set and the winning network output score was below the requested cutoff for that category.)
Integer, predicted presequence length
Integer, reliability class, from 1 to 5, where 1 indicates the strongest prediction. RC is a measure of the size of the difference ('diff') between the highest (winning) and the second highest output scores. There are 5 reliability classes, defined as follows: 1 : diff > 0.800, 2 : 0.800 > diff > 0.600, 3 : 0.600 > diff > 0.400, 4 : 0.400 > diff > 0.200, 5 : 0.200 > diff. Thus, the lower the value of RC the safer the prediction.
Logical, did TargetP predict the presence of a signal peptide
This function creates temporary files in the working directory. Protein ids should be shorter then 20 characters due to server side truncation.
Emanuelsson O, Nielsen H, Brunak S,von Heijne G. (2000) Predicting subcellular localization of proteins based on their N-terminal amino acid sequence. J. Mol. Biol.300: 1005-1016
library(ragp) data(at_nsp) targetp_pred <- get_targetp(at_nsp[1:20,], sequence, Transcript.id) targetp_pred#> Name Len cTP mTP SP other Loc RC TPlen is.targetp #> 1 ATCG00660.1 117 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 2 AT2G43600.1 273 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 3 AT2G28410.1 115 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 4 AT2G22960.1 184 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 5 AT2G19580.1 270 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 6 AT2G19690.2 148 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 7 AT2G19690.1 147 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 8 AT2G33130.1 103 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 9 AT2G05520.1 145 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 10 AT2G05520.2 138 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 11 AT2G05520.3 125 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 12 AT2G05520.4 124 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 13 AT2G05520.6 117 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 14 AT2G05520.5 111 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 15 AT2G04031.1 151 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 16 AT2G43620.1 283 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 17 AT2G37390.1 259 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 18 AT2G37390.2 258 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 19 AT2G35250.1 342 0.000 0.000 0.000 0.000 ? 5 - FALSE #> 20 AT2G38390.1 349 0.000 0.000 0.000 0.000 ? 5 - FALSE


 Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
{% blocktrans with confirmation.email_address.email as email %}Please confirm that {{ email }} is an e-mail address for user {{ user_display }}.{% endblocktrans %}
{% else %} {% url 'account_email' as email_url %}{% blocktrans %}This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request.{% endblocktrans %}
{% endif %}


The Backyahd Ultra is a virtual race put together by some of the Road Hazahds, a ragtag group of people united in our love of running. We've been missing in-person races during the COVID era and have been looking for ways to keep ourselves running, and decided to have our own mini version of an event like Big Dog's Backyard Ultra. (Though we're not quite crazy enough to put in 4.167 miles every hour)
Every hour starting at 8:00 AM on Saturday, April 10th, we'll all run a loop of 1-3 miles and repeat until we just can't do it anymore. The person who keeps going the longest doesn't get anything apart from bragging rights, but the real prize is the fun we'll have along the way.
We're using this event to raise money for The Trevor Project, a nonprofit organization dedicated to suicide prevention in LGBTQ youth. We hope you'll follow along with us in this effort and donate using our team page if you have the means!


Nea Marmaras - not to be confused with Nea Marmara on Evia, is on the western shore of the Sinthonia peninsula. Porto Carras lies about 5NM south of the town.
Moor where directed or to one of the pontoons. Resonable shelter.
Last updated August 2009.


The base module in the Java Sound API's messaging system is the
MidiDevice
interface. MidiDevices
include sequencers (which record, play, load, and edit sequences of time-stamped MIDI messages), synthesizers (which generate sounds when triggered by MIDI messages), and MIDI input and output ports, through which data comes from and goes to external MIDI devices. The functionality typically required of MIDI ports is described by the base MidiDevice
interface. The
Sequencer
and
Synthesizer
interfaces extend the MidiDevice
interface to describe the additional functionality characteristic of MIDI sequencers and synthesizers, respectively. Concrete classes that function as sequencers or synthesizers should implement these interfaces.
A MidiDevice
typically owns one or more ancillary objects that implement the Receiver
or Transmitter
interfaces. These interfaces represent the "plugs" or "portals" that connect devices together, permitting data to flow into and out of them. By connecting a Transmitter
of one MidiDevice
to a Receiver
of another, you can create a network of modules in which data flows from one to another.
The MidiDevice
interface includes methods for determining how many transmitter and receiver objects the device can support concurrently, and other methods for accessing those objects. A MIDI output port normally has at least one Receiver
through which the outgoing messages may be received; similarly, a synthesizer normally responds to messages sent to its Receiver
or Receivers
. A MIDI input port normally has at least one Transmitter
, which propagates the incoming messages. A full-featured sequencer supports both Receivers
, which receive messages during recording, and Transmitters
, which send messages during playback.
The Transmitter
interface includes methods for setting and querying the receivers to which the transmitter sends its MidiMessages
. Setting the receiver establishes the connection between the two. The Receiver
interface contains a method that sends a MidiMessage
to the receiver. Typically, this method is invoked by a Transmitter
. Both the Transmitter
and Receiver
interfaces include a close
method that frees up a previously connected transmitter or receiver, making it available for a different connection.
We'll now examine how to use transmitters and receivers. Before getting to the typical case of connecting two devices (such as hooking a sequencer to a synthesizer), we'll examine the simpler case where you send a MIDI message directly from your application program to a device. Studying this simple scenario should make it easier to understand how the Java Sound API arranges for sending MIDI messages between two devices.
Let's say you want to create a MIDI message from scratch and then send it to some receiver. You can create a new, blank ShortMessage
and then fill it with MIDI data using the following ShortMessage
method:
void setMessage(int command, int channel, int data1, int data2)
Receiver
object, using this Receiver
method:
void send(MidiMessage message, long timeStamp)
An application program can obtain a receiver for a MidiDevice
by invoking the device's getReceiver
method. If the device can't provide a receiver to the program (typically because all the device's receivers are already in use), a MidiUnavailableException
is thrown. Otherwise, the receiver returned from this method is available for immediate use by the program. When the program has finished using the receiver, it should call the receiver's close
method. If the program attempts to invoke methods on a receiver after calling close
, an IllegalStateException
may be thrown.
As a concrete simple example of sending a message without using a transmitter, let's send a Note On message to the default receiver, which is typically associated with a device such as the MIDI output port or a synthesizer. We do this by creating a suitable ShortMessage
and passing it as an argument to Receiver's
send
method:
ShortMessage myMsg = new ShortMessage(); // Start playing the note Middle C (60), // moderately loud (velocity = 93). myMsg.setMessage(ShortMessage.NOTE_ON, 0, 60, 93); long timeStamp = -1; Receiver rcvr = MidiSystem.getReceiver(); rcvr.send(myMsg, timeStamp);
ShortMessage
, namely, NOTE_ON
, for use as the MIDI message's status byte. The other parts of the MIDI message are given explicit numeric values as arguments to the setMessage
method. The zero indicates that the note is to be played using MIDI channel number 1; the 60 indicates the note Middle C; and the 93 is an arbitrary key-down velocity value, which typically indicates that the synthesizer that eventually plays the note should play it somewhat loudly. (The MIDI specification leaves the exact interpretation of velocity up to the synthesizer's implementation of its current instrument.) This MIDI message is then sent to the receiver with a time stamp of -1. We now need to examine exactly what the time stamp parameter means, which is the subject of the next section.
As you already know, the MIDI specification has different parts. One part describes MIDI "wire" protocol (messages sent between devices in real time), and another part describes Standard MIDI Files (messages stored as events in "sequences"). In the latter part of the specification, each event stored in a standard MIDI file is tagged with a timing value that indicates when that event should be played. By contrast, messages in MIDI wire protocol are always supposed to be processed immediately, as soon as they're received by a device, so they have no accompanying timing values.
The Java Sound API adds an additional twist. It comes
as no surprise that timing values are present in the MidiEvent
objects that are stored in sequences (as might be read from a MIDI file), just
as in the Standard MIDI Files specification. But in the Java Sound API, even
the messages sent between devicesin other words, the messages that correspond
to MIDI wire protocolcan be given timing values, known as time stamps.
It is these time stamps that concern us here.
The time stamp that can optionally accompany messages sent between devices in the Java Sound API is quite different from the timing values in a standard MIDI file. The timing values in a MIDI file are often based on musical concepts such as beats and tempo, and each event's timing measures the time elapsed since the previous event. In contrast, the time stamp on a message sent to a device's Receiver
object always measures absolute time in microseconds. Specifically, it measures the number of microseconds elapsed since the device that owns the receiver was opened.
This kind of time stamp is designed to help compensate for latencies introduced by the operating system or by the application program. It's important to realize that these time stamps are used for minor adjustments to timing, not to implement complex queues that can schedule events at completely arbitrary times (as MidiEvent
timing values do).
The time stamp on a message sent to a device (through a Receiver
) can provide precise timing information to the device. The device might use this information when it processes the message. For example, it might adjust the event's timing by a few milliseconds to match the information in the time stamp. On the other hand, not all devices support time stamps, so the device might completely ignore the message's time stamp.
Even if a device supports time stamps, it might not schedule the event for exactly the time that you requested. You can't expect to send a message whose time stamp is very far in the future and have the device handle it as you intended, and you certainly can't expect a device to correctly schedule a message whose time stamp is in the past! It's up to the device to decide how to handle time stamps that are too far off in the future or are in the past. The sender doesn't know what the device considers to be too far off, or whether the device had any problem with the time stamp. This ignorance mimics the behavior of external MIDI hardware devices, which send messages without ever knowing whether they were received correctly. (MIDI wire protocol is unidirectional.)
Some devices send time-stamped messages (via a Transmitter
). For example, the messages sent by a MIDI input port might be stamped with the time the incoming message arrived at the port. On some systems, the event-handling mechanisms cause a certain amount of timing precision to be lost during subsequent processing of the message. The message's time stamp allows the original timing information to be preserved.
To learn whether a device supports time stamps, invoke the following method of MidiDevice
:
long getMicrosecondPosition()
MidiDevice's
notion of time always places time zero at the time the device was opened.
Now, with all that explanation of time stamps as a background, let's return to the send
method of Receiver
:
void send(MidiMessage message, long timeStamp)
timeStamp
argument is expressed in microseconds, according to the receiving device's notion of time. If the device doesn't support time stamps, it simply ignores the timeStamp
argument. You aren't required to time-stamp the messages you send to a receiver. You can use -1 for the timeStamp
argument to indicate that you don't care about adjusting the exact timing; you're just leaving it up to the receiving device to process the message as soon as it can. However, it's not advisable to send -1 with some messages and explicit time stamps with other messages sent to the same receiver. Doing so is likely to cause irregularities in the resultant timing.
We've seen how you can send a MIDI message directly to a receiver, without using a transmitter. Now let's look at the more common case, where you aren't creating MIDI messages from scratch, but are simply connecting devices together so that one of them can send MIDI messages to the other.
The specific case we'll take as our first example is connecting a sequencer to a synthesizer. After this connection is made, starting the sequencer running will cause the synthesizer to generate audio from the events in the sequencer's current sequence. For now, we'll ignore the process of loading a sequence from a MIDI file into the sequencer. Also, we won't go into the mechanism of playing the sequence. Loading and playing sequences is discussed in detail in Playing, Recording, and Editing MIDI Sequences. Loading instruments into the synthesizer is discussed in Synthesizing Sound. For now, all we're interested in is how to make the connection between the sequencer and the synthesizer. This will serve as an illustration of the more general process of connecting one device's transmitter to another device's receiver.
For simplicity, we'll use the default sequencer and the default synthesizer.
Sequencer seq; Transmitter seqTrans; Synthesizer synth; Receiver synthRcvr; try { seq = MidiSystem.getSequencer(); seqTrans = seq.getTransmitter(); synth = MidiSystem.getSynthesizer(); synthRcvr = synth.getReceiver(); seqTrans.setReceiver(synthRcvr); } catch (MidiUnavailableException e) { // handle or throw exception }
Sequencer
interface and the Synthesizer
interface. In that case, it probably wouldn't be necessary to make the explicit connection that we did in the code above. For portability, though, it's safer not to assume such a configuration. If desired, you can test for this condition, of course:
if (seq instanceof Synthesizer)
although the explicit connection above should work in any case.
The previous code example illustrated a one-to-one connection between a transmitter and a receiver. But, what if you need to send the same MIDI message to multiple receivers? For example, suppose you want to capture MIDI data from an external device to drive the internal synthesizer while simultaneously recording the data to a sequence. This form of connection, sometimes referred to as "fan out" or as a "splitter," is straightforward. The following statements show how to create a fan-out connection, through which the MIDI messages arriving at the MIDI input port are sent to both a Synthesizer
object and a Sequencer
object. We assume you've already obtained and opened the three devices: the input port, sequencer, and synthesizer. (To obtain the input port, you'll need to iterate over all the items returned by MidiSystem.getMidiDeviceInfo
.)
Synthesizer synth; Sequencer seq; MidiDevice inputPort; // [obtain and open the three devices...] Transmitter inPortTrans1, inPortTrans2; Receiver synthRcvr; Receiver seqRcvr; try { inPortTrans1 = inputPort.getTransmitter(); synthRcvr = synth.getReceiver(); inPortTrans1.setReceiver(synthRcvr); inPortTrans2 = inputPort.getTransmitter(); seqRcvr = seq.getReceiver(); inPortTrans2.setReceiver(seqRcvr); } catch (MidiUnavailableException e) { // handle or throw exception }
MidiDevice.getTransmitter
method, assigning the results to inPortTrans1
and inPortTrans2
. As mentioned earlier, a device can own multiple transmitters and receivers. Each time MidiDevice.getTransmitter()
is invoked for a given device, another transmitter is returned, until no more are available, at which time an exception will be thrown.
To learn how many transmitters and receivers a device supports, you can use the following MidiDevice
method:
int getMaxTransmitters()
int getMaxReceivers
()
A transmitter can transmit MIDI messages to only one receiver at a time. (Every time you call Transmitter's setReceiver
method, the existing Receiver
, if any, is replaced by the newly specified one. You can tell whether the transmitter currently has a receiver by invoking Transmitter.getReceiver
.) However, if a device has multiple transmitters, it can send data to more than one device at a time, by connecting each transmitter to a different receiver, as we saw in the case of the input port above.
Similarly, a device can use its multiple receivers to receive from more than one device at a time. The multiple-receiver code that's required is straightforward, being directly analogous to the multiple-transmitter code above. It's also possible for a single receiver to receive messages from more than one transmitter at a time.
Once you're done with a connection, you can free up its resources by invoking the close
method for each transmitter and receiver that you've obtained. The Transmitter
and Receiver
interfaces each have a close
method. Note that invoking Transmitter.setReceiver
doesn't close the transmitter's current receiver. The receiver is left open, and it can still receive messages from any other transmitter that's connected to it.
If you're also done with the devices, you can similarly make them available to other application programs by invoking MidiDevice.close()
. Closing a device automatically closes all its transmitters and receivers.


PALMETTO
A Film Review by James Berardinelli
RATING: ** OUT OF ****
United States/Germany, 1998 U.S. Release Date: 2/20/98 (limited) Running Length: 1:50 MPAA Classification: R (Violence, profanity, sex) Theatrical Aspect Ratio: 2.35:1
Cast: Woody Harrelson, Gina Gershon, Elisabeth Shue, Chloe Sevigny, Tom Wright, Michael Rapaport, Rolfe Hoppe Director: Volker Schlondorff Producers: Matthias Wendlandt, Al Corley Screenplay: E. Max Frye based on JUST ANOTHER SUCKER by James Hadley Chase Cinematography: Thomas Kloss U.S. Distributor: Columbia Pictures
From time-to-time, as I'm sitting in a theater watching a movie, I experience a profound sense of deja vu. In the case of something like PALMETTO, which isn't a sequel or a remake, and is based on a novel I know I haven't read, it can be a disturbing feeling. Upon reflection, however, the reason is obvious: there's not a moment of originality in the entire motion picture. Everything -- characters, situations, settings -- is culled from other sources. This is the kind of movie I've seen on a cable movie channel late at night, although it usually shows a lot more skin and features names like Andrew Stevens and Shannon Tweed rather than Woody Harrelson and Elisabeth Shue.
The intent of director Volker Schlondorff (THE HANDMAID'S TALE) is to create the newest entry to the burgeoning genre of '90s film noir. However, despite an impressive cast and a talented cinematographer who knows how to play with light and shadow, he's stuck with a B-movie script. Instead of making PALMETTO tongue-in-cheek, which is the tone it cries out for, he plays everything straight. The result is a stale and tedious mystery that surprises viewers with some of its twists only because they're so contrived that they make little sense.
Harry Barber (Harrelson) is a hard-luck case. After falling victim to a well-orchestrated frame-up and spending the last two years in prison for something he didn't do, he is suddenly sprung when the testimony of an ex-cop reveals the truth. Even as he reunites with his loving, supportive girlfriend, Nina (Gina Gershon), Harry continues to harbor bitterness against the officials of the town of Palmetto, Florida. Then, seemingly out of the blue, he meets the rich and sexy Rhea Malroux (Elisabeth Shue) at a local bar. After sizing Harry up over a drink, she offers him a job. "The money's good but, in exchange, there's an element of risk," she informs him. After contemplating the dried-up employment market, Harry agrees to consider her offer. The work sounds simple. Rhea and her step-daughter, Odette (Chloe Sevigny), are planning to con Rhea's rich, dying husband out of $500,000 by staging Odette's (fake) kidnapping. The money would then be split 50/50 between the two women, with Harry getting $50,000. It sounds like a reasonably straightforward scheme, but, in movies like this, nothing ever goes as planned.
The acting is one of the reasons PALMETTO doesn't work. Woody Harrelson, Gina Gershon, and Michael Rapaport (as Rhea's bodyguard) give grim, humorless performances. They put on their serious faces and treat the script like it's Dostoevsky. Elisabeth Shue, on the other hand, goes 180 degrees in the opposite direction, vamping it up and generally acting silly. The only one to turn in a good job is Chloe Sevigny (KIDS, TREES LOUNGE), who manages the perfect mix of ripe sexuality and innocence. In fact, Sevigny's Odette is the lone character who's even a little interesting, and her screen time is sadly restricted. Meanwhile, as the straight-shooting Assistant D.A., actor Tom Wright stands around for most of the picture looking constipated.
It's hard to feel much sympathy for Harry Barber. First of all, he insists on bothering us with a useless voice-over narrative.   He's courting disaster, and, of course, it's more than happy to welcome him in. For a plot like this one to work, audiences not only have to buy into Harry's lack of intelligence, but must become party to it. In that way, the screenplay is insulting. There are a lot of twists and turns in PALMETTO, but most are so hard-to-swallow that they don't have any impact. And, when the truth finally emerges, it isn't likely to cause more than a momentary shrug. Ultimately, that shrug is about all this movie deserves. If you really have a burning desire to see it, wait for its appearance on Cinemax some night at 2 AM, between ILLICIT DREAMS and BODY CHEMISTRY IV.
Copyright 1998 James Berardinelli
- James Berardinelli e-mail<EMAIL_ADDRESS>Now with more than 1300 reviews... The ReelViews web site: http://movie-reviews.colossus.net/
"No art passes our conscience in the way film does, and goes directly to our feelings, deep down into the dark rooms of our souls"
- Ingmar Bergman
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


RSC Swimming Club has a number of squads.
These are defined as defined as detailed below:
Tadpoles - This is a beginner group for the under 10 year olds learning to swim
Frogs - This is for the more mature learner wanting take up swimming
Minnows - This is the first of the skill development for those who can swim
Piranahs - This is for this is for the more swimmer competting at district level
Sharks - For the serious competitor
Synchro - This is our Synchorised Swimming Squad led by one of the top coaches in the country
Master - This squad is for swimmers aged over 25
There is a place for any swimmer at any level to join a squad and take part
Michael Gunning is firmly back in the swim of things after a Spanish summer of love that he'll never forget.
After the disappointment of missing out on the Commonwealth Games, the Jamaica international swimmer agreed to try a completely different challenge - navigating the untested waters of reality TV. He can currently be seen on 'The Bi Life', filmed in Barcelona a few months back and showing on E! Hosted by the much-loved drag queen and Celebrity Big Brother winner Courtney Act, it's the UK's first dating show for people who are bisexual.
Speaking to Sky Sports in support of Stonewall's Rainbow Laces campaign, the 24-year-old is now fully readjusted to the routine of training as he turns his focus towards the World Aquatics Championships in Gwangju, Korea, next July.
He's totally at ease talking about his sexuality, but accepts that particular element of his confidence has only come to him recently.
"Within my sports environment, it was my biggest worry," he says. In all elite sports, including swimming, LGBT+ representation in general is still so limited, with openly gay and bi male athletes among the least visible. Now, with his Catalan adventures attracting thousands of TV viewers, Gunning is loving being out in life, and is shrugging off those past concerns.
RSC Swimming Club Master   £££


Grow your blog without the guessing at what really works
Be Notified
Sign up to know when the course is ready
Do you know exactly how to use Google Analytics to make important decisions about your blog?
If you're like most bloggers, you know how to do the basics in Google Analytics. You can check your pageviews, see which posts are the most popular, and maybe you even know how to see where your traffic is coming from.
You do your best to create good content, get it posted on different social media sites, increase your rankings on Google, and get featured by other websites, but it's hard to know what is working the best, or where to spend your time for the biggest returns.
The big problem with Google Analytics...
...is that so few people really understand how to use it! And that's a shame because there is so much amazing information in Google Analytics that can really change the way you work on your blog.
Let's stop for a moment and think about how your blog would be different if you could know:
- Exactly how people are coming to your blog
- What people are doing once they get to your blog
- Which pages had huge opportunities to drive more traffic from Google search
All of this data and more is right there in Google Analytics, waiting for you! All you have to do is know a few key things about how to properly use the tool.
Here's What You Get When You Purchase The Course
Who Is This Course For?
NEW BLOGGERS
Grok integrate thinker-maker-doer piverate entrepreneur sticky note iterate waterfall is so 2000 and late 360 campaign cortado quantitative vs. qualitative.
EXPERIENCED BLOGGERS
Grok integrate thinker-maker-doer piverate entrepreneur sticky note iterate waterfall is so 2000 and late 360 campaign cortado quantitative vs. qualitative.


SIGN IN
Delivery
Take away
Dine-in
Our Location
Previous
Next
RECOMMENDED FOR YOU
Ultimate Savings Bucket
₹ 599
buy
Family Fest
₹ 749
buy
Big 8
₹ 549
buy
Let's Celebrate!
×
First name
Looks good!
Last name
Looks good!
Username
@
Please choose a username.
City
Please provide a valid city.
State
Choose...
...
Please select a valid state.
Zip
Please provide a valid zip.
Agree to terms and conditions
You must agree before submitting.
Place Order
×
Success!
Meal is being cooked shortly.
KFC we got
×


Plain link
continuous text
Link embedded in text with prepended icon
continuous text
Link with appended icon
Disabled link with prepended icon


Log-out has been made. Subsystem did not supply any URL via returnUrl parameters, so we cannot redirect you back. Sorry.


Times x Curious
Times x Bold
Miles x Uber Awesome
Which celebrities are you made of?
What does your mood say about your event preference?


{% extends "base.html" %} {% block loginhook %} Click here to login as a different user {% endblock %} {% block body %}
| {{ guild.ctx.discord.name }} | Macros | {% if guild.is_admin %} Admin {% endif %} |
You are not a member of any guilds known to this bot
{% endif %} {% endblock %}


THERMO-FLUID DYNAMICS OF SEPARATED
TWO-PHASE FLOW
A THESIS Presented to The Faculty of the Division of Graduate Studies and Research By
Gunol Kocamustafaogullari
In Partial Fulfillment of the Requirements for the Degree Doctor of Philosophy in the
School of Mechanical Engineering
Georgia Institute of Technology December, 1971
Reproduced with permission of the copyright owner. Further reproduction prohibited without permission.


SSL - Windows
This article shows how to use SSL connections with the message bus on Windows.
Certificates
In order to use an SSL connection you will need some certificates. See the article here for creating SSL certificates on windows,
Configuration
To use SSL we need a custom configuration. We can see the standard
configuration [here][configuration.md].
Create the file appsettings-ssl.ssl
with the following contents.
{
"distributor": {
"address": "<IP_ADDRESS>",
"port": 9001,
"authentication": {
"assemblyPath": null,
"assemblyName": "JetBlack.MessageBus.Common",
"typeName": "JetBlack.MessageBus.Common.Security.Authentication.NullAuthenticator",
"args": []
},
"heartbeatInterval": "00:00:00",
"sslConfig": {
"isEnabled": true,
"storeLocation": "LocalMachine",
"subjectName": "windowsvm.jetblack.net"
},
"allow": [
"All"
],
"deny": [
"None"
],
"isAuthorizationRequired": false
},
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
},
"Console": {
"IncludeScopes": true
}
}
}
The SSL configuration is under the sslConfig
tag.
The
[storeLocation](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.storelocation)
refers to the location of the certificates in the trust store. This will either
be LocalMachine
or CurrentUser
depending on how you've set it up.
The subjectName
is the CN
in the certificate.
Now create a distributor-ssl.bat
file to run the application. The
following assumes the distributor was unpacked to C:\Distributor
.
JetBlack.MessageBus.Distributor %~dp0%\appsettings-ssl.json
The settings file is provided as the first argument and must be an absolute path.
When the distributor is started we get the following message.
2021-08-01 09:05:15.2016415 info: JetBlack.MessageBus.Distributor.Acceptor[0]
Listening on <IP_ADDRESS>:9001 with SSL enabled with NULL authentication
Clients
To Enable SSL on the clients the isSslEnabled
flag must be set to
true
when the client is created.
var client = Client.Create("localhost", 9001, isSslEnabled: true);


Template fields
Butler uses the Handlebars library for templating work.
Handlebars offers a lot of useful features (nested template fields, evaluation context, template comments) and it’s recommended that you browse through at least the language features section of their getting started guide to get a feeling for what’s possible.
Warning
Not all alert destinations (MQTT, outgoing webhooks etc) support template fields.
Please see the Concepts and Getting started sections for more information about which alert types support templates.
If a template field is used for an alert type where that field is not supported, the field will simply be blank. No errors will occur.
The following template fields are available in alert messages.
Note that some fields are usually (always?) empty, for example the script log for stopped messages.
This is simply how Sense works - the template fields just forward the information retrieved from the Sense APIs.
| Failed reload |
Stopped reload |
Field name | Description |
|---|---|---|---|
| ✅ | ✅ | hostName | Server on which a reload or other event took place. |
| ✅ | ✅ | user | Reload failures: User ID for use doing the reload. Typically sa_scheduler .Reload stopped: User ID of user stopping the reload. |
| ✅ | ✅ | taskId | ID of reload task that failed/was stopped. |
| ✅ | ✅ | appName | Name of Sense whose reload failed/was stopped. |
| ✅ | ✅ | appId | ID of Sense app whose reload failed/was stopped. |
| ✅ | ✅ | appOwnerName | Name of app owner (if this is available in the metadata provided by the Sense server) |
| ✅ | ✅ | appOwnerUserDirectory | App owner user’s user directory (if this is available in the metadata provided by the Sense server) |
| ✅ | ✅ | appOwnerUserId | App owner user’s user id (if this is available in the metadata provided by the Sense server) |
| ✅ | ✅ | appOwnerEmail | App owner email (if this is available in the metadata provided by the Sense server) |
| ✅ | ✅ | logTimeStamp | Timestamp as recorded in the Sense logs |
| ✅ | ✅ | logLevel | Log level of the Sense log file entry causing the alert |
| ✅ | ✅ | logMessage | Log message from the Sense log files |
| ✅ | ✅ | executingNodeName | Name of the server where the reload took place |
| ✅ | ✅ | executionDuration.hours | executionDuration is a JSON object. Duration of reload (hours part) |
| ✅ | ✅ | executionDuration.minutes | Duration of reload (minutes part) |
| ✅ | ✅ | executionDuration.seconds | Duration of reload (seconds part) |
| ✅ | ✅ | executionStartTime.startTimeUTC | JSON object. UTC timestamp for reload start |
| ✅ | ✅ | executionStartTime.startTimeLocal1 | Reload start timestamp, format 1 |
| ✅ | ✅ | executionStartTime.startTimeLocal2 | Reload start timestamp, format 2 |
| ✅ | ✅ | executionStartTime.startTimeLocal3 | Reload start timestamp, format 3 |
| ✅ | ✅ | executionStartTime.startTimeLocal4 | Reload start timestamp, format 4 |
| ✅ | ✅ | executionStartTime.startTimeLocal5 | Reload start timestamp, format 5 |
| ✅ | ✅ | executionStopTime.stopTimeUTC | JSON object. UTC timestamp for reload end |
| ✅ | ✅ | executionStopTime.stopTimeLocal1 | Reload end timestamp, format 1 |
| ✅ | ✅ | executionStopTime.stopTimeLocal2 | Reload end timestamp, format 2 |
| ✅ | ✅ | executionStopTime.stopTimeLocal3 | Reload end timestamp, format 3 |
| ✅ | ✅ | executionStopTime.stopTimeLocal4 | Reload end timestamp, format 4 |
| ✅ | ✅ | executionStopTime.stopTimeLocal5 | Reload end timestamp, format 5 |
| ✅ | ✅ | executionStatusNum | Final reload task status code |
| ✅ | ✅ | executionStatusText | Final reload task status message |
| ✅ | ✅ | executionDetails[].timestampUTC | executionDetails is an array of status updates for the reload task, similar to the one found in the QMC’s task view. UTC timestamp of the task status |
| ✅ | ✅ | executionDetails[].timestampLocal1 | Task status timestamp, format 1 |
| ✅ | ✅ | executionDetails[].timestampLocal2 | Task status timestamp, format 2 |
| ✅ | ✅ | executionDetails[].timestampLocal3 | Task status timestamp, format 3 |
| ✅ | ✅ | executionDetails[].timestampLocal4 | Task status timestamp, format 4 |
| ✅ | ✅ | executionDetails[].timestampLocal5 | Task status timestamp, format 5 |
| ✅ | ✅ | executionDetails[].detailsType | Task status timestamp, format 1 |
| ✅ | ✅ | executionDetails[].message | Task status message |
| ✅ | ✅ | scriptLogHeadCount | Number of lines extracted from the start of the script log |
| ✅ | ✅ | scriptLogHead | The first x lines from the reload’s script log |
| ✅ | ✅ | scriptLogTail | Number of lines extracted from the end of the script log |
| ✅ | ✅ | scriptLogTailCount | The first y lines from the reload’s script log |
| ✅ | ✅ | qliksSenseQMC | Links to QMC, as defined in main config file |
| ✅ | ✅ | qliksSenseHub | Links to Hub, as defined in main config file |