library(tidyverse)
library(MASS)
library(magrittr)
set.seed(41)
Generate data
theta <- rnorm(1) # angle
A <- matrix(rnorm(100 * 2), 100, 2) # rotation vector
A <- A %*% diag(c(3, 1)) %*% matrix(c(cos(theta), sin(theta), -sin(theta), cos(theta)), 2, 2)
Sigma <- var(A)
Sigma
[,1] [,2]
[1,] 5.238469 4.280309
[2,] 4.280309 5.060916
Bias vectors
ma <- c(2, 0)
mb <- c(5, 2)
Generate two multivariate gaussians
a <- mvrnorm(n = 1000, ma, Sigma)
b <- mvrnorm(n = 1000, mb, Sigma)
Print covariance matrices
a %>% as.data.frame %>% cov
V1 V2
V1 5.193249 4.379969
V2 4.379969 5.332480
b %>% as.data.frame %>% cov
V1 V2
V1 5.195009 4.128270
V2 4.128270 4.779776
LDA
Compute difference vector and LDA vector
mdiff <- mb - ma
mdiff_lda <- solve(Sigma, mdiff)
Display
Create data frame for the vectors
mdiff_df <- data_frame(x2 = mdiff[1], y2 = mdiff[2], x1 = 0, y1 = 0)
mdiff_lda_df <- data_frame(x2 = mdiff_lda[1], y2 = mdiff_lda[2], x1 = 0, y1 = 0)
df <-
bind_rows(
as.data.frame(a) %>% mutate(class = "a"),
as.data.frame(b) %>% mutate(class = "b")
)
Plot data
ggplot() +
geom_point(data = df, aes(V1, V2, color = class), alpha = .5) +
coord_equal()

Plot data with difference vector (black) and LDA vector (blue)
ggplot() +
geom_point(data = df, aes(V1, V2, color = class), alpha = .5) +
geom_segment(data = mdiff_df, aes(x = x1, y = y1, xend = x2, yend = y2), arrow = arrow()) +
geom_segment(data = mdiff_lda_df, aes(x = x1, y = y1, xend = x2, yend = y2), arrow = arrow(), color = "blue") +
coord_equal() +
facet_wrap(~class) +
ggtitle("Difference vector (black) and LDA vector (blue)")

NA
NA
LS0tCnRpdGxlOiAiTERBIHZzIGRpZmZlcmVuY2UgdmVjdG9yIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdG9jX2RlcHRoOiAzCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHRoZW1lOiBsdW1lbgotLS0KCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KE1BU1MpCmxpYnJhcnkobWFncml0dHIpCmBgYAoKCmBgYHtyfQpzZXQuc2VlZCg0MSkKYGBgCgojIEdlbmVyYXRlIGRhdGEKCmBgYHtyfQp0aGV0YSA8LSBybm9ybSgxKSAjIGFuZ2xlCkEgPC0gbWF0cml4KHJub3JtKDEwMCAqIDIpLCAxMDAsIDIpICMgcm90YXRpb24gdmVjdG9yCkEgPC0gQSAlKiUgZGlhZyhjKDMsIDEpKSAlKiUgbWF0cml4KGMoY29zKHRoZXRhKSwgc2luKHRoZXRhKSwgLXNpbih0aGV0YSksIGNvcyh0aGV0YSkpLCAyLCAyKQpTaWdtYSA8LSB2YXIoQSkKU2lnbWEKYGBgCgpCaWFzIHZlY3RvcnMKCmBgYHtyfQptYSA8LSBjKDIsIDApCm1iIDwtIGMoNSwgMikKYGBgCgpHZW5lcmF0ZSB0d28gbXVsdGl2YXJpYXRlIGdhdXNzaWFucwoKYGBge3J9CmEgPC0gbXZybm9ybShuID0gMTAwMCwgbWEsIFNpZ21hKQpiIDwtIG12cm5vcm0obiA9IDEwMDAsIG1iLCBTaWdtYSkKYGBgCgoKUHJpbnQgY292YXJpYW5jZSBtYXRyaWNlcwoKYGBge3J9CmEgJT4lIGFzLmRhdGEuZnJhbWUgJT4lIGNvdgoKYiAlPiUgYXMuZGF0YS5mcmFtZSAlPiUgY292CmBgYAoKIyBMREEgCgpDb21wdXRlIGRpZmZlcmVuY2UgdmVjdG9yIGFuZCBMREEgdmVjdG9yCgpgYGB7cn0KbWRpZmYgPC0gbWIgLSBtYQptZGlmZl9sZGEgPC0gc29sdmUoU2lnbWEsIG1kaWZmKQpgYGAKCiMgRGlzcGxheSAKCkNyZWF0ZSBkYXRhIGZyYW1lIGZvciB0aGUgdmVjdG9ycwoKYGBge3J9Cm1kaWZmX2RmIDwtIGRhdGFfZnJhbWUoeDIgPSBtZGlmZlsxXSwgeTIgPSBtZGlmZlsyXSwgeDEgPSAwLCB5MSA9IDApCm1kaWZmX2xkYV9kZiA8LSBkYXRhX2ZyYW1lKHgyID0gbWRpZmZfbGRhWzFdLCB5MiA9IG1kaWZmX2xkYVsyXSwgeDEgPSAwLCB5MSA9IDApCmBgYAoKCmBgYHtyfQpkZiA8LSAKICBiaW5kX3Jvd3MoCiAgICBhcy5kYXRhLmZyYW1lKGEpICU+JSBtdXRhdGUoY2xhc3MgPSAiYSIpLAogICAgYXMuZGF0YS5mcmFtZShiKSAlPiUgbXV0YXRlKGNsYXNzID0gImIiKQogICAgKQpgYGAKClBsb3QgZGF0YQoKYGBge3J9CmdncGxvdCgpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gZGYsIGFlcyhWMSwgVjIsIGNvbG9yID0gY2xhc3MpLCBhbHBoYSA9IC41KSArIAogIGNvb3JkX2VxdWFsKCkKYGBgCgpQbG90IGRhdGEgd2l0aCBkaWZmZXJlbmNlIHZlY3RvciAoYmxhY2spIGFuZCBMREEgdmVjdG9yIChibHVlKQoKYGBge3J9CmdncGxvdCgpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gZGYsIGFlcyhWMSwgVjIsIGNvbG9yID0gY2xhc3MpLCBhbHBoYSA9IC41KSArIAogIGdlb21fc2VnbWVudChkYXRhID0gbWRpZmZfZGYsIGFlcyh4ID0geDEsIHkgPSB5MSwgeGVuZCA9IHgyLCB5ZW5kID0geTIpLCBhcnJvdyA9IGFycm93KCkpICsKICBnZW9tX3NlZ21lbnQoZGF0YSA9IG1kaWZmX2xkYV9kZiwgYWVzKHggPSB4MSwgeSA9IHkxLCB4ZW5kID0geDIsIHllbmQgPSB5MiksIGFycm93ID0gYXJyb3coKSwgY29sb3IgPSAiYmx1ZSIpICsKICBjb29yZF9lcXVhbCgpICsgCiAgZmFjZXRfd3JhcCh+Y2xhc3MpICsKICBnZ3RpdGxlKCJEaWZmZXJlbmNlIHZlY3RvciAoYmxhY2spIGFuZCBMREEgdmVjdG9yIChibHVlKSIpCgoKYGBgCgo=