<jupyter_start><jupyter_text>*Not much improvement in this case.* *When is removing outliers justified? What if we had seen a significant decrease in the squared error? Is Sepal.Length ~ Sepal.Width a smart thing to model, or are there hidden variables? (i.e., mean amount of daily sunshine, precipitation levels, exposure to wind, ...).*<jupyter_code># now for some classification
flowers <- subset(iris, Species == "setosa" | Species == "virginica")
# equivalently flowers <- iris[iris$Species == "setosa" | iris$Species == "virginica",]
# R has different "OR" operators depending on whether we are doing operations 
# on matrix like objects or atomic objects. Be sure to use a single bar | here.
# Here our data has two classes, hence we are performing "binary classification".
plot(flowers[,1:4], pch=sapply(flowers$Species, substr, 1, 1))
flowers$Species <- as.factor(flowers$Species)<jupyter_output><empty_output><jupyter_text>*In this case, this is unnecessary because class(flowers$Species) == factor already, but in general we need to make our categorical response variables factors for classification.*<jupyter_code>flowers <- droplevels(flowers) # need to drop "versicolor" from Species levels since it's empty
dotchart(flowers$Petal.Length, pch=sapply(flowers$Species, substr, 1, 1))<jupyter_output><empty_output><jupyter_text>*Notice how the data is linearly separable. (In dot charts the y-axis is meaningless).*<jupyter_code># 1-d case
library(MASS)
oneLinearClass <- lda(Species ~ Petal.Length, flowers)<jupyter_output><empty_output><jupyter_text>*lda stands for Linear Discriminant Analysis. How it works is not important for now.Just know that it attempts to draw a dot/line/plane/hyperplane separating our two classes.*<jupyter_code>onePredictions <- predict(oneLinearClass, flowers)
onePredictionResults <- table(onePredictions$class == flowers$Species) / length(flowers$Species)
onePredictionResults<jupyter_output><empty_output><jupyter_text>*Wow! 0 error! Who would've thunk.*<jupyter_code># 2-d case
plot(Sepal.Length ~ Sepal.Width, flowers, pch=sapply(flowers$Species, substr, 1, 1))
twoLinearClass <- lda(Species ~ Sepal.Length + Sepal.Width, flowers)
twoPredictions <- predict(twoLinearClass, flowers)
twoPredictionResults <- table(twoPredictions$class == flowers$Species) / length(flowers$Species)
twoPredictionResults<jupyter_output><empty_output><jupyter_text>*Here LDA is not perfect, although our data is (barely) linearly separable. This is because we abused the LDA assumption that the two classes have the same covariance matrix. (More on this in later lectures).* *Now let's try the entire iris dataset, including Species == "versicolor" in n-dimensions. n = 4 here, since we have 4 features (we don't include our "Species" label).*<jupyter_code>labelMapper <- function(s) { # this is just to help us plot the data in the next line
    if (s == "setosa") return(1)
    if (s == "versicolor") return(2)
    if (s == "virginica") return(3)
}
plot(iris[,1:4], pch=sapply(iris$Species, labelMapper))
nLinearClass <- lda(Species ~ ., iris) # Species ~ . := Species as explained by "everything"
nPredictions <- predict(nLinearClass, iris)
nPredictionResults <- table(nPredictions$class == iris$Species) / length(iris$Species)
nPredictionResults<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10956416464891042, 'fraction_numerical': 0.005447941888619854, 'mean_word_length': 6.24780701754386, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '424899', 'license': 'MIT', 'n_tokens_mistral': 1071, 'n_tokens_neox': 1006, 'n_words': 334, 'path': '2015-2016.Meetings/01.hello-machine/Hello, Machine!.ipynb', 'repo_name': 'NViday/machine_learning_workshop_Winter17', 'size': '3304'}