From c01c507087b9c2a6ef2b38368e6117a827d2d344 Mon Sep 17 00:00:00 2001 From: ergz Date: Sat, 10 Sep 2022 00:54:37 -0700 Subject: [PATCH] adds more work --- R/ch2.html | 689 ++++++++++++++++-- R/ch2.qmd | 156 ++++ .../figure-html/unnamed-chunk-11-1.png | Bin 0 -> 16136 bytes R/ch2_files/figure-html/unnamed-chunk-6-1.png | Bin 0 -> 12269 bytes 4 files changed, 797 insertions(+), 48 deletions(-) create mode 100644 R/ch2_files/figure-html/unnamed-chunk-11-1.png create mode 100644 R/ch2_files/figure-html/unnamed-chunk-6-1.png diff --git a/R/ch2.html b/R/ch2.html index c574ee7..54a30d8 100644 --- a/R/ch2.html +++ b/R/ch2.html @@ -138,8 +138,10 @@ code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warni library(dplyr) library(tidyr) library(gt) -data(fake_news) -fake_news <- tibble::as_tibble(fake_news) +library(tibble) +library(ggplot2) +data(fake_news) +fake_news <- tibble::as_tibble(fake_news)

What is the proportion of news articles that were labeled fake vs real.

@@ -243,12 +245,12 @@ Probability and Likelihood gt::cols_width(everything() ~ px(100))
-
+
@@ -787,6 +789,597 @@ total probability

\[P(B^c) = P(A \cap B^c) + P(A^c \cap B^c)\] \[=P(A|B^c)P(B^c) + P(A^c|B^c)P(B^c)\] \[=.0132 + .5868 = .6\]

+

In the above calculations we also step through joint probabilities

+
+
+
+ +
+
+Joint and conditional probability +
+
+
+

\[P(A \cap B) = P(A|B)P(B)\]

+

\(A\) and \(B\) are said to be independent events, if and only if

+

\[P(A \cap B) = P(A)P(B)\]

+

from this we can also derive the definition of a conditional probability

+

\[P(A|B) = \frac{P(A \cap B)}{P(B)}\]

+
+
+

At this point we are able to answer the question, “What is the probability, the new article is fake?”. Given that the new article has an exclamation point, we can zoom into the top row of the table of probabilitties. Within this row we have probabilities \(.1068/.12 = .833\) for fake and \(.0132 / .12 = .11\) for real.

+

This is essentially Baye’s Rule. We developed a posterior probability for an event \(B\) given some observation \(A\). We did so by combining the likelihood of event \(B\) given some new data \(A\) and the prior probability of event \(B\). More formally we have the following definition:

+
+
+
+ +
+
+Baye’s Rule +
+
+
+

The posterior probability of an event \(B\) given a \(A\) is:

+

\[ P(B|A) = \frac{P(A \cap B)}{P(A)} = \frac{L(B|A)P(B)}{P(A)}\]

+

where \(L\) is the likelihood function \(L(B|A) = P(B|A)\) and \(P(A)\) is the total probability of \(A\).

+

More generally,

+

\[ \frac{likelihood \cdot prior}{normalizing \;\; constant}\]

+
+
+ +
+

Simualation

+
+
articles <- tibble::tibble(type = c("real", "fake"))
+
+priors <- c(.6, .4)
+
+articles_sim <- sample_n(articles, 10000, replace = TRUE, weight = priors)
+
+
+
articles_sim |>
+    ggplot(aes(x = type)) + geom_bar()
+
+

+
+
+

and a summary table

+
+
articles_sim |>
+    group_by(type) |>
+    summarise(
+        total = n(), 
+        prop = total / nrow(articles_sim)
+    ) |>
+    gt()|>
+    gt::cols_width(everything() ~ px(100))
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
typetotalprop
fake39410.3941
real60590.6059
+
+
+
+

the simulation of 10,000 articles shows us very nearly the same priors we had from the data. We can now add the exclamation usage into the data.

+
+
articles_sim <- articles_sim |>
+    mutate(model_data = case_when(
+        type == "fake" ~ .267, 
+        type == "real" ~ .022
+    ))
+
+

