- Running Logistic Regression models on the Stock Market dataset
summary(Smarket)
Year Lag1 Lag2 Lag3 Lag4 Lag5
Min. :2001 Min. :-4.922000 Min. :-4.922000 Min. :-4.922000 Min. :-4.922000 Min. :-4.92200
1st Qu.:2002 1st Qu.:-0.639500 1st Qu.:-0.639500 1st Qu.:-0.640000 1st Qu.:-0.640000 1st Qu.:-0.64000
Median :2003 Median : 0.039000 Median : 0.039000 Median : 0.038500 Median : 0.038500 Median : 0.03850
Mean :2003 Mean : 0.003834 Mean : 0.003919 Mean : 0.001716 Mean : 0.001636 Mean : 0.00561
3rd Qu.:2004 3rd Qu.: 0.596750 3rd Qu.: 0.596750 3rd Qu.: 0.596750 3rd Qu.: 0.596750 3rd Qu.: 0.59700
Max. :2005 Max. : 5.733000 Max. : 5.733000 Max. : 5.733000 Max. : 5.733000 Max. : 5.73300
Volume Today Direction
Min. :0.3561 Min. :-4.922000 Down:602
1st Qu.:1.2574 1st Qu.:-0.639500 Up :648
Median :1.4229 Median : 0.038500
Mean :1.4783 Mean : 0.003138
3rd Qu.:1.6417 3rd Qu.: 0.596750
Max. :3.1525 Max. : 5.733000
![](data:image/png;base64,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)
- Running a logistic regression model
glm_probs[1:5]
1 2 3 4 5
0.5070841 0.4814679 0.4811388 0.5152224 0.5107812
Checking our performance
#Getting our classification performance
mean(glm_pred==Smarket$Direction)
[1] 0.5216
- Splitting into train-test
Checking performance on test data
mean(glm_pred_test == Smarket_Direction_2005)
[1] 0.4801587
- Classification using only lag1 and lag2 terms
glm_fit_train2 <- glm(Direction ~ Lag1 + Lag2, data = Smarket, family = binomial, subset = train)
glm_probs_test2 <- predict(glm_fit_train2, newdata = Smarket[!train,], type = "response")
glm_pred_test2 <- ifelse(glm_probs_test2>0.5, "Up", "Down")
Checking performance of updated classification codes
table(glm_pred_test2, Smarket_Direction_2005)
Smarket_Direction_2005
glm_pred_test2 Down Up
Down 35 35
Up 76 106
mean(glm_pred_test2 == Smarket_Direction_2005)
[1] 0.5595238
- Running Linear Discriminant Analysis on the Stock Market dataset
rm(ls=list())
Error in rm(ls = list()) : ... must contain names or character strings
Fitting a LDA model
![](data:image/png;base64,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)
Checking what the performance is on test data (year = 2005)
mean(lda_pred$class==Smarket_2005$Direction)
[1] 0.5595238
- K-Nearest Neighbours classification
mean(knn_pred == Smarket$Direction[!train])
[1] 0.5
K-Nearest Neighbors
library(class) ?knn attach(Smarket) Xlag=cbind(Lag1,Lag2) train=Year<2005 knn.pred=knn(Xlag[train,],Xlag[!train,],Direction[train],k=1) table(knn.pred,Direction[!train]) mean(knn.pred==Direction[!train])
LS0tDQp0aXRsZTogIklTTFIgLSBMZWFybmluZyBDbGFzc2lmaWNhdGlvbiB1c2luZyB0aGUgU3RvY2sgTWFya2V0IERhdGEiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoxKSBSdW5uaW5nIExvZ2lzdGljIFJlZ3Jlc3Npb24gbW9kZWxzIG9uIHRoZSBTdG9jayBNYXJrZXQgZGF0YXNldA0KDQpgYGB7cn0NCmxpYnJhcnkoSVNMUikNCm5hbWVzKFNtYXJrZXQpDQpzdW1tYXJ5KFNtYXJrZXQpDQpgYGANCg0KYGBge3J9DQpwYWlycyhTbWFya2V0LCBjb2wgPSBTbWFya2V0JERpcmVjdGlvbikNCmBgYA0KDQotIFJ1bm5pbmcgYSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsDQoNCmBgYHtyfQ0KZ2xtX2ZpdCA8LSBnbG0oRGlyZWN0aW9uIH4gTGFnMSArIExhZzIgKyBMYWczICsgTGFnNCArIExhZzUgKyBWb2x1bWUsIGRhdGEgPSBTbWFya2V0LCBmYW1pbHkgPSBiaW5vbWlhbCkNCnN1bW1hcnkoZ2xtX2ZpdCkNCmdsbV9wcm9icyA8LSBwcmVkaWN0KGdsbV9maXQsIHR5cGUgPSAicmVzcG9uc2UiKQ0KZ2xtX3Byb2JzWzE6NV0NCmdsbV9wcmVkIDwtIGlmZWxzZShnbG1fcHJvYnM+MC41LCJVcCIsIkRvd24iKQ0KYGBgDQoNCg0KQ2hlY2tpbmcgb3VyIHBlcmZvcm1hbmNlDQoNCmBgYHtyfQ0KI0dldHRpbmcgdGhlIGNsYXNzaWZpY2F0aW9uIGNvbmZ1c2lvbiBtYXRyaXgNCnRhYmxlKGdsbV9wcmVkLCBTbWFya2V0JERpcmVjdGlvbikNCg0KI0dldHRpbmcgb3VyIGNsYXNzaWZpY2F0aW9uIHBlcmZvcm1hbmNlDQojQ29ycmVjdCBjbGFzc2lmaWNhdGlvbnMvVG90YWwgbnVtYmVyIG9mIG9ic2VydmF0aW9ucw0KbWVhbihnbG1fcHJlZD09U21hcmtldCREaXJlY3Rpb24pDQpgYGANCg0KLSBTcGxpdHRpbmcgaW50byB0cmFpbi10ZXN0DQpgYGB7cn0NCnRyYWluIDwtIFNtYXJrZXQkWWVhciA8IDIwMDUNCmdsbV9maXRfdHJhaW4gPC0gZ2xtKERpcmVjdGlvbiB+IExhZzEgKyBMYWcyICsgTGFnMyArIExhZzQgKyBMYWc1ICsgVm9sdW1lLCBkYXRhID0gU21hcmtldCwgZmFtaWx5ID0gYmlub21pYWwsIHN1YnNldCA9IHRyYWluKQ0KZ2xtX3Byb2JzX3Rlc3QgPC0gcHJlZGljdChnbG1fZml0X3RyYWluLCBuZXdkYXRhID0gU21hcmtldFshdHJhaW4sXSwgdHlwZSA9ICJyZXNwb25zZSIpDQpnbG1fcHJlZF90ZXN0IDwtIGlmZWxzZShnbG1fcHJvYnNfdGVzdD4wLjUsICJVcCIsICJEb3duIikNCmBgYA0KDQpDaGVja2luZyBwZXJmb3JtYW5jZSBvbiB0ZXN0IGRhdGENCmBgYHtyfQ0KU21hcmtldF9EaXJlY3Rpb25fMjAwNSA8LSBTbWFya2V0JERpcmVjdGlvblshdHJhaW5dDQp0YWJsZShnbG1fcHJlZF90ZXN0LCBTbWFya2V0X0RpcmVjdGlvbl8yMDA1KQ0KDQojQ29ycmVjdCBjbGFzc2lmaWNhdGlvbiBhY2N1cmFjeSBmb3IgdGVzdA0KbWVhbihnbG1fcHJlZF90ZXN0ID09IFNtYXJrZXRfRGlyZWN0aW9uXzIwMDUpDQpgYGANCg0KLSBDbGFzc2lmaWNhdGlvbiB1c2luZyBvbmx5IGxhZzEgYW5kIGxhZzIgdGVybXMNCmBgYHtyfQ0KZ2xtX2ZpdF90cmFpbjIgPC0gZ2xtKERpcmVjdGlvbiB+IExhZzEgKyBMYWcyLCBkYXRhID0gU21hcmtldCwgZmFtaWx5ID0gYmlub21pYWwsIHN1YnNldCA9IHRyYWluKQ0KZ2xtX3Byb2JzX3Rlc3QyIDwtIHByZWRpY3QoZ2xtX2ZpdF90cmFpbjIsIG5ld2RhdGEgPSBTbWFya2V0WyF0cmFpbixdLCB0eXBlID0gInJlc3BvbnNlIikNCmdsbV9wcmVkX3Rlc3QyIDwtIGlmZWxzZShnbG1fcHJvYnNfdGVzdDI+MC41LCAiVXAiLCAiRG93biIpDQpgYGANCg0KQ2hlY2tpbmcgcGVyZm9ybWFuY2Ugb2YgdXBkYXRlZCBjbGFzc2lmaWNhdGlvbiBjb2Rlcw0KYGBge3J9DQp0YWJsZShnbG1fcHJlZF90ZXN0MiwgU21hcmtldF9EaXJlY3Rpb25fMjAwNSkNCm1lYW4oZ2xtX3ByZWRfdGVzdDIgPT0gU21hcmtldF9EaXJlY3Rpb25fMjAwNSkNCg0KYGBgDQoNCg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCjIpIFJ1bm5pbmcgTGluZWFyIERpc2NyaW1pbmFudCBBbmFseXNpcyBvbiB0aGUgU3RvY2sgTWFya2V0IGRhdGFzZXQNCg0KYGBge3J9DQpsaWJyYXJ5KE1BU1MpDQpybShsaXN0ID0gbHMoKSkNCmBgYA0KDQoNCkZpdHRpbmcgYSBMREEgbW9kZWwNCmBgYHtyfQ0KbGRhX2ZpdCA8LSBsZGEoRGlyZWN0aW9uIH4gTGFnMSArIExhZzIsIGRhdGEgPSBTbWFya2V0LCBzdWJzZXQgPSBZZWFyIDwgMjAwNSkNCmxkYV9maXQNCnBsb3QobGRhX2ZpdCkNCmBgYA0KDQoNCkNoZWNraW5nIHdoYXQgdGhlIHBlcmZvcm1hbmNlIGlzIG9uIHRlc3QgZGF0YSAoeWVhciA9IDIwMDUpDQoNCmBgYHtyfQ0KU21hcmtldF8yMDA1IDwtIHN1YnNldChTbWFya2V0LCBZZWFyID09IDIwMDUpDQpsZGFfcHJlZCA9IHByZWRpY3QobGRhX2ZpdCwgU21hcmtldF8yMDA1KQ0KZGF0YS5mcmFtZShsZGFfcHJlZClbMTo1LF0NCg0KdGFibGUobGRhX3ByZWQkY2xhc3MsU21hcmtldF8yMDA1JERpcmVjdGlvbikNCm1lYW4obGRhX3ByZWQkY2xhc3M9PVNtYXJrZXRfMjAwNSREaXJlY3Rpb24pDQoNCmBgYA0KDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQozKSBLLU5lYXJlc3QgTmVpZ2hib3VycyBjbGFzc2lmaWNhdGlvbg0KDQpgYGB7cn0NCmxpYnJhcnkoY2xhc3MpDQo/a25uDQoNClhsYWcgPC0gY2JpbmQoU21hcmtldCRMYWcxLCBTbWFya2V0JExhZzIpDQp0cmFpbiA8LSBTbWFya2V0JFllYXIgPCAyMDA1DQoNCmtubl9wcmVkIDwtIGtubihYbGFnW3RyYWluLF0sIFhsYWdbIXRyYWluLF0sIFNtYXJrZXQkRGlyZWN0aW9uW3RyYWluXSwgaz0xKQ0KDQp0YWJsZShrbm5fcHJlZCwgU21hcmtldCREaXJlY3Rpb25bIXRyYWluXSkNCm1lYW4oa25uX3ByZWQgPT0gU21hcmtldCREaXJlY3Rpb25bIXRyYWluXSkNCg0KYGBgDQoNCg0KDQojIyBLLU5lYXJlc3QgTmVpZ2hib3JzDQpsaWJyYXJ5KGNsYXNzKQ0KP2tubg0KYXR0YWNoKFNtYXJrZXQpDQpYbGFnPWNiaW5kKExhZzEsTGFnMikNCnRyYWluPVllYXI8MjAwNQ0Ka25uLnByZWQ9a25uKFhsYWdbdHJhaW4sXSxYbGFnWyF0cmFpbixdLERpcmVjdGlvblt0cmFpbl0saz0xKQ0KdGFibGUoa25uLnByZWQsRGlyZWN0aW9uWyF0cmFpbl0pDQptZWFuKGtubi5wcmVkPT1EaXJlY3Rpb25bIXRyYWluXSkNCg==