The plan here is to iterate through the 10,000 samples and use the data_model value to assign either, “yes” or “no” using the sample function.

+
+
data <- c("yes", "no")
+
+articles_sim <- articles_sim |>
+    mutate(id = row_number()) |>
+    group_by(id) |>
+    mutate(usage = sample(data, 1, prob = c(model_data, 1 - model_data)))
+
+
+
articles_sim |>
+    group_by(usage, type) |>
+    summarise(
+        total = n()
+    ) |>
+    pivot_wider(names_from = type, values_from = total)
+
+
# A tibble: 2 × 3
+# Groups:   usage [2]
+  usage  fake  real
+  <chr> <int> <int>
+1 no     2936  5932
+2 yes    1005   127
+
+
+
+
articles_sim |>
+    ggplot(aes(x = type, fill = usage)) + 
+    geom_bar() + 
+    scale_fill_discrete(type = c("gray8", "dodgerblue4"))
+
+

+
+
+

So far have compute both the priors and likelihoods, we can simply filter our data to reflect the incoming article and determine our posterior.

+
+
articles_sim |>
+    filter(usage == "yes") |>
+    group_by(type) |>
+    summarise(
+        total = n()
+    ) |>
+    mutate(
+        prop = total / sum(total)
+    )
+
+
# A tibble: 2 × 3
+  type  total  prop
+  <chr> <int> <dbl>
+1 fake   1005 0.888
+2 real    127 0.112
+
+
+
+
+
+ +
+
+Discrete Probability Model +
+
+
+

Let \(Y\) be a discrete random variable. The probability model for \(Y\) is described by a probability mass function (pmf) defined as: \[f(y) = P(Y = y)\]

+

and has the following properties

+
    +
  1. \(0 \leq f(y) \leq 1\;\; \forall y\)
  2. +
  3. \(\sum_{\forall y}f(y) = 1\)
  4. +
+
+
+
+
+
+ +
+
+in emanuel’s words +
+
+
+

what does this mean? well its very straightforward a pmf is a function that takes in a some value y and outputs the probability that the random variable \(Y\) equals \(y\).

+
+
diff --git a/R/ch2.qmd b/R/ch2.qmd index ef93a80..4f2dd87 100644 --- a/R/ch2.qmd +++ b/R/ch2.qmd @@ -25,6 +25,8 @@ library(bayesrules) library(dplyr) library(tidyr) library(gt) +library(tibble) +library(ggplot2) data(fake_news) fake_news <- tibble::as_tibble(fake_news) ``` @@ -180,4 +182,158 @@ parts. Namely $$P(B^c) = P(A \cap B^c) + P(A^c \cap B^c)$$ $$=P(A|B^c)P(B^c) + P(A^c|B^c)P(B^c)$$ $$=.0132 + .5868 = .6$$ +::: + +In the above calculations we also step through **joint probabilities** + +:::{.callout-note} +## Joint and conditional probability + +$$P(A \cap B) = P(A|B)P(B)$$ + +$A$ and $B$ are said to be independent events, if and only if + +$$P(A \cap B) = P(A)P(B)$$ + +from this we can also derive the definition of a conditional probability + +$$P(A|B) = \frac{P(A \cap B)}{P(B)}$$ + +::: + +At this point we are able to answer the question, "What is the probability, +the new article is fake?". Given that the new article has an exclamation +point, we can zoom into the top row of the table of probabilitties. Within +this row we have probabilities $.1068/.12 = .833$ for fake and $.0132 / .12 = .11$ +for real. + +This is essentially Baye's Rule. We developed a posterior probability for an event +$B$ given some observation $A$. We did so by combining the likelihood of event $B$ +given some new data $A$ and the prior probability of event $B$. More formally we +have the following definition: + +:::{.callout-note} +## Baye's Rule + +The posterior probability of an event $B$ given a $A$ is: + +$$ P(B|A) = \frac{P(A \cap B)}{P(A)} = \frac{L(B|A)P(B)}{P(A)}$$ + +where $L$ is the likelihood function $L(B|A) = P(B|A)$ and $P(A)$ is the +total probability of $A$. + +More generally, + +$$ \frac{likelihood \cdot prior}{normalizing \;\; constant}$$ +::: + +### Simualation + + +```{r} +articles <- tibble::tibble(type = c("real", "fake")) + +priors <- c(.6, .4) + +articles_sim <- sample_n(articles, 10000, replace = TRUE, weight = priors) +``` + +```{r} +articles_sim |> + ggplot(aes(x = type)) + geom_bar() +``` + +and a summary table + +```{r} +articles_sim |> + group_by(type) |> + summarise( + total = n(), + prop = total / nrow(articles_sim) + ) |> + gt()|> + gt::cols_width(everything() ~ px(100)) +``` + +the simulation of 10,000 articles shows us very nearly +the same priors we had from the data. We can now add +the exclamation usage into the data. + +```{r} + +articles_sim <- articles_sim |> + mutate(model_data = case_when( + type == "fake" ~ .267, + type == "real" ~ .022 + )) +``` + + +The plan here is to iterate through the 10,000 samples +and use the `data_model` value to assign either, "yes" or +"no" using the `sample` function. + +```{r} +data <- c("yes", "no") + +articles_sim <- articles_sim |> + mutate(id = row_number()) |> + group_by(id) |> + mutate(usage = sample(data, 1, prob = c(model_data, 1 - model_data))) +``` + + +```{r} +articles_sim |> + group_by(usage, type) |> + summarise( + total = n() + ) |> + pivot_wider(names_from = type, values_from = total) +``` + +```{r} +articles_sim |> + ggplot(aes(x = type, fill = usage)) + + geom_bar() + + scale_fill_discrete(type = c("gray8", "dodgerblue4")) +``` + +So far have compute both the priors and likelihoods, we can simply +filter our data to reflect the incoming article and determine our +posterior. + +```{r} +articles_sim |> + filter(usage == "yes") |> + group_by(type) |> + summarise( + total = n() + ) |> + mutate( + prop = total / sum(total) + ) +``` + + +:::{.callout-note} +## Discrete Probability Model + +Let $Y$ be a discrete random variable. The probability model for $Y$ is +described by a **probability mass function** (pmf) defined as: +$$f(y) = P(Y = y)$$ + +and has the following properties + +1. $0 \leq f(y) \leq 1\;\; \forall y$ +2. $\sum_{\forall y}f(y) = 1$ +::: + + +:::{.callout-caution} +## in emanuel's words +what does this mean? well its very straightforward a pmf is a function that takes +in a some value y and outputs the probability that the random variable +$Y$ equals $y$. ::: \ No newline at end of file diff --git a/R/ch2_files/figure-html/unnamed-chunk-11-1.png b/R/ch2_files/figure-html/unnamed-chunk-11-1.png new file mode 100644 index 0000000000000000000000000000000000000000..faa2b6608ef4aed5fb341f03d5e8dd161483b307 GIT binary patch literal 16136 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

eWMo$r<(FnJtcA zLo6bMpBzrX+}AJJA1#UnQ%ZdA`z2xt_y>ex*=zJFD{H9UrPZaRF2DPJ5m^}>rRCN= za0+u!B`Bd%Q?prd)N5GBS-UTT0IezD5eX3IFv$IMW2a3@zEAgC>))QdFtW0P?s{mN3W2($7-IG@9*p(3@+}?O$l~b3(x_7D*{t&2PRc>6uh)Rn z3=~zf72heTUQ6)gfsW`_ULs<%Ox)m}w&0}OsPg8o#I zH;m1;#r$Mw4b!_6Da}u`nKRep& xxFT{{RRdWJv%3 literal 0 HcmV?d00001 diff --git a/R/ch2_files/figure-html/unnamed-chunk-6-1.png b/R/ch2_files/figure-html/unnamed-chunk-6-1.png new file mode 100644 index 0000000000000000000000000000000000000000..84c0bbf5e712c394d8110294b389e83189b360f0 GIT binary patch literal 12269 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