diff --git a/static/~brozek/files/courses/BayesianStatistics/Challenger.png b/static/~brozek/files/courses/BayesianStatistics/Challenger.png new file mode 100644 index 0000000..82d53b2 Binary files /dev/null and b/static/~brozek/files/courses/BayesianStatistics/Challenger.png differ diff --git a/static/~brozek/files/courses/BayesianStatistics/challengerfitted.png b/static/~brozek/files/courses/BayesianStatistics/challengerfitted.png new file mode 100644 index 0000000..38e32c7 Binary files /dev/null and b/static/~brozek/files/courses/BayesianStatistics/challengerfitted.png differ diff --git a/static/~brozek/files/courses/BayesianStatistics/heightpairs.png b/static/~brozek/files/courses/BayesianStatistics/heightpairs.png new file mode 100644 index 0000000..41de2e2 Binary files /dev/null and b/static/~brozek/files/courses/BayesianStatistics/heightpairs.png differ diff --git a/static/~brozek/index.html b/static/~brozek/index.html new file mode 100644 index 0000000..a34b626 --- /dev/null +++ b/static/~brozek/index.html @@ -0,0 +1,89 @@ + + + + + + + + + Home | Brandon Rozek + + + + + + +
+
+

Brandon Rozek's Tilda Space

+

Welcome

+

My main website is https://brandonrozek.com. Though I like the customization that Wordpress allows, it does come with additional overhead.

+

Therefore, I decided to use the Tilda space offered by the Computer Science department to host content pertaining to my Academic Life.

+

As such, my research and other class documents will appear here.

+

For the curious, this website was built with Pico CMS using the BitsAndPieces theme.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2FBayesianStatistics%2Fweek1.html b/static/~brozek/index.html?courses%2FBayesianStatistics%2Fweek1.html new file mode 100644 index 0000000..ef12135 --- /dev/null +++ b/static/~brozek/index.html?courses%2FBayesianStatistics%2Fweek1.html @@ -0,0 +1,382 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Bayesian Statistics

+

Rules of Probability

+

Probabilities must be between zero and one, i.e., $0≤P(A)≤1$ for any event A.

+

Probabilities add to one, i.e., $\sum{P(X_i)} = 1$

+

The complement of an event, $A^c$, denotes that the event did not happen. Since probabilities must add to one, $P(A^c) = 1 - P(A)$

+

If A and B are two events, the probability that A or B happens (this is an inclusive or) is the probability of the union of the events: +$$ +P(A \cup B) = P(A) + P(B) - P(A\cap B) +$$ +where $\cup$ represents union ("or") and $\cap$ represents intersection ("and"). If a set of events $Ai$ are mutually exclusive (only one event may happen), then +$$ +P(\cup{i=1}^n{Ai}) = \sum{i=1}^n{P(A_i)} +$$

+

Odds

+

The odds for event A, denoted $\mathcal{O}(A)$ is defined as $\mathcal{O}(A) = P(A)/P(A^c)$

+

This is the probability for divided by probability against the event

+

From odds, we can also compute back probabilities +$$ +\frac{P(A)}{P(A^c)} = \mathcal{O}(A) +$$

+

$$ +\frac{P(A)}{1-P(A)} = \mathcal{O}(A) +$$

+

$$ +\frac{1 -P(A)}{P(A)} = \frac{1}{\mathcal{O}(A)} +$$

+

$$ +\frac{1}{P(A)} - 1 = \frac{1}{\mathcal{O}(A)} +$$

+

$$ +\frac{1}{P(A)} = \frac{1}{\mathcal{O}(A)} + 1 +$$

+

$$ +\frac{1}{P(A)} = \frac{1 + \mathcal{O}(A)}{\mathcal{O}(A)} +$$

+

$$ +P(A) = \frac{\mathcal{O}(A)}{1 + \mathcal{O}(A)} +$$

+

Expectation

+

The expected value of a random variable X is a weighted average of values X can take, with weights given by the probabilities of those values. +$$ +E(X) = \sum_{i=1}^n{x_i * P(X=x_i)} +$$

+

Frameworks of probability

+

Classical -- Outcomes that are equally likely have equal probabilities

+

Frequentist -- In an infinite sequence of events, what is the relative frequency

+

Bayesian -- Personal perspective (your own measure of uncertainty)

+

In betting, one must make sure that all the rules of probability are followed. That the events are "coherent", otherwise one might construct a series of bets where you're guaranteed to lose money. This is referred to as a Dutch book.

+

Conditional probability

+

$$ +P(A|B) = \frac{P(A\cup B)}{P(B)} +$$

+

Where $A|B$ denotes "A given B"

+

Example from lecture:

+

Suppose there are 30 students, 9 of which are female. From the 30 students, 12 are computer science majors. 4 of those 12 computer science majors are female +$$ +P(Female) = \frac{9}{30} = \frac{3}{10} +$$

+

$$ +P(CS) = \frac{12}{30} = \frac{2}{5} +$$

+

$$ +P(F\cap CS) = \frac{4}{30} = \frac{2}{15} +$$

+

$$ +P(F|CS) = \frac{P(F \cap CS)}{P(CS)} = \frac{2/15}{2/5} = \frac{1}{3} +$$

+

An intuitive way to think about a conditional probability is that we're looking at a subsegment of the original population, and asking a probability question within that segment +$$ +P(F|CS^c) = \frac{P(F\cap CS^c)}{PS(CS^c)} = \frac{5/30}{18/30} = \frac{5}{18} +$$ +The concept of independence is when one event does not depend on another. +$$ +P(A|B) = P(A) +$$ +It doesn't matter that B occurred.

+

If two events are independent then the following is true +$$ +P(A\cap B) = P(A)P(B) +$$ +This can be derived from the conditional probability equation.

+

Conditional Probabilities in terms of other conditional

+

Suppose we don't know what $P(A|B)$ is but we do know what $P(B|A)$ is. We can then rewrite $P(A|B)$ in terms of $P(B|A)$ +$$ +P(A|B) = \frac{P(B|A)P(A)}{P(B|A)P(A) + P(B|A^c)P(A^c)} +$$ +Let's look at an example of an early test for HIV antibodies known as the ELISA test. +$$ +P(+ | HIV) = 0.977 +$$

+

$$ +P(- | NO_HIV) = 0.926 +$$

+

As you can see over 90% of the time, this test was accurate.

+

The probability of someone in North America having this disease was $P(HIV) = .0026$

+

Now let's consider the following problem: the probability of having the disease given that they tested positive $P(HIV | +)$ +$$ +P(HIV|+) = \frac{P(+|HIV)P(HIV)}{P(+|HIV)P(HIV) + P(+|NO_HIV){P(NO_HIV)}} +$$

+

$$ +P(HIV|+) = \frac{(.977)(.0026)}{(.977)(.0026) + (1-.977)(1-.0026)} +$$

+

$$ +P(HIV|+) = 0.033 +$$

+

This example looked at Bayes Theorem for the two event case. We can generalize it to n events through the following formula +$$ +P(A|B) = \frac{P(B|A_1){(A1)}}{\sum{i=1}^{n}{P(B|A_i)}P(A_i)} +$$

+

Bernoulli Distribution

+

~ means 'is distributed as'

+

We'll be first studying the Bernoulli Distribution. This is when your event has two outcomes, which is commonly referred to as a success outcome and a failure outcome. The probability of success is $p$ which means the probability of failure is $(1-p)$ +$$ +X \sim B(p) +$$

+

$$ +P(X = 1) = p +$$

+

$$ +P(X = 0) = 1-p +$$

+

The probability of a random variable $X$ taking some value $x$ given $p$ is +$$ +f(X = x | p) = f(x|p) = p^x(1-p)^{1 - x}I +$$ +Where $I$ is the Heavenside function

+

Recall the expected value +$$ +E(X) = \sum_{x_i}{x_iP(X=x_i)} = (1)p + (0)(1-p) = p +$$ +We can also define the variance of Bernoulli +$$ +Var(X) = p(1-p) +$$

+

Binomial Distribution

+

The binomial distribution is the sum of n independent Bernoulli trials +$$ +X \sim Bin(n, p) +$$

+

$$ +P(X=x|p) = f(x|p) = {n \choose x} p^x (1-p)^{n-x} +$$

+

$n\choose x$ is the combinatoric term which is defined as +$$ +{n \choose x} = \frac{n!}{x! (n - x)!} +$$

+

$$ +E(X) = np +$$

+

$$ +Var(X) = np(1-p) +$$

+

Uniform distribution

+

Let's say X is uniformally distributed +$$ +X \sim U[0,1] +$$

+

$$ +f(x) = \left{ +\begin{array}{lr} +1 & : x \in [0,1]\ +0 & : otherwise +\end{array} +\right. +$$

+

$$ +P(0 < x < \frac{1}{2}) = \int_0^\frac{1}{2}{f(x)dx} = \int_0^\frac{1}{2}{dx} = \frac{1}{2} +$$

+

$$ +P(0 \leq x \leq \frac{1}{2}) = \int_0^\frac{1}{2}{f(x)dx} = \int_0^\frac{1}{2}{dx} = \frac{1}{2} +$$

+

$$ +P(x = \frac{1}{2}) = 0 +$$

+

Rules of probability density functions

+

$$ +\int_{-\infty}^\infty{f(x)dx} = 1 +$$

+

$$ +f(x) \ge 0 +$$

+

$$ +E(X) = \int_{-\infty}^\infty{xf(x)dx} +$$

+

$$ +E(g(X)) = \int{g(x)f(x)dx} +$$

+

$$ +E(aX) = aE(X) +$$

+

$$ +E(X + Y) = E(X) + E(Y) +$$

+

If X & Y are independent +$$ +E(XY) = E(X)E(Y) +$$

+

Exponential Distribution

+

$$ +X \sim Exp(\lambda) +$$

+

Where $\lambda$ is the average unit between observations +$$ +f(x|\lambda) = \lambda e^{-\lambda x} +$$

+

$$ +E(X) = \frac{1}{\lambda} +$$

+

$$ +Var(X) = \frac{1}{\lambda^2} +$$

+

Uniform (Continuous) Distribution

+

$$ +X \sim [\theta_1, \theta_2] +$$

+

$$ +f(x|\theta_1,\theta_2) = \frac{1}{\theta_2 - \theta1}I{\theta_1 \le x \le \theta_2} +$$

+

Normal Distribution

+

$$ +X \sim N(\mu, \sigma^2) +$$

+

$$ +f(x|\mu,\sigma^2) = \frac{1}{\sqrt{2\pi \sigma^2}}e^{-\frac{1}{2\sigma^2}(x-\mu)^2} +$$

+

$$ +E(X) = \mu +$$

+

$$ +Var(X) = \sigma^2 +$$

+

Variance

+

Variance is the squared distance from the mean +$$ +Var(X) = \int_{-\infty}^\infty {(x - \mu)^2f(x)dx} +$$

+

Geometric Distribution (Discrete)

+

The geometric distribution is the number of trails needed to get the first success, i.e, the number of Bernoulli events until a success is observed. +$$ +X \sim Geo(p) +$$

+

$$ +P(X = x|p) = p(1-p)^{x-1} +$$

+

$$ +E(X) = \frac{1}{p} +$$

+

Multinomial Distribution (Discrete)

+

Multinomial is like a binomial when there are more than two possible outcomes.

+

$$ +f(x_1,...,x_k|p_1,...,p_k) = \frac{n!}{x_1! ... x_k!}p_1^{x_1}...p_k^{x_k} +$$

+

Poisson Distribution (Discrete)

+

The Poisson distribution is used for counts. The parameter $\lambda > 0$ is the rate at which we expect to observe the thing we are counting. +$$ +X \sim Pois(\lambda) +$$

+

$$ +P(X=x|\lambda) = \frac{\lambda^xe^{-\lambda}}{x!} +$$

+

$$ +E(X) = \lambda +$$

+

$$ +Var(X) = \lambda +$$

+

Gamma Distribution (Continuous)

+

If $X_1, X_2, ..., X_n$ are independent and identically distributed Exponentials,waiting time between success events, then the total waiting time for all $n$ events to occur will follow a gamma distribution with shape parameter $\alpha = n$ and rate parameter $\beta = \lambda$ +$$ +Y \sim Gamma(\alpha, \beta) +$$

+

$$ +f(y|\alpha,\beta) = \frac{\beta^n}{\Gamma(\alpha)}y^{n-1}e^{-\beta y}I_{y\ge0}(y) +$$

+

$$ +E(Y) = \frac{\alpha}{\beta} +$$

+

$$ +Var(Y) = \frac{\alpha}{\beta^2} +$$

+

Where $\Gamma(x)$ is the gamma function. The exponential distribution is a special case of the gamma distribution with $\alpha = 1$. As $\alpha$ increases, the gamma distribution more closely resembles the normal distribution.

+

Beta Distribution (Continuous)

+

The beta distribution is used for random variables which take on values between 0 and 1. For this reason, the beta distribution is commonly used to model probabilities. +$$ +X \sim Beta(\alpha, \beta) +$$

+

$$ +f(x|\alpha,\beta) = \frac{\Gamma(\alpha + \beta)}{\Gamma(\alpha)\Gamma(\beta)}x^{n -1}(1 - x)^{\beta - 1}I_{{0 < x < 1}} +$$

+

$$ +E(X) = \frac{\alpha}{\alpha + \beta} +$$

+

$$ +Var(X) = \frac{\alpha\beta}{(\alpha + \beta)^2(\alpha+\beta+1)} +$$

+

The standard uniform distribution is a special case of the beta distribution with $\alpha = \beta = 1$

+

Bayes Theorem for continuous distribution

+

$$ +f(\theta|y) = \frac{f(y|\theta)f(\theta)}{\int{f(y|\theta)f(\theta)d\theta}} +$$

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2FBayesianStatistics%2Fweek2.html b/static/~brozek/index.html?courses%2FBayesianStatistics%2Fweek2.html new file mode 100644 index 0000000..2d8474d --- /dev/null +++ b/static/~brozek/index.html?courses%2FBayesianStatistics%2Fweek2.html @@ -0,0 +1,510 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Under the frequentest paradigm, you view the data as a random sample from some larger, potentially hypothetical population. We can then make probability statements i.e, long-run frequency statements based on this larger population.

+

Coin Flip Example (Central Limit Theorem)

+

Let's suppose we flip a coin 100 times and we get 44 heads and 56 tails. +$$ +n = 100 +$$ +We can view these 100 flips as a random sample from a much larger infinite hypothetical population of flips from this coin.

+

Let's say that each flip follows a Bournelli distribution with some probability p. In this case $p$ is unknown, but we're assuming it's fixed because we have a particular physical coin.

+

We can ask what's our best estimate of the probability of getting a head, or an estimate of $p$. We can also ask about how confident we are about that estimate.

+

Let's start by applying the Central Limit Theorem. The Central Limit Theorem states that the sum of 100 flips will follow approximately a Normal distribution with mean 100p and variance 100p(1-p) +$$ +\sum^n_{i=1}{x_i} \sim N(np, np(1-p)) +$$

+

$$ +\sum_{i = 1}^{100}{x_i} \sim N(100p, 100p(1-p)) +$$

+

By the properties of a Normal distribution, 95% of the time we'll get a result within 1.96 standard deviations of the mean. Our estimate is $100\hat{p}$ and our error is 1.96 times the standard deviation. +$$ +n\hat{p} \pm 1.96\sqrt{n\hat{p}(1-\hat{p})} +$$

+

$$ +100\hat{p} \pm 1.96\sqrt{100\hat{p}(1-\hat{p})} +$$

+

This is referred to as a Confidence Interval. Confidence Intervals are commonly abbreviated as CI. In our example $\hat{p} = \frac{44}{n} = \frac{44}{100}$. Therefore, the 95% Confidence Interval in the true number of heads after flipping a coin 100 times is: +$$ +100(.44) \pm 1.96\sqrt{100(.44)(1-.44)} +$$

+

$$ +44 \pm 1.96\sqrt{44(.56)} +$$

+

$$ +44\pm 1.96\sqrt{24.64} +$$

+

$$ +(34.27, 53.73) +$$

+

We can divide this by 100 to get the 95% Confidence Interval for $p$ +$$ +(0.34, 0.53) +$$ +Let's step back and ask, what does it mean when I say we're 95% confident?

+

Under the frequentest paradigm, what this means is we have to think back to our infinite hypothetical sequence of events. So if we were to repeat this trial an infinite number of times, or an arbitrary large number of times. Each time we create a confidence interval based on the data we observe, than on average 95% of the intervals we make will contain the true value of p.

+

On the other hand, we might want to know something about this particular interval. Does this interval contain the true p? What's the probability that this interval contains a true p? Well, we don't know for this particular interval. But under the frequentest paradigm, we're assuming that there is a fixed answer for p. Either p is in that interval or it's not in that interval. The probability that p is in that interval is either 0 or 1.

+

Example: Heart Attack Patients (Maximum Likelihood)

+

Consider a hospital where 400 patients are admitted over a month for heart attacks, and a month later 72 of them have died and 328 of them have survived.

+

We can ask, what's our estimate of the mortality rate?

+

Under the frequentest paradigm, we must first establish our reference population. What do we think our reference population is here? One possibility is we could think about heart attack patients in the region.

+

Another reference population we can think about is heart attack patients that are admitted to this hospital, but over a longer period of time.

+

Both of these might be reasonable attempts, but in this case our actual data are not random sample from either of those populations. We could sort of pretend they are and move on, or we could also try to think harder about what a random sample situation might be. We can think about all the people in the region who might possibly have a heart attack and might possibly get admitted to this hospital.

+

It's a bit of an odd hypothetical situation, and so there are some philosophical issues with the setup of this whole problem with the frequentest paradigm, In any case, let's forge forward and think about how we might do some estimation.

+

Moving on, we can say each patient comes from a Bernoulli distribution with an unknown parameter $\theta$. +$$ +Y_i \sim B(\theta) +$$

+

$$ +P(Y_i = 1) = \theta +$$

+

In this case, let's call the "success" a mortality.

+

The probability density function for the entire set of data we can write in vector form. Probability of all the Y's take some value little y given a value of theta. +$$ +P(Y = y | \theta) = P(Y_1 = y_1, Y_2, = y_2,\dots, Y_n=y_n|\theta) +$$ +Since we're viewing these as independent events, then the probability of each of these individual ones we can write in product notation. +$$ +P(Y = y | \theta) = P(Y_1 = y_1|\theta)\dots P(Y_n = y_n | \theta) +$$

+

$$ +P(Y = y | \theta) = \prod_{i = 1}^n{P(Y_i =yi | \theta)} = \prod{i = 1}^n{(\theta^{y_i}(1-\theta)^{1-y_i})} +$$

+

This is the probability of observing the actual data that we collected, conditioned on a value of the parameter $\theta$. We can now think about this expression as a function of theta. This is a concept of a likelihood. +$$ +L(\theta|y) = \prod_{i = 1}^n{(\theta^{y_i}(1-\theta)^{1-y_i})} +$$ +It looks like the same function, but here it is a function of y given $\theta$. And now we're thinking of it as a function of $\theta$ given y.

+

This is not a probability distribution anymore, but it is still a function for $\theta$.

+

One we to estimate $\theta$ is that we choose the $\theta$ that gives us the largest value of the likelihood. It makes the data the most likely to occur for the particular data we observed.

+

This is referred to as the maximum likelihood estimate (MLE),

+

We're trying to find the $\theta$ that maximizes the likelihood.

+

In practice, it's usually easier to maximize the natural logarithm of the likelihood, commonly referred to as the log likelihood. +$$ +\mathcal{L}(\theta) = \log{L(\theta|y)} +$$ +Since the logarithm is a monotonic function, if we maximize the logarithm of the function, we also maximize the original function. +$$ +\mathcal{L(\theta)} = \log{\prod_{i = 1}^n{(\theta^{y_i}(1-\theta)^{1-y_i})}} +$$

+

$$ +\mathcal{L}(\theta) = \sum_{i = 1}^n{\log{(\theta^{y_i}(1-\theta)^{1-y_i})}} +$$

+

$$ +\mathcal{L}(\theta) = \sum_{i = 1}^n{(\log{(\theta^{y_i}}) + \log{(1-\theta)^{1-y_i}})} +$$

+

$$ +\mathcal{L}(\theta) = \sum_{i = 1}^n{(y_i\log{\theta} + (1 - y_i)\log{(1-\theta)})} +$$

+

$$ +\mathcal{L}(\theta) = \log{\theta}\sum_{i = 1}^n{yi} + \log{(1-\theta)}\sum{i = 1}^n{(1-y_i)} +$$

+

How do we find the theta that maximizes this function? Recall from calculus that we can maximize a function by taking the derivative and setting it equal to 0. +$$ +\mathcal{L}^\prime(\theta) = \frac{1}{\theta}\sum{y_i} - \frac{1}{1-\theta}\sum{(1 - y_i)} +$$ +Now we need to set it equal to zero and solve for $\hat{\theta}$ +$$ +\frac{\sum{y_i}}{\hat{\theta}} = \frac{\sum{(1-y_i)}}{1-\hat{\theta}} +$$

+

$$ +\hat{\theta}\sum{(1-y_i)} = (1-\hat{\theta})\sum{y_i} +$$

+

$$ +\hat{\theta}\sum{(1-y_i)} + \hat{\theta}\sum{y_i} = \sum{y_i} +$$

+

$$ +\hat{\theta}(\sum^n{(1 - y_i + y_i)}) = \sum{y_i} +$$

+

$$ +\hat{\theta} = \frac{1}{n}\sum{y_i} = \hat{p} = \frac{72}{400} = 0.18 +$$

+

Maximum likelihood estimators have many desirable mathematical properties. They're unbiased, they're consistent, and they're invariant.

+

In general, under certain regularity conditions, we can say that the MLE is approximately normally distributed with mean at the true value of $\theta$ and the variance $\frac{1}{I(\hat{\theta})}$ where $I(\hat{\theta})$ is the Fisher information at the value of $\hat{\theta}$. The Fisher information is a measure of how much information about $\theta$ is in each data point. +$$ +\hat{\theta} \sim N(\theta, \frac{1}{I(\hat{\theta})}) +$$ +For a Bernoulli random variable, the Fisher information turns out to be +$$ +I(\theta) = \frac{1}{\theta(1-\theta)} +$$ +So the information is larger, when theta is near zero or near one, and it's the smallest when theta is near one half.

+

This makes sense, because if you're flipping a coin, and you're getting a mix of heads and tails, that tells you a little bit less than if you're getting nearly all heads or nearly all tails.

+

Exponential Likelihood Example

+

Let's say $X_i$ are distributed so +$$ +Xi \sim Exp(\lambda) +$$ +Let's say the data is independent and identically distributed, therefore making the overall density function +$$ +f(x|\lambda) = \prod{i = 1}^n{\lambda e^{-\lambda x_i}} +$$

+

$$ +f(x|\lambda) = \lambda^ne^{-\lambda \sum{x_i}} +$$

+

Now the likelihood function is +$$ +L(\lambda|x) = \lambda^n e^{-\lambda \sum{x_i}} +$$

+

$$ +\mathcal{L}(\lambda) = n\ln{\lambda} - \lambda\sum{x_i} +$$

+

Taking the derivative +$$ +\mathcal{L}^\prime(\lambda) = \frac{n}{\lambda} - \sum{x_i} +$$ +Setting this equal to zero +$$ +\frac{n}{\hat{\lambda}} =\sum{x_i} +$$

+

$$ +\hat{\lambda} = \frac{n}{\sum{x_i}} = \frac{1}{\bar{x}} +$$

+

Uniform Distribution

+

$$ +X_i \sim U[0, \theta] +$$

+

$$ +f(x|\theta) = \prod{i = 1}^n{\frac{1}{\theta}I{0 \le x_i \le \theta}} +$$

+

Combining all the indicator functions, for this to be a 1, each of these has to be true. These are going to be true if all the observations are bigger than 0, as in the minimum of the x is bigger than or equal to 0. The maximum of the x's is also less than or equal to $\theta$. +$$ +L(\theta|x) = \theta^{-1} I_{0\le min(x_i) \le max(x_i) \le \theta} +$$

+

$$ +L^\prime(\theta) = -n\theta^{-(n + 1)}I_{0 \le min(x_i) \le max(x_i)\le \theta} +$$

+

So now we can ask, can we set this equal to zero and solve for $\theta$? Well it turns out, this is not equal to zero for any $\theta$ positive value. We need $\theta$ to be strictly larger than zero.

+

However, we can also note that for $\theta$ positive, this will always be negative. The derivative is negative, that says this is a decreasing function. So this funciton will be maximized when we pick $\theta$ as small as possible. What's the smallest possible value of $\theta$ we can pick? Well we need in particular for $\theta$ to be larger than all of the $X_i$ . And so, the maximum likelihood estimate is the maximum of $X_i$ +$$ +\hat{\theta} = max(x_i) +$$

+

Products of Indicator Functions

+

Because 0 * 1 = 0, the product of indicator functions can be combined into a single indicator function with a modified condition.

+

Example: $I{x < 5} * I{x \ge 0} = I_{0 \le x < 5}$

+

Example: $\prod{i = 1}^n{I{xi < 2}} = I{xi < 2 for all i} = I{max(x_i) < 2}$

+

Introduction to R

+

R has some nice functions that one can use for analysis

+

mean(z) gives the mean of some row vector $z$

+

var(z) reports the variance of some row vector

+

sqrt(var(z)) gives the standard deviation of some row vector

+

seq(from=0.1, to = 0.9, by = 0.1) creates a vector that starts from $0.1$ and goes to $0.9$ incrementing by $0.1$

+
seq(from=0.1, to = 0.9, by = 0.1)
+[1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9
+seq(1, 10)
+[1] 1 2 3 4 5 6 7 8 9 10
+

names(x) gives the names of all the columns in the dataset.

+
names(trees)
+[1] "Girth"  "Height"  "Volume"
+

hist(x) provides a histogram based on a vector

+

The more general plot function tries to guess at which type of plot to make. Feeding it two numerical vectors will make a scatter plot.

+

The R function pairs takes in a data frame and tries to make all possible Pairwise scatterplots for the dataset.

+

The summary command gives the five/six number summary (minimum, first quartile, median, mean, third quartile, maximum)

+

Plotting the likelihood function in R

+

Going back to the hospital example

+
## Likelihood function
+likelihood = function(n, y, theta) {
+  return(theta^y * (1 - theta)^(n - y))
+}
+theta = seq(from = 0.01, to = 0.99, by = 0.01)
+plot(theta, likelihood(400, 72, theta))
+

You can also do this with log likelihoods. This is typically more numerically stable to compute

+
loglike = function(n, y, theta) {
+  return(y * log(theta) + (n - y) * log(1 - theta))
+}
+plot(theta, loglike(400, 72, theta))
+

Having these plotted as points makes it difficult to see, let's plot it as lines

+
plot(theta, loglike(400, 72, theta), type = "l")
+

Cumulative Distribution Function

+

The cumulative distribution function (CDF) exists for every distribution. We define it as $F(x) = P(X \le x)$ for random variable $X$.

+

If $X$ is discrete-valued, then the CDF is computed with summation $F(x) = \sum_{t = -\infty}^x {f(t)}$. where $f(t) = P(X = t)$ is the probability mass function (PMF) which we've already seen.

+

If $X$ is continuous, the CDF is computed with an integral $F(x) = \int_{-\infty}^x{f(t)dt}$

+

The CDF is convenient for calculating probabilities of intervals. Let $a$ and $b$ be any real numbers with $a < b$. Then the probability that $X$ falls between $a$ and $b$ is equal to $P(a < X < b) = P(X \le b) - P(X \le a) = F(b) - F(a)$

+

Quantile Function

+

The CDF takes a value for a random variable and returns a probability. Suppose instead we start with a number between $0$ and $1$, which we call $p$, and we wish to find a value $x$ so that $P(X \le x) = p$. The value $x$ which satisfies this equation is called the $p$ quantile. (or $100p$ percentile) of the distribution of $X$.

+

Probability Distributions in R

+

Each of the distributions introduced in Lesson 3 have convenient functions in R which allow you to evaluate the PDF/PMF, CDF, and quantile functions, as well as generate random samples from the distribution. To illustrate, Table I list these functions for the normal distribution

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FunctionWhat it does
dnorm(x, mean, sd)Evaluate the PDF at $x$ (mean = $\mu$ and sd = $\sqrt{\sigma^2}$)
pnorm(q, mean, sd)Evaluate the CDF at $q$
qnorm(p, mean, sd)Evaluate the quantile function at $p$
rnorm(n, mean, sd)Generate $n$ pseudo-random samples from the normal distribution
+

These four functions exist for each distribution where d... function evaluates the density/mass, p... evaluates the CDF, q... evaluates the quantile, and r... generates a sample. Table 2 lists the d... functions for some of the most popular distributions. The d can be replaced with p, q, or r for any of the distributions, depending on what you want to calculate.

+

For details enter ?dnorm to view R's documentation page for the Normal distribution. As usual , replace the norm with any distribution to read the documentation for that distribution.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DistributionFunctionParameters
$Binomial(n,p)$dbinom(x, size, prob)size = $n$, prob = $p$
$Poisson(\lambda)$dpois(x, lambda)lambda = $\lambda$
$Exp(\lambda)$dexp(x, rate)rate = $\lambda$
$Gamma(\alpha, \beta)$dgamma(x, shape, rate)shape = $\alpha$, rate = $\beta$
$Uniform(a, b)$dunif(x, min, max)min = $a$, max = $b$
$Beta(\alpha, \beta)$dbeta(x, shape1, shape2)shape1 = $\alpha$, shape2 = $\beta$
$N(\mu, \sigma^2)$dnorm(x, mean, sd)mean = $\mu$, sd = $\sqrt{\sigma^2}$
$t_v$dt(x, df)df = $v$
+

Two Coin Example

+

Suppose your brother has a coin which you know to be loaded so that it comes up heads 70% of the time. He then comes to you with some coin, you're not sure which one and he wants to make a bet with you. Betting money that it's going to come up heads.

+

You're not sure if it's the loaded coin or if it's just a fair one. So he gives you a chance to flip it 5 times to check it out.

+

You flip it five times and get 2 heads and 3 tails. Which coin do you think it is and how sure are you about that?

+

We'll start by defining the unknown parameter $\theta$, this is either that the coin is fair or it's a loaded coin. +$$ +\theta = {fair ,loaded} +$$

+

$$ +X \sim Bin(5, ?) +$$

+

$$ +f(x|\theta) = \begin{cases} +{5 \choose x}(\frac{1}{2})^5 & \theta = fair \ +{5 \choose x} (.7)^x (.3)^{5 - x} & \theta = loaded\ +\end{cases} +$$

+

We can also rewrite $f(x|\theta)$ with indicator functions +$$ +f(x|\theta) = {5\choose x}(.5)^5I{{\theta= fair}} + {5 \choose x}(.7)^x(.3)^{5 - x}I{{\theta = loaded}} +$$ +In this case, we observed that $x = 2$ +$$ +f(\theta | x = 2) = \begin{cases} +0.3125 & \theta = fair \ +0.1323 & \theta = loaded +\end{cases} +$$ +MLE $\hat{\theta} = fair$

+

That's a good point estimate, but then how do we answer the question, how sure are you?

+

This is not a question that's easily answered in the frequentest paradigm. Another question is that we might like to know what is the probability that theta equals fair, give, we observe two heads. +$$ +P(\theta = fair|x = 2) = ? +$$ +In the frequentest paradigm, the coin is a physical quantity. It's a fixed coin, and therefore it has a fixed probability of coining up heads. It is either the fair coin, or it's the loaded coin. +$$ +P(\theta = fair) = {0,1} +$$

+

Bayesian Approach to the Problem

+

An advantage of the Bayesian approach is that it allows you to easily incorporate prior information, when you know something in advance of the looking at the data. This is difficult to do under the Frequentest paradigm.

+

In this case, we're talking about your brother. You probably know him pretty well. So suppose you think that before you've looked at the coin, there's a 60% probability that this is the loaded coin.

+

This case, we put this into our prior. Our prior is that the probability the coin is loaded is 0.6. We can update our prior with the data to get our posterior beliefs, and we can do this using the bayes theorem.

+

Prior: $P(loaded) = 0.6$ +$$ +f(\theta|x) = \frac{f(x|\theta)f(\theta)}{\sum_\theta{f(x|\theta)f(\theta)}} +$$

+

$$ +f(\theta|x) = \frac{{5\choose x} [(\frac{1}{2})^5(.4)I{{\theta = fair}} + (.7)^x (.3)^{5-x}(.6)I{{\theta = loaded}} ] } +{{5\choose x} [(\frac{1}{2})^5(.4) + (.7)^x (.3)^{5-x}(0.6) ] } +$$

+

$$ +f(\theta|x=2)= \frac{0.0125I{{\theta=fair}} + 0.0079I{{\theta=loaded}} }{0.0125+0.0079} +$$

+

$$ +f(\theta|x=2) = 0.612I{{\theta=fair}} + 0.388I{{\theta = loaded}} +$$

+

As you can see in the calculation here, we have the likelihood times the prior in the numerator, and in the denominator, we have a normalizing constant, so that when we divide by this, we'll get answer that add up to one. These numbers match exactly in this case, because it's a very simple problem. But this is a concept that goes on, what's in the denominator here is always a normalizing constant. +$$ +P(\theta = loaded | x = 2) = 0.388 +$$ +This here updates our beliefs after seeing some data about what the probability might be.

+

We can also examine what would happen under different choices of prior. +$$ +P(\theta = loaded) = \frac{1}{2} \implies P(\theta = loaded | x = 2) = 0.297 +$$

+

$$ +P(\theta = loaded) = 0.9 \implies P(\theta = loaded | x = 2) = 0.792 +$$

+

In this case, the Bayesian approach is inherently subjective. It represents your own personal perspective, and this is an important part of the paradigm. If you have a different perspective, you will get different answers, and that's okay. It's all done in a mathematically vigorous framework, and it's all mathematically consistent and coherent.

+

And in the end, we get results that are interpretable

+

Continuous Bayes

+

$$ +f(\theta | y) = \frac{f(y | \theta)f(\theta)}{f(y)} = \frac{f(y|\theta)f(\theta)}{\int{f(y|\theta)f(\theta)d\theta}} = \frac{likelihood prior}{normalization} \propto likelihood prior +$$

+

In practice, sometimes this integral can be a pain to compute. And so, we may work with looking at saying this is proportional to the likelihood times the prior. And if we can figure out what this looks like and just put the appropriate normalizing constant on at the end, we don't necessarily have to compute this integral.

+

So for example, suppose we're looking at a coin and it has unknown probability $\theta$ of coming up heads. Suppose we express ignorance about the value of $\theta$ by assigning it a uniform distribution. +$$ +\theta \sim U[0, 1] +$$

+

$$ +f(\theta) = I_{{0 \le \theta\le 1}} +$$

+

$$ +f(\theta | y = 1) = \frac{\theta^1(1-\theta)^0I{{0 \le \theta\le1}}}{\int{-\infty}^\infty{\theta^1(1-\theta)^0I_{{0\le \theta \le 1}}}} +$$

+

$$ +f(\theta | y = 1) = \frac{\theta I_{{0\le\theta\le1}}}{\int0^1{\theta d\theta}} = 2\theta I{{0\le\theta\le1}} +$$

+

Now if we didn't want to take the integral we could've done this approach +$$ +f(\theta | y) \propto f(y|\theta)f(\theta) \propto \theta I_{{0\le\theta\le1}} +$$ +Which then we need to find the constant such that it's a proper PMF. In this case, it's $2$.

+

Since it's a proper PMF, we can perform interval probabilities as well. This is called Posterior interval estimates. +$$ +P(0.025 < \theta < 0.975) = \int_{0.025}^{0.975}{2\theta d \theta} = (0.975)^2 - (0.025)^2 = 0.95 +$$

+

$$ +P(\theta > 0.05) = 1 - (0.05)^2 = 0.9975 +$$

+

These are the sort of intervals we would get from the prior and asking about what their posterior probability is.

+

In other cases, we may want to ask, what is the posterior interval of interest? What's an interval that contains 95% of posterior probability in some meaningful way? This would be equivalent then to a frequentest confidence interval. We can do this in several different ways, 2 main ways that we make Bayesian Posterior intervals or credible intervals are equal-tailed intervals and highest posterior density intervals.

+

Equal-tailed Interval

+

In the case of an equal-tailed interval, we put the equal amount of probability in each tail. So to make a 95% interval we'll put 0.025 in each tail.

+

To be able to do this, we're going to have to figure out what the quantiles are. So we're going to need some value, $q$, so that +$$ +P(\theta < q | Y = 1) = \int_0^9{2\theta d\theta} = q^2 +$$

+

$$ +P(\sqrt{0.025} < \theta < \sqrt{0.975}) = P(0.158 < \theta < 0.987) = 0.95 +$$

+

This is an equal tailed interval in that the probability that $\theta$ is less than 0.18 is the same as the probability that $\theta$ is greater than 0.987. We can say that under the posterior, there's a 95% probability that $\theta$ is in this interval.

+

Highest Posterior Density (HPD)

+

Here we want to ask where in the density function is it highest? Theoretically this will be the shortest possible interval that contains the given probability, in this case a 95% probability. +$$ +P(\theta > \sqrt{0.05} | Y = 1) = P(\theta > 0.224 | Y = 1) = 0.95 +$$ +This is the shortest possible interval, that under the posterior has a probability 0.95. it's $\theta$ going from 0.224 up to 1.

+

The posterior distribution describes our understanding of our uncertainty combinbing our prior beliefs and the data. It does this with a probability density function, so at the end of teh day, we can make intervals and talk about probabilities of data being in the interval.

+

This is different from the frequentest approach, where we get confidence intervals. But we can't say a whole lot about the actual parameter relative to the confidence interval. We can only make long run frequency statements about hypothetical intervals.

+

In this case, we can legitimately say that the posterior probability that $\theta$ is bigger than 0.05 is $0.9975$. We can also say that we believe there's a 95% probability that $\theta$ is in between 0.158 and 0.987.

+

Bayesians represent uncertainty with probabilities, so that the coin itself is a physical quantity. It may have a particular value for $\theta$.

+

It may be fixed, but because we don't know what that value is, we represent our uncertainty about that value with a distribution. And at the end of the day, we can represent our uncertainty, collect it with the data, and get a posterior distribution and make intuitive statements.

+

+

Frequentest confidence intervals have the interpretation that "If you were to repeat many times the process of collecting data and computing a 95% confidence interval, then on average about 95% of those intervals would contain the true parameter value; however, once you observe data and compute an interval the true value is either in the interval or it is not, but you can't tell which."

+

Bayesian credible intervals have the interpretation that "Your posterior probability that the parameter is in a 95% credible interval is 95%."

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2FBayesianStatistics%2Fweek3.html b/static/~brozek/index.html?courses%2FBayesianStatistics%2Fweek3.html new file mode 100644 index 0000000..fa3e2e5 --- /dev/null +++ b/static/~brozek/index.html?courses%2FBayesianStatistics%2Fweek3.html @@ -0,0 +1,360 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

How do we choose a prior?

+

Our prior needs to represent our personal perspective, beliefs, and our uncertainties.

+

Theoretically, we're defining a cumulative distribution function for the parameter +$$ +\begin{cases} +P(\theta \le c) & c \in \mathbb{R} +\end{cases} +$$ +This is true for an infinite number of possible sets. This isn't practical to do, and it would be very difficult to do coherently so that all the probabilities were consistent.

+

In practice, we work with a convenient family that's sufficiently flexible such that a member of a family represents our beliefs.

+

Generally if one has enough data, the information in the data will overwhealm the information in the prior. And so, the prior is not particularly important in terms of what you get for the posterior. Any reasonable choice of prior will lead to approximately the same posterior. However, there are some things that can go wrong.

+

Example of Bad Prior

+

Suppose we chose a prior that says the probability of $P(\theta = \frac{1}{2}) = 1$

+

And thus, the probability of $\theta$ equaling any other value is $0$. If we do this, our data won't make a difference since we only put a probability of $1$ at a single point. +$$ +f(\theta|y) \propto f(y|\theta)f(\theta) = f(\theta) = \delta(\theta) +$$

+

In the basic context, events with prior probability of zero have a posterior probability of zero. Events with a prior probability of one, have a posterior probability of one.

+

Thus a good Bayesian will not assign probability of zero or one to any event that has already occurred or already known not to occur.

+

Calibration

+

A useful concept in terms of choosing priors is that of the calibration of predictive intervals.

+

If we make an interval where we're saying we predict 95% of new data points will occur in this interval. It would be good if in reality 95% of new data points actually did fall in that interval.

+

How do we calibrate to reality? This is actually a frequentest concept but this is important for practical statistical purposes that our results reflect reality.

+

We can compute a predictive interval, this is an interval such that 95% of new observations are expected to fall into it. It's an interval for the data rather than an interval for $\theta$ +$$ +f(y) = \int{f(y|\theta)f(\theta)d\theta} = \int{f(y, \theta)d\theta} +$$ +Where $f(y,\theta)$ is the joint density of Y and $\theta$.

+

This is the prior predictive before any data is observed.

+

Side Note: From this you can say that $f(y, \theta) = f(y|\theta)f(\theta)$

+

Binomial Example

+

Suppose we're going to flip a coin ten times and count the number of heads we see. We're thinking about this in advance of actually doing it, so we're interested in the predictive distribution. How many heads do we predict we're going to see? +$$ +X = \sum_{i = 1}^{10}{Y_i} +$$ +Where $Y_i$ is each individual coin flip.

+

If we think that all possible coins or all possible probabilities are equally likely, then we can put a prior for $\theta$ that's flat over the interval from 0 to 1. +$$ +f(\theta) = I_{{0 \le \theta \le 1}} +$$

+

$$ +f(x) = \int{f(x|\theta)f(\theta)d\theta} = \int_0^1{\frac{10!}{x!(10-x)!}\theta^x(1-\theta)^{10 -x}(1)d\theta} +$$

+

Note that because we're interested in $X$ at the end, it's important that we distinguish between a binomial density and a Bernoulli density. Here we just care about the total count rather than the exact ordering which would be Bernoulli's

+

For most of the analyses we're doing, where we're interested in $\theta$ rather than x, the binomial and the Bernoulli are interchangeable because the part in here that depends on $\theta$ is the same.

+

To solve this integral let us recall some facts +$$ +n! = \Gamma(n + 1) +$$

+

$$ +Z \sim Beta(\alpha, \beta) +$$

+

$$ +f(z) = \frac{\Gamma(\alpha + \beta)}{\Gamma(\alpha) \Gamma(\beta)}z^{\alpha - 1}(1-z)^{\beta - 1} +$$

+

Let us rewrite $f(x)$ +$$ +f(x) = \int_0^1{\frac{\Gamma(11)}{\Gamma(x + 1)\Gamma(11 - x)}\theta^{(x + 1)-1}(1-\theta)^{(11-x)-1}d\theta} +$$

+

$$ +f(x) = \frac{\Gamma(11)}{\Gamma(12)}\int_0^1{\frac{\Gamma(12)}{\Gamma(x + 1)\Gamma(11 - x)}\theta^{(x + 1)-1}(1-\theta)^{(11-x)-1}d\theta} +$$

+

The integral above is a beta density, all integrals of valid beta densities equals to one. +$$ +f(x) = \frac{\Gamma(11)}{\Gamma(12)} = \frac{10!}{11!} = \frac{1}{11} +$$ +For $x \in {0, 1, 2, \dots, 10}$

+

Thus we see that if we start with a uniform prior, we then end up with a discrete uniform predictive density for $X$. If all possible probabilities are equally likely, then all possible $X$ outcomes are equally likely.

+

Posterior Predictive Distribution

+

What about after we've observed data? What's our posterior predictive distribution?

+

Going from the previous example, let us observe after one flip that we got a head. We want to ask, what's our predictive distribution for the second flip, given we saw a head on the first flip. +$$ +f(y_2|y_1) = \int{f(y_2|\theta,y_1)f(\theta|y_1)}d\theta +$$ +We're going to assume that $Y_2$ is independent of $Y_1$. Therefore, +$$ +f(y_2 |y_1) = \int{f(y_2|\theta)f(\theta|y_1)d\theta} +$$ +Suppose we're thinking of a uniform distribution for $\theta$ and we observe the first flip is a heads. What do we predict for the second flip?

+

This is no longer going to be a uniform distribution like it was before, because we have some data. We're going to think it's more likely that we're going to get a second head. We think this because since we observed a head $\theta$ is now likely to be at least $\frac{1}{2}$ possibly larger. +$$ +f(y_2 | Y_1 = 1) = \int_0^1{\theta^{y_2}(1-\theta)^{1-y_2}2\theta d\theta} +$$

+

$$ +f(y_2|Y_1 = 1) = \int_0^1{2\theta^{y_2 + 1}(1-\theta)^{1-y_2}d\theta} +$$

+

We could work this out in a more general form, but in this case, $Y_2$ has to take the value $0$ or $1$. The next flip is either going to be heads or tails so it's easier to just plop in a particular example. +$$ +P(Y_2 = 1|Y_1 = 1) = \int_0^1{2\theta^2d\theta} = \frac{2}{3} +$$

+

$$ +P(Y_2 = 0 | Y_1 = 1) = 1 - P(Y_2 = 1 | Y_1 = 1) = 1 - \frac{2}{3} = \frac{1}{3} +$$

+

We can see here that the posterior is a combination of the information in the prior and the information in the data. In this case, our prior is like having two data points, one head and one tail.

+

Saying we have a uniform prior for $\theta$ is equivalent in an information sense as saying we have observed one head and one tail.

+

So then when we observe one head, it's like we now have seen two heads and one tail. So our predictive distribution for the second flip says if we have two heads and one tail, then we have a $\frac{2}{3}$ probability of getting another head and a $\frac{1}{3}$ probability of getting another tail.

+

Binomial Likelihood with Uniform Prior

+

Likelihood of y given theta is +$$ +f(y|\theta) = \theta^{\sum{y_i}}(1-\theta)^{n - \sum{y_i}} +$$

+

Our prior for theta is just a uniform distribution +$$ +f(\theta) = I_{{0 \le \theta \le 1}} +$$ +Thus our posterior for $\theta$ is +$$ +f(\theta | y) = \frac{f(y|\theta)f(\theta)}{\int{f(y|\theta)f(\theta)d\theta}} = \frac{\theta^{\sum{y_i}}(1-\theta)^{n - \sum{yi}} I{{0 \le \theta \le 1}}}{\int_0^1{\theta^{\sum{y_i}}(1-\theta)^{n - \sum{yi}} I{{0 \le \theta \le 1}}d\theta}} +$$ +Recalling the form of the beta distribution we can rewrite our posterior as +$$ +f(\theta | y) = \frac{\theta^{\sum{y_i}}(1-\theta)^{n - \sum{yi}} I{{0 \le \theta \le 1}}}{\frac{\Gamma(\sum{y_i} + 1)\Gamma(n - \sum{y_i} + 1)}{\Gamma(n + 2)}\int_0^1{\frac{\Gamma(n + 2)}{\Gamma(\sum{y_i} + 1)\Gamma(n - \sum{y_i} + 1)}\theta^{\sum{y_i}}(1-\theta)^{n - \sum{y_i}}d\theta}} +$$ +Since the beta density integrates to $1$, we can simplify this as +$$ +f(\theta | y) = \frac{\Gamma(n + 2)}{\Gamma(\sum{y_i}+ 1)\Gamma(n - \sum{y_i}+ 1)}\theta^{\sum{y_i}}(1-\theta)^{n-\sum{yi}}I{{0 \le \theta \le 1}} +$$ +From here we can see that the posterior follows a beta distribution +$$ +\theta | y \sim Beta(\sum{y_i} + 1, n - \sum{y_i} + 1) +$$

+

Conjugate Priors

+

The uniform distribution is $Beta(1, 1)$

+

Any beta distribution is conjugate for the Bernoulli distribution. Any beta prior will give a beta posterior. +$$ +f(\theta) = \frac{\Gamma(\alpha + \beta)}{\Gamma(\alpha)\Gamma(\beta)}\theta^{\alpha - 1}(1-\theta)^{\beta -1}I_{{0 \le \theta \le 1}} +$$

+

$$ +f(\theta | y) \propto f(y|\theta)f(\theta) = \theta^{\sum{y_i}}(1-\theta)^{n - \sum{yi}}\frac{\Gamma(\alpha + \beta)}{\Gamma(\alpha)\Gamma(\beta)}\theta^{\alpha - 1}(1 - \theta)^{\beta - 1}I{{0 \le \theta \le 1}} +$$

+

$$ +f(y|\theta)f(\theta) \propto \theta^{\alpha + \sum{y_i}-1}(1-\theta)^{\beta + n - \sum{y_i} - 1} +$$

+

Thus we see that this is a beta distribution +$$ +\theta | y \sim Beta(\alpha + \sum{y_i}, \beta + n - \sum{y_i}) +$$ +When $\alpha$ and $\beta$ is one like in the uniform distribution, then we get the same result as earlier.

+

This whole process where we choose a particular form of prior that works with a likelihood is called using a conjugate family.

+

A family of distributions is referred to as conjugate if when you use a member of that family as a prior, you get another member of that family as your posterior.

+

The beta distribution is conjugate for the Bernoulli distribution. It's also conjugate for the binomial distribution. The only difference in the binomial likelihood is that there is a combinatoric term. Since that does not depend on $\theta$, we get the same posterior.

+

We often use conjugate priors because they make life much more simpler, sticking to conjugate families allows us to get closed form solutions easily.

+

If the family is flexible enough, then you can find a member of that family that closely represents your beliefs.

+

Posterior Mean and Effect Size

+

Returning to the beta posterior model it is clear how both the prior and the data contribute to the posterior.

+

We can say that the effect size of the prior is $\alpha + \beta$

+

Recall that the expected value or mean of a beta distribution is $\frac{\alpha}{\alpha + \beta}$

+

Therefore we can derive the posterior mean as +$$ +posterior_{mean} = \frac{\alpha + \sum{y_i}}{\alpha + \sum{y_i}+\beta + n - \sum{y_i}}= \frac{\alpha+\sum{yi}}{\alpha + \beta + n} +$$ +We can further decompose this as +$$ +posterior{mean} = \frac{\alpha + \beta}{\alpha + \beta + n}\frac{\alpha}{\alpha + \beta} + \frac{n}{\alpha + \beta + n}\frac{\sum{y_i}}{n} +$$ +We can describe this as the (prior weight prior mean) + (data weight data mean)

+

The posterior mean is a weighted average of the prior mean and the data mean.

+

This effective sample size gives you an idea of how much data you would need to make sure that your prior doesn't have much influence on your posterior.

+

If $\alpha + \beta$ is small compared to $n$ then the posterior will largely just be driven by the data. If $\alpha + \beta$ is large relative to $n$ then the posterior will be largely driven by the prior.

+

We can make a 95% credible interval using our posterior distribution for $\theta$. We can find an interval that actually has 95% probability of containing $\theta$.

+

Using Bayesian Statistics we can chain together dong a sequential update every time we get new data. We can get a new posterior, and we just use our previous posterior as a prior to do another update using Baye's theorem.

+

Data Analysis Example in R

+

Suppose we're giving two students a multiple-choice exam with 40 questions, where each question has four choices. We don't know how much the students have studied for this exam, but we think that they'll do better than just guessing randomly

+

1) What are the parameters of interest?

+

The parameters of interests are $\theta_1 = true$ the probability that the first student will answer a question correctly, $\theta_2 = true$ the probability that the second student will answer a question correctly.

+

2) What is our likelihood?

+

The likelihood is $Binomial(40, \theta)$, if we assume that each question is independent and that the probability a student gets each question right is the same for all questions for that student.

+

3) What prior should we use?

+

The conjugate prior is a beta prior. We can plot the density with dbeta

+
theta = seq(from = 0, to = 1, by = 0.1)
+# Uniform
+plot(theta, dbeta(theta, 1, 1), type = 'l')
+# Prior mean 2/3
+plot(theta, dbeta(theta, 4, 2), type = 'l')
+# Prior mean 2/3 but higher effect size (more concentrated at mean)
+plot(theta, dbeta(theta, 8, 4), type = 'l')
+

4 ) What are the prior probabilities $P(\theta > 0.25)$? $P(\theta > 0.5)$? $P(\theta > 0.8)$?

+
1 - pbeta(0.25, 8, 4)
+#[1] 0.998117
+1 - pbeta(0.5, 8, 4)
+#[1] 0.8867188
+1 - pbeta(0.8, 8, 4)
+#[1] 0.16113392
+

5) Suppose the first student gets 33 questions right. What is the posterior distribution for $\theta_1$? $P(\theta > 0.25)$? $P(\theta > 0.5)$? $P(\theta > 0.8)$? What is the 95% posterior credible interval for $\theta_1$? +$$ +Posterior \sim Beta(8 + 33, 4 + 40 - 33) = Beta(41, 11) +$$ +With a posterior mean of $\frac{41}{41+11} = \frac{41}{52}$

+

We can plot the posterior distribution with the prior

+
plot(theta, dbeta(theta, 41, 11), type = 'l')
+lines(theta, dbeta(theta, 8 ,4), lty = 2) #Dashed line for prior
+

Posterior probabilities

+
1 - pbeta(0.25, 41, 11)
+#[1] 1
+1 - pbeta(0.5, 41, 11)
+#[1] 0.9999926
+1 - pbeta(0.8, 41, 11)
+#[1] 0.4444044
+

Equal tailed 95% credible interval

+
qbeta(0.025, 41, 11)
+#[1] 0.6688426
+qbeta(0.975, 41, 11)
+#[1] 0.8871094
+

95% confidence that $\theta_1$ is between 0.67 and 0.89

+

6) Suppose the second student gets 24 questions right. What is the posterior distribution for $\theta_2$? $P(\theta > 0.25)$? $P(\theta > 0.5)$? $P(\theta > 0.8)$? What is the 95% posterior credible interval for $\theta_2$ +$$ +Posterior \sim Beta(8 + 24, 4 + 40 - 24) = Beta(32, 20) +$$ +With a posterior mean of $\frac{32}{32+20} = \frac{32}{52}$

+

We can plot the posterior distribution with the prior

+
plot(theta, dbeta(theta, 32, 20), type = 'l')
+lines(theta, dbeta(theta, 8 ,4), lty = 2) #Dashed line for prior
+

Posterior probabilities

+
1 - pbeta(0.25, 32, 20)
+#[1] 1
+1 - pbeta(0.5, 32, 20)
+#[1] 0.9540427
+1 - pbeta(0.8, 32, 20)
+#[1] 0.00124819
+

Equal tailed 95% credible interval

+
qbeta(0.025, 32, 20)
+#[1] 0.4808022
+qbeta(0.975, 32, 20)
+#[1] 0.7415564
+

95% confidence that $\theta_1$ is between 0.48 and 0.74

+

7) What is the posterior probability that $\theta_1 > \theta_2$? i.e., that the first student has a better chance of getting a question right than the second student?

+

Estimate by simulation: draw 1,000 samples from each and see how often we observe $\theta_1 > \theta_2$

+
theta1 = rbeta(100000, 41, 11)
+theta2 = rbeta(100000, 32, 20)
+mean(theta1 > theta2)
+#[1] 0.975
+

Poisson Data (Chocolate Chip Cookie Example)

+

In mass produced chocolate chip cookies, they make a large amount of dough. They mix in a large number of chips, mix it up really well and then chunk out individual cookies. In this process, the number of chips per cookie approximately follow a Poisson distribution.

+

If we were to assume that chips have no volume, then this would be exactly a Poisson process and follow exactly a Poisson distribution. In practice, however, chips aren't that big so they follow approximately a Poisson distribution for the number of chips per cookie. +$$ +Y_i \sim Poisson(\lambda) +$$

+

$$ +f(y|\lambda) = \frac{\lambda^{\sum{yi}}e^{-n\lambda}}{\prod{i = 1}^n{y_i!}} +$$

+

This is for $\lambda > 0$

+

What type of prior should we put on $\lambda$? It would be convenient if we could put a conjugate prior. What distribution looks like lambda raised to a power and e raised to a negative power?

+

For this, we're going to use a Gamma prior. +$$ +\lambda \sim \Gamma(\alpha, \beta) +$$

+

$$ +f(\lambda) = \frac{\beta^\alpha}{\Gamma(\alpha)}\lambda^{\alpha - 1}e^{-\beta\lambda} +$$

+

$$ +f(\lambda | y) \propto f(y|\lambda)f(\lambda) \propto \lambda^{\sum{y_i}}e^{-n\lambda}\lambda^{\alpha - 1}e^{-\beta \lambda} +$$

+

$$ +f(\lambda | y) \propto \lambda^{\alpha + \sum{y_i} - 1}e^{-(\beta + n)\lambda} +$$

+

Thus we can see that the posterior is a Gamma Distribution +$$ +\lambda|y \sim \Gamma(\alpha + \sum{y_i}, \beta + n) +$$ +The mean of Gamma under this parameterization is $\frac{\alpha}{\beta}$

+

The posterior mean is going to be +$$ +posterior_{mean} = \frac{\alpha + \sum{y_i}}{\beta + n} = \frac{\beta}{\beta + n}\frac{\alpha}{\beta} + \frac{n}{\beta + n}\frac{\sum{y_i}}{n} +$$ +As you can see here the posterior mean of the Gamma distribution is also the weighted average of the prior mean and the data mean.

+

Let us present two strategies on how to choose our hyper parameters $\alpha$ and $\beta$

+
    +
  1. Think about the prior mean. For example, what do you think the number of chips per cookie on average is?
  2. +
+

After this, we need some other piece of knowledge to pin point both parameters. Here are some options.

+ +
    +
  1. In Bayesian Statistics, a vague prior refers to one that's relatively flat across much of the space. For a Gamma prior we can choose $\Gamma(\epsilon, \epsilon)$ where $\epsilon$ is small and strictly positive.
  2. +
+

This would create a distribution with a mean of 1 and a huge standard deviation across the whole space. Hence the posterior will be largely driven by the data and very little by the prior.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2FBayesianStatistics%2Fweek4.html b/static/~brozek/index.html?courses%2FBayesianStatistics%2Fweek4.html new file mode 100644 index 0000000..7b6ae77 --- /dev/null +++ b/static/~brozek/index.html?courses%2FBayesianStatistics%2Fweek4.html @@ -0,0 +1,495 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Exponential Data

+

Suppose you're waiting for a bus that you think comes on average once every 10 minutes, but you're not sure exactly how often it comes. +$$ +Y \sim Exp(\lambda) +$$ +Your waiting time has a prior expectation of $\frac{1}{\lambda}$

+

It turns out the gamma distribution is conjugate for an exponential likelihood. We need to specify a prior, or a particular gamma in this case. If we think that the buses come on average every ten minutes, that's a rate of one over ten. +$$ +prior_{mean} = \frac{1}{10} +$$ +Thus, we'll want to specify a gamma distribution so that the first parameter divded by the second parameter is $\frac{1}{10}$

+

We can now think about our variability. Perhaps you specify +$$ +\Gamma(100, 1000) +$$ +This will indeed have a prior mean of $\frac{1}{10}$ and it'll have a standard deviation of $\frac{1}{100}$. If you want to have a rough estimate of our mean plus or minus two standard deviations then we have the following +$$ +0.1 \pm 0.02 +$$ +Suppose that we wait for 12 minutes and a bus arrives. Now you want to update your posterior for $\lambda$ about how often this bus will arrive. +$$ +f(\lambda | y) \propto f(y|\lambda)f(\lambda) +$$

+

$$ +f(\lambda | y) \propto \lambda e^{-\lambda y}\lambda^{\alpha - 1}e^{-\beta \lambda} +$$

+

$$ +f(\lambda | y) \propto \lambda^{(\alpha + 1) - 1}e^{-(\beta + y)\lambda} +$$

+

$$ +\lambda | y \sim \Gamma(\alpha + 1, \beta + y) +$$

+

Plugging in our particular prior gives us a posterior for $\lambda$ which is +$$ +\lambda | y \sim \Gamma(101, 1012) +$$ +Thus our posterior mean is going to be $\frac{101}{1012} Which is equal to 0.0998.

+

This one observation doesn't contain a lot of data under this likelihood. When the bus comes and it takes 12 minutes instead of 10, it barely shifts our posterior mean up. One data point doesn't have a big impact here.

+

Normal/Gaussian Data

+

Let's suppose the standard deviation or variance is known and we're only interested in learning about the mean. This is the situation that often arises in monitoring industrial production processes. +$$ +X_i \sim N(\mu, \sigma^2) +$$ +It turns out that the Normal distribution is conjugate for itself when looking for the mean parameter

+

Prior +$$ +\mu \sim N(m_0,S_0^2) +$$

+

$$ +f(\mu |x ) \propto f(x|\mu)f(\mu) +$$

+

$$ +\mu | x \sim N(\frac{n\bar{x}/\sigma_0^2 + m_0/s_0^2}{n/\sigma_0^2 + 1/s_0^2}, \frac{1}{n/\sigma_0^2 + 1/s_0^2}) +$$

+

Let's look at the posterior mean +$$ +posterior_{mean} = \frac{n/\sigma_0^2}{n/\sigma_0^2 + 1/s_0^2}\bar{x} + \frac{1/s_0^2}{n/\sigma_0^2 + 1/s_0^2} +$$

+

$$ +posterior_{mean} = \frac{n}{n + \sigma_0^2/s_0^2}\bar{x} + \frac{\sigma_0^2/s_0^2}{n + \sigma_0^2/s_0^2} +$$

+

Thus we see, that the posterior mean is a weighted average of the prior mean and the data mean. And indeed that the effective sample size for this prior is the ratio of the variance for the data to the variance in the prior.

+

This makes sense, because the larger the variance of the prior, the less information that's in it.

+

The marginal distribution for Y is +$$ +N(m_0, s_0^2 + \sigma^2) +$$

+

When $\mu$ and $\sigma^2$ is unknown

+

$$ +X_i | \mu, \sigma^2 \sim N(\mu, \sigma^2) +$$

+

A prior from $\mu$ conditional on the value for $\sigma^2$ +$$ +\mu | \sigma^2 \sim N(m, \frac{\sigma^2}{w}) +$$ +$w$ is going to be the ratio of $\sigma^2$ and some variance for the Normal distribution. This is the effective sample size of the prior.

+

Finally, the last step is to specify a prior for $\sigma^2$. The conjugate prior here is an inverse gamma distribution with parameters $\alpha$ and $\beta$. +$$ +\sigma^2 \sim \Gamma^{-1}(\alpha, \beta) +$$ +After many calculations... we get the posterior distribution +$$ +\sigma^2 | x \sim \Gamma^{-1}(\alpha + \frac{n}{2}, \beta + \frac{1}{2}\sum_{i = 1}^n{(x-\bar{x}^2 + \frac{nw}{2(n+2)}(\bar{x} - m)^2)}) +$$

+

$$ +\mu | \sigma^2,x \sim N(\frac{n\bar{x}+wm}{n+w}, \frac{\sigma^2}{n + w}) +$$

+

Where the posterior mean can be written as the weighted average of the prior mean and the data mean. +$$ +\frac{n\bar{x}+wm}{n+w} = \frac{w}{n + w}m + \frac{n}{n + w}\bar{x} +$$ +In some cases, we really only care about $\mu$. We want some inference on $\mu$ and we may want it such that it doesn't depend on $\sigma^2$. We can marginalize that $\sigma^2$ integrating it out. The posterior for $\mu$ marginally follows a $t$ distribution. +$$ +\mu | x \sim t +$$ +Similarly the posterior predictive distribution also is a $t$ distribution.

+

Finally, note that we can extend this in various directions, this can be extended to the multivariate normal case that requires matrix vector notations and can be extended in a hierarchial fashion if we want to specify priors for $m$, $w$ and $\beta$

+

Non Informative Priors

+

We've seen examples of choosing priors that contain a significant amount of information. We've also seen some examples of choosing priors where we're attempting to not put too much information in to keep them vague.

+

Another approach is referred to as objective Bayesian statistics or inference where we explicitly try to minimize the amount of information that goes into the prior.

+

This is an attempt to have the data have maximum influence on the posterior

+

Let's go back to coin flipping +$$ +Y_i \sim B(\theta) +$$ +How do we minimize our prior information in $\theta$? One obvious intuitive approach is to say that all values of $\theta$ are equally likely. So we could have a piror for $\theta$ which follows a uniform distribution on the interval $[0, 1]$

+

Saying all values of $\theta$ are equally likely seems like it would have no information in it.

+

Recall however, that a $Uniform(0, 1)$ is the same as $Beta(1, 1)$

+

The effective sample size of a beta prior is the sum of its two parameters. So in this case, it has an effective sample size of 2. This is equivalent to data, with one head and one tail already in it.

+

So this is not a completely non informative prior.

+

We could think about a prior that has less information. For example $Beta(\frac{1}{2}, \frac{1}{2})$, this would have half as much information with an effective sample size of one.

+

We can take this even further. Think about something like $Beta(0.001, 0.001)$ This would have much less information, with the effective sample size fairly close to zero. In this case, the data would determine the posterior and there would be very little influence from the prior.

+

Improper priors

+

Can we go even further? We can think of the limiting case. Let's think of $Beta(0,0)$, what would that look like? +$$ +f(\theta) \propto \theta^{-1}(1-\theta)^{-1} +$$ +This is not a proper density. If you integrate this over $(0,1)$, you'll get an infinite integral, so it's not a true density in the sense of it not integrating to 1.

+

There's no way to normalize it, since it has an infinite integral. This is what we refer to as an improper prior.

+

It's improper in the sense that it doesn't have a proper density. But it's not necessarily imporper in the sense that we can't use it. If we collect data, we use this prior and as long as we observe one head and one tail, or at least one success and one failure. Then we can get a posterior +$$ +f(\theta|y) \propto \theta^{y-1}(1-\theta)^{n-y-1} \sim Beta(y, n-y) +$$ +With a posterior mean of $\frac{y}{n} =\hat{\theta}$, which you should recognize as the maximum likelihood estimate. So by using this improper prior, we get a posterior which gives us point estimates exactly the same as the frequentest approach.

+

But in this case, we can also think of having a full posterior. From this, we can make interval statements, probability statements, and we can actually find an interval and say that there's 95% probability that $\theta$ is in this interval. Which is not something you can do under the frequentest approach even though we may get the same exact interval.

+

Statements about improper priors

+

Improper priors are okay as long as the posterior itself is proper. There may be some mathematical things that need to be checked and you may need to have certain restrictions on the data. In this case, we needed to make sure that we observed at least one head and one tail to get a proper posterior.

+

But as long as the posterior is proper, we can go forwards and do Bayesian inference even with an improper prior.

+

The second point is that for many problems there does exist a prior, typically an improper prior that will lead to the same point estimates as you would get under the frequentest paradigm. So we can get very similar results, results that are fully dependent on the data, under the Bayesian approach.

+

But in this case, we can also have continue to have a posterior and make posterior interval estimates and talk about posterior probabilities of the parameter.

+

Normal Case

+

Another example is thinking about the normal case. +$$ +Y_i \stackrel{iid}\sim N(\mu, \sigma^2) +$$ +Let's start off by assuming that $\sigma^2$ is known and we'll just focus on the mean $\mu$.

+

We can think about a vague prior like before and say that +$$ +\mu \sim N(0, 1000000^2) +$$ +This would just spread things out across the real line. That would be a fairly non informative prior covering a lot of possibilities. We can then think about taking the limit, what happens if we let the variance go to $\infty$. In that case, we're basically spreading out this distribution across the entire real number line. We can say that the density is just a constant across the whole real line. +$$ +f(\mu) \propto 1 +$$ +This is an improper prior because if you integrate the real line you get an infinite answer. However, if we go ahead and find the posterior +$$ +f(\mu|y) \propto f(y|\mu)f(\mu) \propto exp(-\frac{1}{2\sigma^2}\sum{(y_i - \mu)^2})(1) +$$

+

$$ +f(\mu | y) \propto exp(-\frac{1}{2\sigma^2/n}(\mu - \bar{y})^2) +$$

+

$$ +\mu | y \sim N(\bar{y}, \frac{\sigma^2}{n}) +$$

+

This should look just like the maximum likelihood estimate.

+

Unknown Variance

+

In the case that $\sigma^2$ is unknown, the standard non informative prior is +$$ +f(\sigma^2) \propto \frac{1}{\sigma^2} +$$

+

$$ +\sigma^2 \sim \Gamma^{-1}(0,0) +$$

+

This is an improper prior and it's uniform on the log scale of $\sigma^2$.

+

In this case, we'll end up with a posterior for $\sigma^2$ +$$ +\sigma^2|y \sim \Gamma^{-1}(\frac{n-1}{2}, \frac{1}{2}\sum{(y_i - \bar{y})^2}) +$$ +This should also look reminiscent of quantities we get as a frequentest. For example, the samples standard deviation

+

Jeffreys Prior

+

Choosing a uniform prior depends upon the particular parameterization.

+

Suppose I used a prior which is uniform on the log scale for $\sigma^2$ +$$ +f(\sigma^2) \propto \frac{1}{\sigma^2} +$$ +Suppose somebody else decides, that they just want to put a uniform prior on $\sigma^2$ itself. +$$ +f(\sigma^2) \propto 1 +$$ +These are both uniform on certain scales or certain parameterizations, but they are different priors. So when we compute the posteriors, they will be different as well.

+

The key thing is that uniform priors are not invariant with respect to transformation. Depending on how you parameterize the problem, you can get different answers by using a uniform prior

+

One attempt to round this out is to use Jeffrey's Prior

+

Jeffrey's Prior is defined as the following +$$ +f(\theta) \propto \sqrt{\mathcal{I(\theta)}} +$$ +Where $\mathcal{I}(\theta)$ is the fisher information of $\theta$. In most cases, this will be an improper prior.

+

Normal Data

+

For the example of Normal Data +$$ +Y_i \sim N(\mu, \sigma^2) +$$

+

$$ +f(\mu) \propto 1 +$$

+

$$ +f(\sigma^2) \propto \frac{1}{\sigma^2} +$$

+

Where $\mu$ is uniform and $\sigma^2$ is uniform on the log scale.

+

This prior will then be transformation invariant. We will end up putting the same information into the prior even if we use a different parameterization for the Normal.

+

Binomial

+

$$ +Y_i \sim B(\theta) +$$

+

$$ +f(\theta) \propto \theta^{-\frac{1}{2}}(1-\theta)^{-\frac{1}{2}} \sim Beta(\frac{1}{2},\frac{1}{2}) +$$

+

This is a rare example of where the Jeffreys prior turns out to be a proper prior.

+

You'll note that this prior actually does have some information in it. It's equivalent to an effective sample size of one data point. However, this information will be the same, not depending on the parameterization we use.

+

In this case, we have $\theta$ as a probability, but another alternative which is sometimes used is when we model things on a logistics scale.

+

By using the Jeffreys prior, we'll maintain the exact same information.

+

Closing information about priors

+

Other possible approaches to objective Bayesian inference includes priors such as reference priors and maximum entropy priors.

+

A related concept to this is called empirical Bayesian analysis. The idea in empirical Baye's is that you use the data to help inform your prior; such as by using the mean of the data to set the mean of the prior distribution. This approach often leads to reasonable point estimates in your posterior. However, it's sort of cheating since you're using your data twice and as a result may lead to improper uncertainty estimates.

+

Fisher Information

+

The Fisher information (for one parameter) is defined as +$$ +\mathcal{I}(\theta) = E[(\frac{d}{d\theta}log{(f(X|\theta))})^2] +$$ +Where the expectation is taken with respect to $X$ which has PDF $f(x|\theta)$. This quantity is useful in obtaining estimators for $\theta$ with good properties, such as low variance. It is also the basis for Jeffreys prior.

+

Example: Let $X | \theta \sim N(\theta, 1)$. Then we have +$$ +f(x|\theta) = \frac{1}{\sqrt{2\pi}}exp[-\frac{1}{2}(x-\theta)^2] +$$

+

$$ +\log{(f(x|\theta))} = -\frac{1}{2}\log{(2\pi)}-\frac{1}{2}(x-\theta)^2 +$$

+

$$ +(\frac{d}{d\theta}log{(f(x|\theta))})^2 = (x-\theta)^2 +$$

+

and so $\mathcal{I}(\theta) = E[(X - \theta)^2] = Var(X) = 1$

+

Linear Regression

+

Brief Review of Regression

+

Recall that linear regression is a model for predicting a response or dependent variable ($Y$, also called an output) from one or more covariates or independent variables ($X$, also called explanatory variables, inputs, or features). For a given value of a single $x$, the expected value of $y$ is +$$ +E[y] = \beta_0 + \beta_1x +$$ +or we could say that $Y \sim N(\beta_0 + \beta_1x, \sigma^2)$. For data $(x_1, y_1), \dots , (x_n, y_n)$, the fitted values for the coefficients, $\hat{\beta_0}$ and $\hat{\beta1}$ are those that minimize the sum of squared errors $\sum{i = 1}^n{(y_i - \hat{y_i})^2}$, where the predicted values for the response are $\hat{y} = \hat{\beta_0} + \hat{\beta_1}x$. We can get these values from R. These fitted coefficients give the least-squares line for the data.

+

This model extends to multiple covariates, with one $\beta_j$ for each $k$ covariates +$$ +E[y_i] = \beta_0 + \beta1x{i1} + \dots + \betakx{ik} +$$ +Optionally, we can represent the multivariate case using vector-matrix notation.

+

Conjugate Modeling

+

In the Bayesian framework, we treat the $\beta$ parameters as unknown, put a prior on them, and then find the posterior. We might treat $\sigma^2$ as fixed and known, or we might treat it as an unknown and also put a prior on it. Because the underlying assumption of a regression model is that the errors are independent and identically normally distributed with mean $0$ and variance $\sigma^2$, this defines a normal likelihood.

+

$\sigma^2$ known

+

Sometimes we may know the value of the error variance $\sigma^2$. This simplifies calculations. The conjugate prior for the $\beta$'s is a normal prior. In practice, people typically use a non-informative prior, i.e., the limit as the variance of the normal prior goes to infinity, which has the same mean as the standard least-squares estimates. If we are only estimating $\beta$ and treating $\sigma^2$ as known, then the posterior for $\beta$ is a (multivariate) normal distribution. If we just have a single covariate, then the posterior for the slope is +$$ +\beta1 | y \sim N(\frac{\sum{i = 1}^n{(x_i-\bar{x})(yi - \bar{y})}}{\sum{i=1}^n{(xi-\bar{x})^2}}, \frac{\sigma^2}{\sum{i=1}^n{(x_i - \bar{x})^2}}) +$$ +If we have multiple covariates, then using a matrix-vector notation, the posterior for the vector of coefficients is +$$ +\beta | y \sim N((X^tX)^{-1}X^ty, (X^tX)^{-1}\sigma^2) +$$ +where $X$ denotes the design matrix and $X^t$ is the transpose of $X$. The intercept is typically included in $X$ as a column of $1$'s. Using an improper prior requires us to have at least as many data points as we have parameters to ensure that the posterior is proper.

+

$\sigma^2$ Unknown

+

If we treat both $\beta$ and $\sigma^2$ as unknown, the standard prior is the non-informative Jeffreys prior, $f(\beta, \sigma^2) \propto \frac{1}{\sigma^2}$. Again, the posterior mean for $\beta$ will be the same as the standard least-squares estimates. The posterior for $\beta$ conditional on $\sigma^2$ is the same normal distributions as when $\sigma^2$ is known, but the marginal posterior distribution for $\beta$, with $\sigma^2$ integrated out is a $t$ distribution, analogous to the $t$ tests for significance in standard linear regression. The posterior $t$ distribution has mean $(X^tX)^{-1}X^ty$ and scale matrix (related to the variance matrix) $s^2(X^tX)^{-1}$, where $s^2 = \sum_{i = 1}^n{(y_i - \hat{yi})^2/(n - k - 1)}$. The posterior distribution for $\sigma^2$ is an inverse gamma distribution +$$ +\sigma^2 | y \sim \Gamma^{-1}(\frac{n - k - 1}{2}, \frac{n - k - 1}{2}s^2) +$$ +In the simple linear regression case (single variable), the marginal posterior for $\beta$ is a $t$ distribution with mean $\frac{\sum{i = 1}^n{(x_i-\bar{x})(yi - \bar{y})}}{\sum{i=1}^n{(xi-\bar{x})^2}}$ and scale $ \frac{s^2}{\sum{i=1}^n{(x_i - \bar{x})^2}}$. If we are trying to predict a new observation at a specified input $x^$, that predicted value has a marginal posterior predictive distribution that is a $t$ distribution, with mean $\hat{y} = \hat{\beta_0} + \hat{\beta_1}x^$ and scale $se_r\sqrt{1 + \frac{1}{n} + \frac{(x^* - \bar{x})^2}{(n - 1)s_x^2}}$. $se_r$ is the residual standard error of the regression, which can be found easily in R. $s_x^2$ is the sample variance of $x$. Recall that the predictive distribution for a new observation has more variability than the posterior distribution for $\hat{y}$ , because individual observations are more variable than the mean.

+

Linear Regression

+

Single Variable Regression

+

We'll be looking at the Challenger dataset. It contains 23 past launches where it has the temperature at the day of launch and the O-ring damage index

+

http://www.randomservices.org/random/data/Challenger2.txt +Read in the data

+
oring=read.table("http://www.randomservices.org/random/data/Challenger2.txt",
+                 header=T)
+# Note that attaching this masks T which is originally TRUE
+attach(oring)
+

Now we'll see the plot

+
plot(T, I)
+

Challenger

+

Fit a linear model

+
oring.lm=lm(I~T)
+summary(oring.lm)
+

Output of the summary

+
Call:
+lm(formula = I ~ T)
+
+Residuals:
+    Min      1Q  Median      3Q     Max 
+-2.3025 -1.4507 -0.4928  0.7397  5.5337 
+
+Coefficients:
+            Estimate Std. Error t value Pr(>|t|)
+(Intercept) 18.36508    4.43859   4.138 0.000468
+T           -0.24337    0.06349  -3.833 0.000968
+
+(Intercept) ***
+T           ***
+---
+Signif. codes:  
+0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
+
+Residual standard error: 2.102 on 21 degrees of freedom
+Multiple R-squared:  0.4116,    Adjusted R-squared:  0.3836 
+F-statistic: 14.69 on 1 and 21 DF,  p-value: 0.0009677
+

Add the fitted line into the scatterplot

+
lines(T,fitted(oring.lm))     
+

challengerfitted

+

Create a 95% posterior interval for the slope

+
-0.24337 - 0.06349*qt(.975,21)
+# [1] -0.3754047
+-0.24337 + 0.06349*qt(.975,21)
+# [1] -0.1113353
+

Note: These are the same as the frequentest confidence intervals

+

If the challenger launch was at 31 degrees Fahrenheit, how much O-Ring damage would we predict?

+
coef(oring.lm)[1] + coef(oring.lm)[2]*31  
+# [1] 10.82052 
+

Let's make our posterior prediction interval

+
predict(oring.lm,data.frame(T=31),interval="predict")
+

Output of predict

+
       fit      lwr      upr
+1 10.82052 4.048269 17.59276
+

We can calculate the lower bound through the following formula

+
10.82052-2.102*qt(.975,21)*sqrt(1+1/23+((31-mean(T))^2/22/var(T)))
+

What's the posterior probability that the damage index is greater than zero?

+
1-pt((0-10.82052)/(2.102*sqrt(1+1/23+((31-mean(T))^2/22/var(T)))),21)
+

Multivariate Regression

+

We're looking at Galton's seminal data predicting the height of children from the height of the parents

+

http://www.randomservices.org/random/data/Galton.txt +Read in the data

+
heights=read.table("http://www.randomservices.org/random/data/Galton.txt",
+                   header=T)
+attach(heights)
+

What are the columns in the dataset?

+
names(heights)
+# [1] "Family" "Father" "Mother" "Gender" "Height" "Kids"  
+

Let's look at the relationship between the different variables

+
pairs(heights)
+

heightpairs

+

First let's start by creating a linear model taking all of the columns into account

+
summary(lm(Height~Father+Mother+Gender+Kids))
+

Output of summary

+
Call:
+lm(formula = Height ~ Father + Mother + Gender + Kids)
+
+Residuals:
+    Min      1Q  Median      3Q     Max 
+-9.4748 -1.4500  0.0889  1.4716  9.1656 
+
+Coefficients:
+            Estimate Std. Error t value Pr(>|t|)
+(Intercept) 16.18771    2.79387   5.794 9.52e-09
+Father       0.39831    0.02957  13.472  < 2e-16
+Mother       0.32096    0.03126  10.269  < 2e-16
+GenderM      5.20995    0.14422  36.125  < 2e-16
+Kids        -0.04382    0.02718  -1.612    0.107
+
+(Intercept) ***
+Father      ***
+Mother      ***
+GenderM     ***
+Kids           
+---
+Signif. codes:  
+0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
+
+Residual standard error: 2.152 on 893 degrees of freedom
+Multiple R-squared:  0.6407,    Adjusted R-squared:  0.6391 
+F-statistic: 398.1 on 4 and 893 DF,  p-value: < 2.2e-16
+

As you can see here, the Kids column is not significant. Let's look at a model with it removed.

+
summary(lm(Height~Father+Mother+Gender))
+

Output of summary

+
Call:
+lm(formula = Height ~ Father + Mother + Gender)
+
+Residuals:
+   Min     1Q Median     3Q    Max 
+-9.523 -1.440  0.117  1.473  9.114 
+
+Coefficients:
+            Estimate Std. Error t value Pr(>|t|)
+(Intercept) 15.34476    2.74696   5.586 3.08e-08
+Father       0.40598    0.02921  13.900  < 2e-16
+Mother       0.32150    0.03128  10.277  < 2e-16
+GenderM      5.22595    0.14401  36.289  < 2e-16
+
+(Intercept) ***
+Father      ***
+Mother      ***
+GenderM     ***
+---
+Signif. codes:  
+0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
+
+Residual standard error: 2.154 on 894 degrees of freedom
+Multiple R-squared:  0.6397,    Adjusted R-squared:  0.6385 
+F-statistic:   529 on 3 and 894 DF,  p-value: < 2.2e-16
+

This model looks good, let's go ahead and save it to a variable

+
heights.lm=lm(Height~Father+Mother+Gender)
+

From this we can tell that for each extra inch of height in a father is correlated with an extra 0.4 inches extra to the height of a child.

+

We can also tell that each extra inch of height in a mother is correlated with an extra 0.3 inches extra to the height of the child.

+

A male child is on average 5.2 inches taller than a female child.

+

Let's create a 95% posterior interval for the difference in height by gender

+
5.226 - 0.144*qt(.975,894)
+# [1] 4.943383 
+5.226 + 0.144*qt(.975,894)
+# [1] 5.508617
+

Let's make a posterior prediction interval for a male and female with a father whose 68 inches and a mother whose 64 inches.

+
predict(heights.lm,data.frame(Father=68,Mother=64,Gender="M"),
+        interval="predict")
+
+#       fit      lwr     upr
+# 1 68.75291 64.51971 72.9861
+
predict(heights.lm,data.frame(Father=68,Mother=64,Gender="F"),
+        interval="predict")
+
+#       fit      lwr      upr
+# 1 63.52695 59.29329 67.76062
+

What's next?

+

This concludes this course, if you want to go further with Bayesian statistics, the next topics to explore would be hierarchal modeling and fitting of non conjugate models with Markov Chain Monte Carlo or MCMC.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2FBayesianStatistics.html b/static/~brozek/index.html?courses%2FBayesianStatistics.html new file mode 100644 index 0000000..fc287cc --- /dev/null +++ b/static/~brozek/index.html?courses%2FBayesianStatistics.html @@ -0,0 +1,89 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Bayesian Statistics: From Concept to Data Analysis

+

In the Winter of 2017, I took a course on Bayesian Statistics on Coursera offered by Dr. Herbert Lee.

+

Below are the notes for each of the four weeks.

+

Week 1

+

Week 2

+

Week 3

+

Week 4

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2FReproducibleResearch%2Fweek1.html b/static/~brozek/index.html?courses%2FReproducibleResearch%2Fweek1.html new file mode 100644 index 0000000..1c04293 --- /dev/null +++ b/static/~brozek/index.html?courses%2FReproducibleResearch%2Fweek1.html @@ -0,0 +1,337 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Reproducible Research Week 1

+

Replication

+

The ultimate standard for strengthening scientific evidence is replication of finding and conducting studies with independent

+ +

Replication is particularly important in studies that can impact broad policy or regulatory decisions

+

What's wrong with replication?

+

Some studies cannot be replicated

+ +

Reproducible Research: Make analytic data and code available so that others may reproduce findings

+

Reproducibility bridges the gap between replication which is awesome and doing nothing.

+

Why do we need reproducible research?

+

New technologies increasing data collection throughput; data are more complex and extremely high dimensional

+

Existing databases can be merged into new "megadatabases"

+

Computing power is greatly increased, allowing more sophisticated analyses

+

For every field "X" there is a field "Computational X"

+

Research Pipeline

+

Measured Data -> Analytic Data -> Computational Results -> Figures/Tables/Numeric Summaries -> Articles -> Text

+

Data/Metadata used to develop test should be made publically available

+

The computer code and fully specified computational procedures used for development of the candidate omics-based test should be made sustainably available

+

"Ideally, the computer code that is released will encompass all of the steps of computational analysis, including all data preprocessing steps. All aspects of the analysis needs to be transparently reported" -- IOM Report

+

What do we need for reproducible research?

+ +

Who is the audience for reproducible research?

+

Authors:

+ +

Readers:

+ +

Challenges for reproducible research

+ +

What happens in reality

+

Authors:

+ +

Readers:

+ +

Literate (Statistical) Programming

+

An article is a stream of text and code

+

Analysis code is divided into text and code "chunks"

+

Each code chunk loads data and computes results

+

Presentation code formats results (tables, figures, etc.)

+

Article text explains what is going on

+

Literate programs can be weaved to produce human-readable documents and tagled to produce machine-readable documents

+

Literate programming is a general concept that requires

+
    +
  1. A documentation language (human readable)
  2. +
  3. A programming language (machine readable)
  4. +
+

Knitr is an R package that brings a variety of documentation languages such as Latex, Markdown, and HTML

+

Quick summary so far

+

Reproducible research is important as a minimum standard, particularly for studies that are difficult to replicate

+

Infrastructure is needed for creating and distributing reproducible document, beyond what is currently available

+

There is a growing number of tools for creating reproducible documents

+

Golden Rule of Reproducibility: Script Everything

+

Steps in a Data Analysis

+
    +
  1. Define the question
  2. +
  3. Define the ideal data set
  4. +
  5. Determine what data you can access
  6. +
  7. Obtain the data
  8. +
  9. Clean the data
  10. +
  11. Exploratory data analysis
  12. +
  13. Statistical prediction/modeling
  14. +
  15. Interpret results
  16. +
  17. Challenge results
  18. +
  19. Synthesize/write up results
  20. +
  21. Create reproducible code
  22. +
+

"Ask yourselves, what problem have you solved, ever, that was worth solving, where you knew all of the given information in advance? Where you didn't have a surplus of information and have to filter it out, or you had insufficient information and have to go find some?" -- Dan Myer

+

Defining a question is the kind of most powerful dimension reduction tool you can ever employ.

+

An Example for #1

+

Start with a general question

+

Can I automatically detect emails that are SPAM or not?

+

Make it concrete

+

Can I use quantitative characteristics of emails to classify them as SPAM?

+

Define the ideal data set

+

The data set may depend on your goal

+ +

Determine what data you can access

+

Sometimes you can find data free on the web

+

Other times you may need to buy the data

+

Be sure to respect the terms of use

+

If the data don't exist, you may need to generate it yourself.

+

Obtain the data

+

Try to obtain the raw data

+

Be sure to reference the source

+

Polite emails go a long way

+

If you load the data from an Internet source, record the URL and time accessed

+

Clean the data

+

Raw data often needs to be processed

+

If it is pre-processed, make sure you understand how

+

Understand the source of the data (census, sample, convenience sample, etc)

+

May need reformatting, subsampling -- record these steps

+

Determine if the data are good enough -- If not, quit or change data

+

Exploratory Data Analysis

+

Look at summaries of the data

+

Check for missing data

+

-> Why is there missing data?

+

Look for outliers

+

Create exploratory plots

+

Perform exploratory analyses such as clustering

+

If it's hard to see your plots since it's all bunched up, consider taking the log base 10 of an axis

+

plot(log10(trainSpan$capitalAve + 1) ~ trainSpam$type)

+

Statistical prediction/modeling

+

Should be informed by the results of your exploratory analysis

+

Exact methods depend on the question of interest

+

Transformations/processing should be accounted for when necessary

+

Measures of uncertainty should be reported.

+

Interpret Results

+

Use the appropriate language

+ +

Gives an explanation

+

Interpret Coefficients

+

Interpret measures of uncertainty

+

Challenge Results

+

Challenge all steps:

+ +

Challenge measures of uncertainty

+

Challenge choices of terms to include in models

+

Think of potential alternative analyses

+

Synthesize/Write-up Results

+

Lead with the question

+

Summarize the analyses into the story

+

Don't include every analysis, include it

+ +

In the lecture example...

+

Lead with the question

+

​ Can I use quantitative characteristics of the emails to classify them as SPAM?

+

Describe the approach

+

​ Collected data from UCI -> created training/test sets

+

​ Explored Relationships

+

​ Choose logistic model on training set by cross validation

+

​ Applied to test, 78% test set accuracy

+

Interpret results

+

​ Number of dollar signs seem reasonable, e.g. "Make more money with Viagra $ $ $ $"

+

Challenge Results

+

​ 78% isn't that great

+

​ Could use more variables

+

​ Why use logistic regression?

+

Data Analysis Files

+

Data

+ +

Figures

+ +

R Code

+ +

Text

+ +

Raw Data

+

Should be stored in the analysis folder

+

If accessed from the web, include URL, description, and date accessed in README

+

Processed Data

+

Processed data should be named so it is easy to see which script generated the data

+

The processing script -- processed data mapping should occur in the README

+

Processed data should be tidy

+

Exploratory Figures

+

Figures made during the course of your analysis, not necessarily part of your final report

+

They do not need to be "pretty"

+

Final Figures

+

Usually a small subset of the original figures

+

Axes/Colors set to make the figure clear

+

Possibly multiple panels

+

Raw Scripts

+

May be less commented (but comments help you!)

+

May be multiple versions

+

May include analyses that are later discarded

+

Final Scripts

+

Clearly commented

+ +

Include processing details

+

Only analyses that appear in the final write-up

+

R Markdown Files

+

R Markdown files can be used to generate reproducible reports

+

Text and R code are integrated

+

Very easy to create in RStudio

+

Readme Files

+

Not necessary if you use R Markdown

+

Should contain step-by-step instructions for analysis

+

Text of the document

+

It should contain a title, introduction (motivation), methods (statistics you used), results (including measures of uncertainty), and conclusions (including potential problems)

+

It should tell a story

+

It should not include every analysis you performed

+

References should be included for statistical methods

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2FReproducibleResearch%2Fweek2.html b/static/~brozek/index.html?courses%2FReproducibleResearch%2Fweek2.html new file mode 100644 index 0000000..bc47af6 --- /dev/null +++ b/static/~brozek/index.html?courses%2FReproducibleResearch%2Fweek2.html @@ -0,0 +1,267 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Coding Standards for R

+
    +
  1. Always use text files/text editor
  2. +
  3. Indent your code
  4. +
  5. Limit the width of your code (80 columns?)
  6. +
  7. Author suggests indentation of 4 spaces at minimum
  8. +
  9. Limit the length of individual functions
  10. +
+

What is Markdown?

+

Markdown is a text-to-HTML conversion tool for web writers. Markdown allows you to write using an easy-to-read, easy-to-write plain text format, then convert it structurally to valid XHTML/HTML

+

Markdown Syntax

+

*This text will appear italicized!*

+

This text will appear italicized!

+

**This text will appear bold!**

+

This text will appear bold

+

## This is a secondary heading

+

###This is a tertiary heading

+

This is a secondary heading

+

This is a tertiary heading

+

Unordered Lists

+

- first item in list

+

- second item in list

+ +

Ordered lists

+

1. first item in list

+

2. second item in list

+

3. third item in list

+
    +
  1. first item in list
  2. +
  3. second item in list
  4. +
  5. third item in list
  6. +
+

Create links

+

[Download R](http://www.r-project.org/)

+

Download R

+

Advanced linking

+

I spent so much time reading [R bloggers][1] and [Simply Statistics][2]!

+

[1]: http://www.r-bloggers.com/ "R bloggers"

+

[2]: http://simplystatistics.org/ "Simply Statistics"

+

I spent so much time reading R bloggers and Simply Statistics!

+

Newlines require a double space after the end of a line

+

What is Markdown?

+

Created by John Gruber and Aaron Swartz. It is a simplified version of "markup" languages. It allows one to focus on writing as opposed to formatting. Markdown provides a simple, minimal, and intuitive way of formatting elements.

+

You can easily convert Markdown to valid HTML (and other formats) using existing tools.

+

What is R Markdown?

+

R Markdown is the integration of R code with markdown. It allows one to create documents containing "live" R code. R code is evaluated as part of the processing of the markdown and its results are inserted into the Markdown document. R Markdown is a core tool in literate statistical programming

+

R Markdown can be converted to standard markdown using knitr package in R. Markdown can then be converted to HTML using the markdown package in R. This workflow can be easily managed using R Studio. One can create powerpoint like slides using the slidify package.

+

Problems, Problems

+ +

One of the ways to resolve this is to simply put the data and code together in the same document so that people can execute the code in the right order, and the data are read at the right times. You can have a single document that integrates the data analysis with all the textual representations.

+

Literate Statistical Programming

+ +

Literate Statistical Programming

+ +

How Do I Make My Work Reproducible?

+ +

Literate Programming: Pros

+ +

Literate Programming: Cons

+ +

What is Knitr Good For?

+ +

What is knitr NOT good for?

+ +

Non-GUI Way of Creating R Markdown documents

+
library(knitr)
+setwd(<working directory>)
+knit2html('document.Rmd')
+browseURL('document.html')
+

A few notes about knitr

+ +

Processing of knitr documents

+ +

Inline Text Computations

+

You can reference variable in RMarkdown through the following

+
`The current time is `r time`. My favorite random number is `r rand`
+

Setting Global Options

+ +

Example for suppressing all code chunks

+
​```{r setoptions, echo=FALSE}
+opts_chunk$set(echo=False, results = "hide")
+​```
+

Some Common Options

+ +

Caching Computations

+ +

Caching Caveats

+ +

Summary of knitr

+ +
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2FReproducibleResearch%2Fweek3.html b/static/~brozek/index.html?courses%2FReproducibleResearch%2Fweek3.html new file mode 100644 index 0000000..b7a90c5 --- /dev/null +++ b/static/~brozek/index.html?courses%2FReproducibleResearch%2Fweek3.html @@ -0,0 +1,370 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

tl;dr

+

People are busy, especially managers and leaders. Results of data analyses are sometimes presented in oral form, but often the first cut is presented via email.

+

It is often useful therefore, to breakdown the results of an analysis into different levels of granularity/detail

+

Hierarchy of Information: Research Paper

+ +

Hierarchy of Information: Email Presentation

+ +

DO: Start with Good Science

+ +

DON'T: Do Things By Hand

+ +

Things done by hand need to precisely documented (this is harder than it sounds!)

+

DON'T: Point and Click

+ +

DO: Teach a Computer

+

If something needs to be done as part of your analysis / investigation, try to teach your computer to do it (even if you only need to do it once)

+

In order to give your computer instructions, you need to write down exactly what you mean to do and how it should be done. Teaching a computer almost guarantees reproducibility

+

For example, by, hand you can

+
    1. Go to the UCI Machine Learning Repository at http://archive.ics.uci.edu/mil/
+        2. Download the Bike Sharing Dataset
+

Or you can teach your computer to do it using R

+
download.file("http://archive.ics.uci.edu/ml/machine-learning-databases/00275/Bike-Sharing-Dataset.zip", "ProjectData/Bike-Sharing-Dataset.zip")
+

Notice here that:

+ +

DO: Use Some Version Control

+

It helps you slow things down by adding changes into small chunks. (Don't just do one massive commit). It allows one to track / tag snapshots so that one can revert back to older versions of the project. Software like Github / Bitbucket / SourceForge make it easy to publish results.

+

DO: Keep Track of Your Software Environment

+

If you work on a complex project involving many tools / datasets, the software and computing environment can be critical for reproducing your analysis.

+

Computer Architecture: CPU (Intel, AMD, ARM), CPU Architecture, GPUs

+

Operating System: Windows, Mac OS, Linux / Unix

+

Software Toolchain: Compilers, interpreters, command shell, programming language (C, Perl, Python, etc.), database backends, data analysis software

+

Supporting software / infrastructure: Libraries, R packages, dependencies

+

External dependencies: Websites, data repositories, remote databases, software repositories

+

Version Numbers: Ideally, for everything (if available)

+

This function in R helps report a bunch of information relating to the software environment

+
sessionInfo()
+

DON'T: Save Output

+

Avoid saving data analysis output (tables, figures, summaries, processed data, etc.), except perhaps temporarily for efficiency purposes.

+

If a stray output file cannot be easily connected with the means by which it was created, then it is not reproducible

+

Save the data + code that generated the output, rather than the output itself.

+

Intermediate files are okay as long as there is clear documentation of how they were created.

+

DO: Set Your Seed

+

Random number generators generate pseudo-random numbers based on an initial seed (usually a number or set of numbers)

+

​ In R, you can use the set.seed() function to set the seed and to specify the random number generator to use

+

Setting the seed allows for the stream of random numbers to be exactly reproducible

+

Whenever you generate random numbers for a non-trivial purpose, always set the seed.

+

DO: Think About the Entire Pipeline

+ +

Summary: Checklist

+ +

Replication and Reproducibility

+

Replication

+ +

Reproducibility

+ +

Background and Underlying Trends

+ +

The Result?

+ +

What Problem Does Reproducibility Solve?

+

What we get:

+ +

What we do NOT get

+ +

An analysis can be reproducible and still be wrong

+

We want to know 'can we trust this analysis

+

Does requiring reproducibility deter bad analysis?

+

Problems with Reproducibility

+

The premise of reproducible research is that with data/code available, people can check each other and the whole system is self-correcting

+ +

Who Reproduces Research?

+ +

The Story So Far

+ +

Evidence-based Data Analysis

+ +

Evidence-based Data Analysis

+ +

Case Study: Estimating Acute Effects of Ambient Air Pollution Exposure

+ +

Case Study: Estimating Acute Effects of Ambient Air Pollution Exposure

+ +

DSM Modules for Time Series Studies of Air Pollution and Health

+
    +
  1. Check for outliers, high leverage, overdispersion
  2. +
  3. Fill in missing data? No!
  4. +
  5. Model selection: Estimate degrees of freedom to adjust for unmeasured confounders +
      +
    • Other aspects of model not as critical
    • +
  6. +
  7. Multiple lag analysis
  8. +
  9. Sensitivity analysis wrt +
      +
    • Unmeasured confounder adjustment
    • +
    • Influential points
    • +
  10. +
+

Where to Go From Here?

+ +

A Curated Library of Data Analysis

+ +

Summary

+ +
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2FReproducibleResearch%2Fweek4.html b/static/~brozek/index.html?courses%2FReproducibleResearch%2Fweek4.html new file mode 100644 index 0000000..5073871 --- /dev/null +++ b/static/~brozek/index.html?courses%2FReproducibleResearch%2Fweek4.html @@ -0,0 +1,233 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

The cacher Package for R

+ +

The value of this is so other people can get the analysis or clone the analysis and look at subsets of the code. Or maybe more specifically data objects. People who want to run your code may not necessarily have the resources that you have. Because of that, they may not want to run the entire Markov chain Monte Carlo simulation that you did to get the posterior distribution or the histogram that you got at the end.

+

But the idea is that you peel the onion a little bit rather than just go straight to the core.

+

Using cacher as an Author

+
    +
  1. Parse the R source file; Create the necessary cache directiories and subdirectories
  2. +
  3. Cycle through each expression in the source file +
      +
    • If an expression has never been evaluated, evaluate it and store any resulting R objects in the cache database
    • +
    • If any cached results exists, lazy-load the results from the cache database and move to the next expression
    • +
    • If an expression does not create any R objects (i.e, there is nothing to cache), add the expression to the list of expressions where evaluation needs to be forced
    • +
    • Write out metadata for this expression to the metadata file
    • +
  4. +
+ +

Using cacher as a Reader

+

A journal article says

+

​ "... the code and data for this analysis can be found in the cacher package 092dcc7dda4b93e42f23e038a60e1d44dbec7b3f"

+
library(cacher)
+clonecache(id = "092dcc7dda4b93e42f23e038a60e1d44dbec7b3f")
+clonecache(id = "092d") ## Same as above
+# Created cache directory `.cache`
+showfiles()
+# [1] "top20.R"
+sourcefile("top20.R")
+

Cloning an Analysis

+ +

graphcode() gives a node graph representing the code

+

Running Code

+ +

Checking Code and Objects

+ +

You can inspect data objects with loadcache. This loads in pointers to each of the data objects into the workspace. Once you access the object, it will transfer it from the cache.

+

cacher Summary

+ +

Case Study: Air Pollution

+

Particulate Matter -- PM

+

When doing air pollution studies you're looking at particulate matter pollution. The dust is not just one monolithic piece of dirt or soot but it's actually composed of many different chemical constituents.

+

Metals inert things like salts and other kinds of components so there's a possibility that a subset of those constituents are really harmful elements.

+

PM is composed of many different chemical constituents and it's important to understand that the Environmental Protection Agency (EPA) monitors the chemical constituents of particulate matter and has been doing so since 1999 or 2000 on a national basis.

+

What causes PM to be Toxic?

+ +

NMMAPS

+ +

NMMAPS and Reproducibility

+ +

What Causes Particulate Matter to be Toxic?

+

http://www.ncbi.nlm.nih.gov/pmc/articles/PMC1665439

+ +

A Reanalysis of the Lippmann et al. Study

+

http://www.ncbi.nlm.nih.gov/pmc/articles/PMC2137127

+ +

Does Nickel Make PM Toxic?

+ +

Does Nickel Make PM Toxic?

+

One of the most important things about those three points to the right is those are called high leverage points. So the regression line can be very senstive to high leverage points. Removing those three points from the dataset brings the regression line's slope down a little bit. Which then produces a line that is no longer statistical significant (p-value about 0.31)

+

What Have We Learned?

+ +

Lessons Learned

+ +
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2FReproducibleResearch.html b/static/~brozek/index.html?courses%2FReproducibleResearch.html new file mode 100644 index 0000000..c243d0e --- /dev/null +++ b/static/~brozek/index.html?courses%2FReproducibleResearch.html @@ -0,0 +1,89 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Reproducible Research

+

In the Winter of 2017, I took a coursera course on Reproducible Research taught by Dr. Peng from John Hopkins University

+

Below are my notes for each of the four weeks.

+

Week 1

+

Week 2

+

Week 3

+

Week 4

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2FStat381.html b/static/~brozek/index.html?courses%2FStat381.html new file mode 100644 index 0000000..46442d9 --- /dev/null +++ b/static/~brozek/index.html?courses%2FStat381.html @@ -0,0 +1,89 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Probability and Statistical Inference

+

In the Fall of 2017, I took the course STAT 381 with Dr. Debra Hydorn. Below I included the interesting labs we worked on in the class.

+

Please note that these reports were not formatted for this site. So equations and images may not show up.

+

Random Walk

+

Random Number Generation

+

Central Limit Theorum

+

Confidence Interval

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2Fstat381%2Fcentrallimit.html b/static/~brozek/index.html?courses%2Fstat381%2Fcentrallimit.html new file mode 100644 index 0000000..fba09c5 --- /dev/null +++ b/static/~brozek/index.html?courses%2Fstat381%2Fcentrallimit.html @@ -0,0 +1,453 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Central Limit Theorem Lab

+

Brandon Rozek

+

Introduction

+

The Central Limit Theorem tells us that if the sample size is large, then the distribution of sample means approach the Normal Distribution. For distributions that are more skewed, a larger sample size is needed, since that lowers the impact of extreme values on the sample mean.

+

Skewness

+

Skewness can be determined by the following formula +$$ +Sk = E((\frac{X - \mu}{\sigma})^3) = \frac{E((X - \mu)^3)}{\sigma^3} +$$ +Uniform distributions have a skewness of zero. Poisson distributions however have a skewness of $\lambda^{-\frac{1}{2}}$.

+

In this lab, we are interested in the sample size needed to obtain a distribution of sample means that is approximately normal.

+

Shapiro-Wilk Test

+

In this lab, we will test for normality using the Shapiro-Wilk test. The null hypothesis of this test is that the data is normally distributed. The alternative hypothesis is that the data is not normally distributed. This test is known to favor the alternative hypothesis for a large number of sample means. To circumvent this, we will test normality starting with a small sample size $n$ and steadily increase it until we obtain a distribution of sample means that has a p-value greater than 0.05 in the Shapiro-Wilk test.

+

This tells us that with a false positive rate of 5%, there is no evidence to suggest that the distribution of sample means don't follow the normal distribution.

+

We will use this test to look at the distribution of sample means of both the Uniform and Poisson distribution in this lab.

+

Properties of the distribution of sample means

+

The Uniform distribution has a mean of $0.5$ and a standard deviation of $\frac{1}{\sqrt{12n}}$ and the Poisson distribution has a mean of $\lambda$ and a standard deviation of $\sqrt{\frac{\lambda}{n}}$.

+

Methods

+

For the first part of the lab, we will sample means from a Uniform distribution and a Poisson distribution of $\lambda = 1$ both with a sample size $n = 5$.

+

Doing so shows us how the Uniform distribution is roughly symmetric while the Poisson distribution is highly skewed. This begs the question: what sample size $(n)$ do I need for the Poisson distribution to be approximately normal?

+

Sampling the means

+

The maximum number of mean observations that the Shapiro-Wilk test allows is 5000 observations. Therefore, we will obtain n observations separately from both the Uniform or Poisson distribution and calculate the mean from it. Repeating that process 5000 times.

+

The mean can be calculated from the following way +$$ +Mean = \frac{\sum x_i}{n} +$$ +Where $x_i$ is the observation obtained from the Uniform or Poisson distribution

+

Iterating with the Shapiro-Wilk Test

+

Having a sample size of a certain amount doesn't always guarantee that it will fail to reject the Shapiro-Wilk test. Therefore, it is useful to run the test multiple times so that we can create a 95th percentile of sample sizes that fails to reject the Shapiro-Wilk test.

+

The issue with this is that lower lambda values result in higher skewness's. Which is described by the skewness formula. If a distribution has a high degree of skewness, then it will take a larger sample size n to make the sample mean distribution approximately normal.

+

Finding large values of n result in longer computational time. Therefore, the code takes this into account by starting at a larger value of n and/or incrementing by a larger value of n each iteration. Incrementing by a larger value of n decreases the precision, though that is the compromise I'm willing to take in order to achieve faster results.

+

Finding just the first value of $n$ that generates the sample means that fails to reject the Shapiro-Wilk test doesn't tell us much in terms of the sample size needed for the distribution of sample means to be approximately normal. Instead, it is better to run this process many times, finding the values of n that satisfy this condition multiple times. That way we can look at the distribution of sample sizes required and return back the 95th percentile.

+

Returning the 95th percentile tells us that 95% of the time, it was the sample size returned or lower that first failed to reject the Shapiro-Wilk test. One must be careful, because it can be wrongly interpreted as the sample size needed to fail to reject the Shapiro-Wilk test 95% of the time. Using that logic requires additional mathematics outside the scope of this paper. Returning the 95th percentile of the first sample size that failed to reject the Shapiro-Wilk test, however, will give us a good enough estimate for a sample size needed.

+

Plots

+

Once a value for n is determined, we sample the means of the particular distribution (Uniform/Poisson) and create histograms and Q-Q plots for each of the parameters we're interested in. We're looking to verify that the histogram looks symmetric and that the points on the Q-Q Plot fit closely to the Q-Q Line with one end of the scattering of points on the opposite side of the line as the other.

+

Results

+

Part I

+

Sampling the mean of the uniform distribution with $n = 5$ results in a mean of $\bar{x} = 0.498$ and standard deviation of $sd = 0.1288$. The histogram and Q-Q Plot can be seen in Figure I and Figure II respectively.

+

$\bar{x}$ isn't far from the theoretical 0.5 and the standard deviation is also close to +$$ +\frac{1}{\sqrt{12(5)}} \approx 0.129 +$$ +Looking at the histogram and Q-Q plot, it suggests that data is approximately normal. Therefore we can conclude that a sample size of 5 is sufficient for the sample mean distribution coming from the normal distribution to be approximately normal.

+

Sampling the mean of the Poisson distribution with $n = 5$ and $\lambda = 1$ results in a mean of $\bar{x} = 0.9918$ and a standard deviation of $sd = 0.443$. The histogram and Q-Q Plot can be seen in Figures III and IV respectively.

+

$\bar{x}$ is not too far from the theoretical $\lambda = 1$, the standard deviation is a bit farther from the theoretical +$$ +\sqrt{\frac{\lambda}{n}} = \sqrt{\frac{1}{5}} = 0.447 +$$ +Looking at the Figures, however, shows us that the data does not appear normal. Therefore, we cannot conclude that 5 is a big enough sample size for the Poisson Distribution of $\lambda = 1$ to be approximately normal.

+

Part II

+

Running the algorithm I described, I produced the following table

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
$\lambda$SkewnessSample Size NeededShapiro-Wilk P-ValueAverage of Sample MeansStandard Deviation of Sample MeansTheoretical Standard Deviation of Sample Means
0.13.1622827100.057780.0990.00600.0061
0.51.414218020.168400.4990.02500.0249
11.000002150.064791.0000.06750.0682
50.44721530.125504.9970.30600.3071
100.31622310.141209.9990.56170.5679
500.14142100.4844050.032.24612.2361
1000.1000060.47230100.00274.12454.0824
+

The skewness was derived from the formula in the first section while the sample size was obtained by looking at the .95 blue quantile line in Figures XVIII-XIV. The rest of the columns are obtained from the output of the R Code function show_results.

+

Looking at the histograms and Q-Q Plots produced by the algorithm, the distribution of sample means distributions are all roughly symmetric. The sample means are also tightly clustered around the Q-Q line, showing that the normal distribution is a good fit. This allows us to be confident that using these values of n as the sample size would result in the distribution of sample means of Uniform or Poisson (with a given lambda) to be approximately normal.

+

All the values of the average sampling means are within 0.001 of the theoretical average of sample means. The standard deviation of sample means slightly increase as the value of $\lambda$ increases, but it still is quite low.

+

Conclusion

+

The table in the results section clearly show that as the skewness increases, so does the sample size needed to make the distribution of sample means approximately normal. This shows the central limit theorem in action in that no matter the skewness, if you obtain a large enough sample, the distribution of sample means will be approximately normal.

+

These conclusions pave the way for more interesting applications such as hypothesis testing and confidence intervals.

+

Appendix

+

Figures

+

Figure I, Histogram of Sample Means coming from a Uniform Distribution with sample size of 5

+

part1histunif

+

Figure II, Q-Q Plot of Sample Means coming from a Uniform Distribution with sample size of 5

+

part1qunif

+

Figure III, Histogram of Sample Means coming from a Poisson Distribution with $\lambda = 1$ and sample size of 5

+

part1histpoisson

+

Figure IV, Q-Q Plot of Sample Means coming from Poisson Distribution with $\lambda = 1$ and sample size of 5

+

part1qpoisson

+

Figure V, Histogram of Sample Means coming from Poisson Distribution with $\lambda = 0.1$ and sample size of 2710

+

histpoisson01

+

Figure VI, Q-Q Plot of Sample Means coming from Poisson Distribution with $\lambda = 0.1$ and sample size of 2710

+

qpoisson01

+

Figure VII, Histogram of Sample Means coming from Poisson Distribution with $\lambda = 0.5$ and sample size of 516

+

histpoisson05

+

Figure VII, Q-Q Plot of Sample Means coming from Poisson Distribution with $\lambda = 0.5$ and sample size of 516

+

qpoisson05

+

Figure VIII, Histogram of Sample Means coming from Poisson Distribution with $\lambda = 1$ and sample size of 215

+

histpoisson1

+

Figure IX, Q-Q Plot of Sample Means coming from Poisson Distribution with $\lambda = 1$ and sample size of 215

+

qpoisson1

+

Figure X, Histogram of Sample Means coming from Poisson Distribution of $\lambda = 5$ and sample size of 53

+

histpoisson5

+

Figure XI, Q-Q Plot of Sample Means coming from Poisson Distribution of $\lambda = 5$ and sample size of 53

+

qpoisson5

+

Figure XII, Histogram of Sample Means coming from Poisson Distribution of $\lambda = 10$ and sample size of 31

+

histpoisson10

+

Figure XIII, Q-Q Plot of Sample Means coming from Poisson Distribution of $\lambda = 10$ and sample size of 31

+

qpoisson10

+

Figure XIV, Histogram of Sample Means coming from Poisson Distribution of $\lambda = 50$ and sample size of 10

+

histpoisson50

+

Figure XV, Q-Q Plot of Sample Means coming from Poisson Distribution of $\lambda = 50$ and sample size of 10

+

qpoisson50

+

Figure XVI, Histogram of Sample Means coming from Poisson Distribution of $\lambda = 100$ and sample size of 6

+

histpoisson100

+

Figure XVII, Q-Q Plot of Sample Means coming from Poisson Distribution of $\lambda = 100$ and sample size of 6

+

qpoisson100

+

Figure XVIII, Histogram of sample size needed to fail to reject the normality test for Poisson Distribution of $\lambda = 0.1$

+

histl01

+

Figure XIX, Histogram of sample size needed to fail to reject the normality test for Poisson Distribution of $\lambda = 0.5$

+

histl05

+

Figure XX, Histogram of sample size needed to fail to reject the normality test for Poisson Distribution of $\lambda = 1$

+

histl1.0

+

Figure XXI, Histogram of sample size needed to fail to reject the normality test for Poisson Distribution of $\lambda = 5$

+

histl5

+

Figure XXII, Histogram of sample size needed to fail to reject the normality test for Poisson Distribution of $\lambda = 10$

+

histl10

+

Figure XXIII, Histogram of sample size needed to fail to reject the normality test for Poisson Distribution of $\lambda = 50$

+

histl50

+

Figure XXIV, Histogram of sample size needed to fail to reject the normality test for Poisson Distribution of $\lambda = 100$

+

histl100

+

R Code

+
rm(list=ls())
+library(ggplot2)
+
+sample_mean_uniform = function(n) {
+  xbarsunif = numeric(5000)
+  for (i in 1:5000) {
+    sumunif = 0
+    for (j in 1:n) {
+      sumunif = sumunif + runif(1, 0, 1)
+    }
+    xbarsunif[i] = sumunif / n 
+  }
+  xbarsunif
+}
+
+sample_mean_poisson = function(n, lambda) {
+  xbarspois = numeric(5000)
+  for (i in 1:5000) {
+    sumpois = 0
+    for (j in 1:n) {
+      sumpois = sumpois + rpois(1, lambda) 
+    }
+    xbarspois[i] = sumpois / n
+  }
+  xbarspois
+}
+
+poisson_n_to_approx_normal = function(lambda) {
+  print(paste("Looking at Lambda =", lambda))
+  ns = c()
+
+  # Speed up computation of lower lambda values by starting at a different sample size
+  # and/or lowering the precision by increasing the delta sample size
+  # and/or lowering the number of sample sizes we obtain from the shapiro loop
+  increaseBy = 1;
+  iter = 3;
+  startingValue = 2
+  if (lambda == 0.1) {
+    startingValue = 2000;
+    iter = 3;
+    increaseBy = 50;
+  } else if (lambda == 0.5) {
+    startingValue = 200;
+    iter = 5;
+    increaseBy = 10;
+  } else if (lambda == 1) {
+    startingValue = 150;
+    iter = 25;
+  } else if (lambda == 5) {
+    startingValue = 20;
+    iter = 50;
+    startingValue = 10;
+  } else if (lambda == 10) {
+    iter = 100;
+  } else {
+    iter = 500;
+  }
+
+  progressIter = 1
+  for (i in 1:iter) {
+
+    # Include a progress indicator for personal sanity
+    if (i / iter > .1 * progressIter) {
+      print(paste("Progress", i / iter * 100, "% complete"))
+      progressIter = progressIter + 1
+    }
+
+    n = startingValue
+
+    dist = sample_mean_poisson(n, lambda)
+    p.value = shapiro.test(dist)$p.value
+    while (p.value < 0.05) {
+      n = n + increaseBy
+      dist = sample_mean_poisson(n, lambda)
+      p.value = shapiro.test(dist)$p.value
+
+      # More sanity checks
+      if (n %% 10 == 0) {
+        print(paste("N =", n, " p.value =", p.value))
+      }
+    }
+    ns = c(ns, n)
+  }
+
+  print(ggplot(data.frame(ns), aes(x = ns)) +
+          geom_histogram(fill = 'white', color = 'black', bins = 10) +
+          geom_vline(xintercept = ceiling(quantile(ns, .95)), col = '#0000AA') +
+          ggtitle(paste("Histogram of N needed for Poisson distribution of lambda =", lambda)) +
+          xlab("N") +
+          ylab("Count") +
+          theme_bw())
+
+  ceiling(quantile(ns, .95)) #95% of the time, this value of n will give you a sampling distribution that is approximately normal
+}
+
+uniform_n_to_approx_normal = function() {
+  ns = c()
+  progressIter = 1
+
+  for (i in 1:500) {
+
+    # Include a progress indicator for personal sanity
+    if (i / 500 > .1 * progressIter) {
+      print(paste("Progress", i / 5, "% complete"))
+      progressIter = progressIter + 1
+    }
+
+    n = 2
+    dist = sample_mean_uniform(n)
+    p.value = shapiro.test(dist)$p.value
+    while (p.value < 0.05) {
+      n = n + 1
+      dist = sample_mean_uniform(n)
+      p.value = shapiro.test(dist)$p.value
+
+      if (n %% 10 == 0) {
+        print(paste("N =", n, " p.value =", p.value))
+      }
+
+    }
+
+    ns = c(ns, n)
+  }
+
+  print(ggplot(data.frame(ns), aes(x = ns)) +
+    geom_histogram(fill = 'white', color = 'black', bins = 10) +
+    geom_vline(xintercept = ceiling(quantile(ns, .95)), col = '#0000AA') +
+    ggtitle("Histogram of N needed for Uniform Distribution") +
+    xlab("N") +
+    ylab("Count") +
+    theme_bw())
+
+  ceiling(quantile(ns, .95)) #95% of the time, this value of n will give you a sampling distribution that is approximately normal
+}
+
+show_results = function(dist) {
+  print(paste("The mean of the sample mean distribution is:", mean(dist)))
+  print(paste("The standard deviation of the sample mean distribution is:", sd(dist)))
+  print(shapiro.test(dist))
+  print(ggplot(data.frame(dist), aes(x = dist)) +
+          geom_histogram(fill = 'white', color = 'black', bins = 20) +
+          ggtitle("Histogram of Sample Means") +
+          xlab("Mean") + 
+          ylab("Count") +
+          theme_bw())
+  qqnorm(dist, pch = 1, col = '#001155', main = "QQ Plot", xlab = "Sample Data", ylab = "Theoretical Data")
+  qqline(dist, col="#AA0000", lty=2)
+}
+
+## PART I
+uniform_mean_dist = sample_mean_uniform(n = 5)
+poisson_mean_dist = sample_mean_poisson(n = 5, lambda = 1)
+
+show_results(uniform_mean_dist)
+show_results(poisson_mean_dist)
+
+## PART II
+
+print("Starting Algorithm to Find Sample Size Needed for the Poisson Distribution of Lambda = 0.1");
+n.01 = poisson_n_to_approx_normal(0.1)
+show_results(sample_mean_poisson(n.01, 0.1))
+print("Starting Algorithm to Find Sample Size Needed for the Poisson Distribution of Lambda = 0.5");
+n.05 = poisson_n_to_approx_normal(0.5)
+show_results(sample_mean_poisson(n.05, 0.5))
+print("Starting Algorithm to Find Sample Size Needed for the Poisson Distribution of Lambda = 1");
+n.1  = poisson_n_to_approx_normal(1)
+show_results(sample_mean_poisson(n.1, 1))
+print("Starting Algorithm to Find Sample Size Needed for the Poisson Distribution of Lambda = 5");
+n.5  = poisson_n_to_approx_normal(5)
+show_results(sample_mean_poisson(n.5, 5))
+print("Starting Algorithm to Find Sample Size Needed for the Poisson Distribution of Lambda = 10");
+n.10 = poisson_n_to_approx_normal(10)
+show_results(sample_mean_poisson(n.10, 10))
+print("Starting Algorithm to Find Sample Size Needed for the Poisson Distribution of Lambda = 50");
+n.50 = poisson_n_to_approx_normal(50)
+show_results(sample_mean_poisson(n.50, 50))
+print("Starting Algorithm to Find Sample Size Needed for the Poisson Distribution of Lambda = 100");
+n.100 = poisson_n_to_approx_normal(100)
+show_results(sample_mean_poisson(n.100, 100))
+
+print("Starting Algorithm to Find Sample Size Needed for the Uniform Distribution")
+n.uniform = uniform_n_to_approx_normal()
+show_results(sample_mean_uniform(n.uniform))
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2Fstat381%2Fconfint.html b/static/~brozek/index.html?courses%2Fstat381%2Fconfint.html new file mode 100644 index 0000000..37e075d --- /dev/null +++ b/static/~brozek/index.html?courses%2Fstat381%2Fconfint.html @@ -0,0 +1,331 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Confidence Interval Lab

+

Written by Brandon Rozek

+

Introduction

+

Confidence intervals expands the concept of a point estimation by giving a margin of error such that one can be confident that a certain percentage of the time the true parameter falls within that interval.

+

In this lab, we will look at confidence intervals for a mean. This lab focuses on a certain method of confidence intervals that depends on the distribution of sample means being Normal. We will show how the violation of this assumption impacts the probability that the true parameter falls within the interval.

+

Methods

+

The observed level of confidence tells us the proportion of times the true mean falls within a confidence interval. To show how the violation of the Normality assumption affects this, we will sample from both a Normal distribution, T distribution, and exponential distribution with different sample sizes.

+

The normal and T distributions are sampled with a mean of 5 and a standard deviation of 2. The exponential deviation is sampled with a lambda of 2 or mean of 0.5.

+

From the samples, we obtain the mean and the upper/lower bounds of the confidence interval. This is performed 100,000 times. That way we obtain a distribution of these statistics.

+

We know that a confidence interval is valid, if the lower bound is no more than the true mean and the upper bound is no less than the true mean. From this definition, we can compute a proportion of observed confidence from the simulations

+

Visualizations

+

From the distributions of statistics, we can create visualizations to support the understanding of confidence intervals.

+

The first one is a scatterplot of lower bounds vs upper bounds. This plot demonstrates the valid confidence intervals in blue and the invalid ones in red. It demonstrates how confidence intervals that are invalid are not located inside the box.

+

The second visualization is a histogram of all the sample means collected. The sample means that didn't belong to a valid confidence interval are shaded in red. This graphic helps demonstrate the type I errors on both sides of the distribution.

+

In this lab, we're interested in seeing how our observed level of confidence differs from our theoretical level of confidence (95%) when different sample sizes and distributions are applied.

+

Results

+

We can see from the table section in the Appendix that sampling from a Normal or t distribution does not adversely affect our observed level of confidence. The observed level of confidence varies slightly from the theoretical level of confidence of 0.95.

+

When sampling from the exponential distribution, however, the observed level of confidence highly depends upon the sample size.

+

Looking at Table III, we can see that for a sample size of 10, the observed level of confidence is at a meager 90%. This is 5% off from our theoretical level of confidence. This shows how the normality assumption is vital to the precision of our estimate.

+

This comes from the fact that using this type of confidence interval on a mean from a non-normal distribution requires a large sample size for the central limit theorem to take affect.

+

The central limit theorem states that if the sample size is "large", the distribution of sample means approach the normal distribution. You can see how in Figure XVIII, the distribution of sample means is skewed, though as the sample size increases, the distribution of sample means become more symmetric (Figure XIX).

+

Conclusion

+

From this, we can conclude that violating the underlying assumption of normality decreases the observed level of confidence. We can mitigate the decrease of the observed level of confidence when sampling means from a non-normal distribution by having a larger sample size. This is due to the central limit theorem.

+

Appendix

+

Tables

+

Table I. Sampling from Normal

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Sample SizeProportion of Means Within CI
100.94849
200.94913
500.95045
1000.94955
+

Table II. Sampling from T Distribution

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Sample SizeProportion of Means Within CI
100.94966
200.94983
500.94932
1000.94999
+

Table III. Sampling from Exponential Distribution

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Sample SizeProportion of Means Within CI
100.89934
200.91829
500.93505
1000.94172
+

Figures

+

Normal Distribution

+
Figure I. Scatterplot of Bounds for Normal Distribution of Sample Size 10
+

normal10scatter

+
Figure II. Histogram of Sample Means for Normal Distribution of Sample Size 10
+

normal10hist

+
Figure III. Scatterplot of Bounds for Normal Distribution of Sample Size 20
+

normal20scatterplot

+
Figure IV. Histogram of Sample Means for Normal Distribution of Sample Size 20
+

normal20hist

+
Figure VScatterplot of Bounds for Normal Distribution of Sample Size 50
+

normal50scatterplot

+
Figure VI. Histogram of Sample Means for Normal Distribution of Sample Size 50
+

normal50hist

+
Figure VII. Scatterplot of Bounds for Normal Distribution of Sample Size 100
+

normal100scatterplot

+
Figure VIII. Histogram of Sample Means for Normal Distribution of Sample Size 100
+

normal100hist

+

T Distribution

+
Figure IX. Scatterplot of Bounds for T Distribution of Sample Size 10
+

t10scatterplot

+
Figure X. Histogram of Sample Means for T Distribution of Sample Size 10
+

t10hist

+
Figure XI. Scatterplot of Bounds for T Distribution of Sample Size 20
+

t20scatterplot

+
Figure XII. Histogram of Sample Means for T Distribution of Sample Size 20
+

t20hist

+
Figure XIII. Scatterplot of Bounds for T Distribution of Sample Size 50
+

t50scatter

+
Figure XIV. Histogram of Sample Means for T Distribution of Sample Size 50
+

t50hist

+
Figure XV. Scatterplot of Bounds for T Distribution of Sample Size 100
+

t100scatter

+
Figure XVI. Histogram of Sample Means for T Distribution of Sample Size 100
+

t100hist

+

Exponential Distribution

+
Figure XVII. Scatterplot of Bounds for Exponential Distribution of Sample Size 10
+

exp10scatter

+
Figure XVIII. Histogram of Sample Means for Exponential Distribution of Sample Size 10
+

exp10hist

+
Figure XIX. Scatterplot of Bounds for Exponential Distribution of Sample Size 20
+

exp20scatter

+
Figure XX. Histogram of Sample Means for Exponential Distribution of Sample Size 20
+

exp20hist

+
Figure XXI. Scatterplot of Bounds for Exponential Distribution of Sample Size 50
+

exp50scatter

+
Figure XXII. Histogram of Sample Means for Exponential Distribution of Sample Size 50
+

exp50hist

+
Figure XXIII. Scatterplot of Bounds for Exponential Distribution of Sample Size 100
+

exp100scatter

+
Figure XXIV. Histogram of Sample Means for Exponential Distribution of Sample Size 100
+

exp100hist

+

R Code

+
rm(list=ls())
+library(ggplot2)
+library(functional) # For function currying
+
+proportion_in_CI = function(n, mu, dist) {
+
+  # Preallocate vectors
+  lower_bound = numeric(100000)
+  upper_bound = numeric(100000)
+  means = numeric(100000)
+
+  number_within_CI = 0
+
+  ME = 1.96 * 2 / sqrt(n) ## Normal Margin of Error
+
+  for (i in 1:100000) {
+    x = numeric(n)
+
+    # Sample from distribution
+    if (dist == "Normal" | dist == "t") {
+      x = rnorm(n,mu,2)
+    } else if (dist == "Exponential") {
+      x = rexp(n, 1 / mu)
+    }
+
+    ## Correct ME if non-normal
+    if (dist != "Normal") {
+      ME = qt(0.975,n-1)*sd(x)/sqrt(n)
+    }
+
+    ## Store statistics
+    means[i] = mean(x)
+    lower_bound[i] = mean(x) - ME
+    upper_bound[i] = mean(x) + ME
+
+    # Is Confidence Interval Valid?
+    if (lower_bound[i] < mu & upper_bound[i] > mu) {
+      number_within_CI = number_within_CI + 1 
+    }
+  }
+
+  # Prepare for plotting
+  lbub = data.frame(lower_bound, upper_bound, means)
+  lbub$col = ifelse(lbub$lower_bound < mu & lbub$upper_bound > mu, 'Within CI', 'Outside CI')
+  print(ggplot(lbub, aes(x = lower_bound, y = upper_bound, col = col)) +
+          geom_point(pch = 1) +
+          geom_hline(yintercept = mu, col = '#000055') +
+          geom_vline(xintercept = mu, col = '#000055') +
+          ggtitle(paste("Plot of Lower Bounds vs Upper Bounds with Sample Size of ", n)) +
+          xlab("Lower Bound") +
+          ylab("Upper Bounds") +
+          theme_bw()
+  )
+  print(ggplot(lbub, aes(x = means, fill = col)) +
+          geom_histogram(color = 'black') +
+          ggtitle(paste("Histogram of Sample Means with Sample Size of ", n)) +
+          xlab("Sample Mean") +
+          ylab("Count") +
+          theme_bw()
+  )
+
+  # Return proportion within CI
+  number_within_CI / 100000
+}
+
+sample_sizes = c(10, 20, 50, 100)
+
+### PART I
+proportion_in_CI_Normal = Curry(proportion_in_CI, dist = "Normal", mu = 5)
+p_norm = sapply(sample_sizes, proportion_in_CI_Normal)
+sapply(p_norm, function(x) {
+  cat("The observed proportion of intervals containing mu is", x, "\n")
+  invisible(x)
+})
+
+### PART II
+proportion_in_CI_T = Curry(proportion_in_CI, dist = "t", mu = 5)
+p_t = sapply(sample_sizes, proportion_in_CI_T)
+sapply(p_t, function(x) {
+  cat("The observed proportion of intervals containing mu is", x, "\n")
+  invisible(x)
+})
+
+### PART III
+proportion_in_CI_Exp = Curry(proportion_in_CI, dist = "Exponential", mu = 0.5)
+p_exp = sapply(sample_sizes, proportion_in_CI_Exp)
+sapply(p_exp, function(x) {
+  cat("The observed proportion of intervals containing mu is", x, "\n")
+  invisible(x)
+})
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2Fstat381%2Frandomnumber.html b/static/~brozek/index.html?courses%2Fstat381%2Frandomnumber.html new file mode 100644 index 0000000..d935895 --- /dev/null +++ b/static/~brozek/index.html?courses%2Fstat381%2Frandomnumber.html @@ -0,0 +1,465 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Random Number Generation

+

Introduction

+

The generation of random numbers have a variety of applications including but not limited to the modeling of stochastic processes. It is important, therefore, to be able to generate any random number following a given distribution. One of the many ways to achieve this is to transform numbers sampled from a random uniform distribution.

+

In this lab, we will compare the effectiveness between the linear congruence method (LCM), runif, and rexp to generate random numbers. The programming language R will be used and different plots and summary statistics are drawn upon to analyze the effectiveness of the methods.

+

Methods

+

The Linear Congruential Method

+

The linear congruential method (LCM) is an algorithm that produces a sequence of pseudo-random numbers using the following recursive function +$$ +X_{n + 1} = (aX_n + c) \mod m +$$ +The R code we use has a c value of 0 which is a special case known as the multiplicative congruential generator (MCG).

+

There are several conditions for using a MCG. First, the seed value must be co-prime to m. In other words, the greatest common denominator between the two must be 1. A function was written in R to check this. Secondly, m must be a prime number or a power of a prime number.

+

Periodicity

+

An element of periodicity comes into play when dealing with pseudo-random number generators. Once the generator has produced a certain number of terms, it is shown to loop back to the first term of the sequence. It is advantageous, therefore, to keep the period high.

+

The period in a MCG is at most m - 1. In this lab, m has a value of $2^{31}$ and only 100 numbers were sampled from the LCM. This allows us to avoid the issue of periodicity entirely in our analysis.

+

Mersenne-Twister Method

+

The default pseudo-random number generator (pseudo RNG) in R is the Mersenne-Twister with the default seed value of the current time and the process id of the current R instance. Mersenne-Twister is part of a class of pseudo RNG called the generalized feedback register. This class of pseudo RNGs provide a very long period (VLP) or in other words, a long cycle before the values start repeating. VLPs are often useful when executing large simulations in R.

+

Since this method is already coded in the base R-package, we will leave the implementation for the curious to research.

+

The Uniform Distribution

+

Probability Mass Function

+

The uniform distribution function $Unif(\theta_1, \theta_2)$ has a probability mass function (PMF) of the following. +$$ +f(x) = \frac{1}{\theta_2 - \theta_1} +$$ +Where x is valid between [$\theta_1$, $\theta_2$].

+

In our case, we are producing numbers from [0,1]. We can therefore reduce the probability mass function to the following +$$ +f(x) = 1 +$$

+

Expected Value

+

The expected value can be defined as +$$ +E(X) = \int_a^b xf(x)dx +$$ +For the uniform distribution we're using that becomes +$$ +E(X) = \int_0^1 xdx = \frac{1}{2}[x^2]_0^1 = \frac{1}{2} +$$ +We should, therefore, expect the mean of the generated random number sequence to roughly equal $\frac{1}{2}$.

+

Median

+

To find the median of the distribution, we need to find the point at which the cumulative density function (CDF) is equal to .5. +$$ +\int_0^{Median(X)} f(x)dx = \frac{1}{2} +$$ +$$ +\int_0^{Median(X)} dx = \frac{1}{2} +$$

+

$$ +[X]_0^{Median(X)} = \frac{1}{2} +$$

+

$$ +Median(X) = \frac{1}{2} +$$

+

This shows us that the median of the distribution should be roughly equal to $\frac{1}{2}$ as well.

+

Analysis of Uniform Distribution Fit

+

The histogram of a uniform distribution of data should look rectangular in shape. This means that the counts of all the sub-intervals should be about the same.

+

Another way to test whether or not the distribution is a good fit is to use what is called a Quantile-Quantile plot (Q-Q Plot). This is a probability plot that compares the quantiles from the theoretical distribution, this is the uniform distribution, to that of the sample.

+

For a precise Q-Q Plot, we need a lot of quantiles to compare. In this lab, we will compare 100 different quantiles. The quantiles from the theoretical distribution can be easily derived from the fact that all value ranges are equally probable. The theoretical quantiles in this case is 0.01, 0.02, ..., 0.98, 0.99, 1. The sample quantiles are obtianed by receiving 100 observations from runif or the LCM.

+

In the Q-Q plot, a good fit is shown when the points hug closely to the Q-Q line. It is also important to have symmetry in the points. This means that the points are ending on opposite sides of the Q-Q line.

+

For sake of exploration, we will use 5 different seed values for the linear congruential method (while making sure that the seed values are co-prime). We will then use the results of these and compare LCM to how the standard runif method generates random numbers.

+

Exponential Distribution

+

Probability Mass Function and the Cumulative Density Function

+

The exponential distribution is a type of continuous distribution that is defined by the following PMF +$$ +f(x) = \lambda e^{-\lambda t} +$$ +We can find the CDF by taking the integral of the PMF. +$$ +F(x) = \int f(x)dx = \lambda \int e^{-\lambda x} dx = \lambda * (\frac{-1}{\lambda}) e^{-\lambda x} + C = -e^{-\lambda x} + C +$$ +One of the conditions for the cumulative density function is that as $x \to \infty$, $F(x) \to 1$. +$$ +1 = \lim{x \to \infty} (-e^{-\lambda x} + C) = \lim{x \to \infty} (-e^{-\lambda x}) + lim{x \to \infty} ( C) = \lim{x \to \infty}(-e^{\lambda x}) + C +$$ +This shows that $C = 1$, since $lim_{x \to \infty} (-e^{-\lambda x})$ is equal to 0.

+

Substituting $C​$ gives us the following. +$$ +F(x) = 1 - e^{-\lambda x} +$$

+

Expected Value

+

We can find the expected value using the formula described in the previous Expected Value section. Reflected in the bounds of integration is the domain of the exponential distribution $[0, \infty)$. +$$ +E(X) = \lim_{a \to \infty}\int_0^a x \lambda e^{-\lambda x} dx +$$ +The integral above features a product of two functions. So as an aside, we will derive a formula so we can take the integral above.

+

The total derivative is defined as +$$ +d(uv) = udv + vdu +$$

+

After taking the integral of both sides, we can solve for a formula that gives the following +$$ +\int d(uv) = \int udv + \int vdu +$$

+

$$ +\int udv = uv - \int vdu +$$

+

The formula above is called Integration by Parts. We will make use of this formula by defining $u = \lambda x$ and $dv = e^{-\lambda x} dx$

+

This implies that $du = \lambda dx$ and $v= -\frac{1}{\lambda}e^{-\lambda x}$
+$$ +E(X) = -\lim_{a \to \infty}[\lambda x \frac{1}{\lambda}e^{-\lambda x}]0^a - \lim{b \to \infty}\int_0^b -\frac{1}{\lambda}e^{-\lambda x}\lambda dx +$$

+

$$ +E(X) = -\lim_{a \to \infty} [xe^{-\lambda x}]0^a - \lim{b \to \infty}\int_0^b -e^{-\lambda x}dx +$$

+

$$ +E(X) = -\lim{a \to \infty}(ae^{-\lambda a}) - \lim{b \to \infty}[\frac{1}{\lambda}e^{-\lambda x}]_0^b +$$

+

$$ +E(X) = 0 - \frac{1}{\lambda}[\lim_{b \to \infty}(e^{-\lambda b}) - e^{-0\lambda}] +$$

+

$$ +E(X) = -\frac{1}{\lambda}(-1) = \frac{1}{\lambda} +$$

+

For the purposes of this lab, we will make the rate ($\lambda$) equal to 3. Which means we should expect our mean to be roughly equal to $\frac{1}{3}$.

+

Median

+

The median can be found by setting the CDF equal to $\frac{1}{2}$ +$$ +1- e^{-\lambda Median(X)} = \frac{1}{2} +$$

+

$$ +e^{-\lambda Median(X)} = \frac{1}{2} +$$

+

$$ +-\lambda Median(X) = \ln(\frac{1}{2}) +$$

+

$$ +Median(X) = \frac{\ln(2)}{\lambda} +$$

+

This shows that we should expect our median to be around $\frac{\ln(2)}{3} \approx 0.231$.

+

Inverse Transform Sampling

+

Once we have a uniform distribution of values, we can then use these values to map to an exponential distribution. This is done through a technique called inverse transform sampling, the technique works as follows:

+
    +
  1. Generate a random number u from the standard uniform distribution
  2. +
  3. Compute the value of X such that F(X) = u
  4. +
  5. The value of X belongs to the distribution of F
  6. +
+

Using these steps, we'll derive the exponential transform below. +$$ +F(X) = 1 - e^{-\lambda x} = u +$$ +Then proceeding to solve for X, we obtain the following. +$$ +e^{-\lambda X} = 1 - u +$$

+

$$ +-\lambda X = \ln(1 - u) +$$

+

$$ +X = \frac{-\ln(1 - u)}{\lambda} +$$

+

With this formula, we can now find values for X which is a random variable that follows an exponential distribution given random uniform data $u$.

+

In this lab, we are looking at the exponential distribution with a rate of 3. Therefore, the probability mass function, the cumulative distribution function, and the exponential transform can be redefined as these respectively. +$$ +f(x) = 3e^{-3x} +$$

+

$$ +F(x) = 1 - e^{-3x} +$$

+

$$ +X = \frac{-\ln(1 - u)}{3} +$$

+

R Code

+

The R code makes use of the concepts above. The purpose of this code is to output the summary statistics, histograms, and Q-Q plots are used to compare the different methods.

+

First the LCM is executed four times with three different seed values. The LCM is used to create a uniform distribution of data that is then compared to the standard runif function in the R language.

+

Then, transformations of a LCM, runif, are executed and compared with the standard rexp to create an exponential distribution of data with $\lambda = 3$.

+

Results

+

Uniform Distribution

+

For a small sample of 100 values, the data seems evenly distributed for all seeds and methods used. The peaks and troughs are more pronounced in the LCM methods suggesting that the runif command creates more evenly distributed data than the LCM.

+

Deviations from the mean and median are lowest for the LCM rather than the standard runif command with the exception of the LCM with the seed of 93463.

+

The Q-Q plots for all of the methods follow the Q-Q Line tightly and appear symmetric.

+

Exponential Distribution

+

A bin size of 20 is used to make the histograms easily comparable to each other. One interesting thing to note is that in Figure XI, there is an observation located far out from the rest of the data. For the purpose of a histogram, which is to show us the shape of the distribution, this one far observation skews what we can see. Therefore the next figure, Figure XII has that single outlier removed and shows the histogram of the rest of the data.

+

All of the histograms appear exponential in shape. Looking at the Q-Q plots, the LCM transformation and the rexp distribution of data fit closely to the QQ-Line. All of the Q-Q Plots have the points getting further away from the line as you get higher up in the percentiles. The runif transformation quantiles diverge from the line after about the 50th percentile.

+

Deviations from the mean and median were about the same for both transformed techniques (runif and LCM). The rexp command did better when it came to the deviation from the mean, but performed worse when it came to deviation from the median.

+

Conclusion

+

The linear congruential methods performed better when it came to simulating the distribution than the standard R functions. It more accurately captured the median for both the standard uniform data, and the exponential data. Against the runif command, it also performed better at simulating the mean.

+

This can especially be seen when comparing the two transform techniques. The transformed LCM distribution of data followed the Q-Q line more tightly than the transformed runif.

+

I speculate that this is due to the seed value used. The Mersenne-Twist method performs better when the seed value doesn't have many zeros in it. Since the seed value is determined by the system time and process id, we don't know for sure if it's a proper input for the Mersenne-Twist. For the LCM, seeds were properly tested to make sure that it was co-prime with one of its parameters. This condition allowed proper seeds to work well with the LCM.

+

Further research can be done on standardizing the seed values used across all the different pseudo random number generators and looking at the 6 other pseudo RNG that comes built into R. Changing the seed and random number generator can be achieved through the set.seed function.

+

Appendix

+

Figures

+

Figure I, Histogram of LCM Random Data with seed 55555

+

+

Figure II, Q-Q Plot of LCM Random Data with seed 55555

+

qqplot55555

+

Figure III, Histogram of LCM Random Data with seed 93463

+

hist93463

+

Figure IV, Q-Q Plot of LCM Random Data with seed 93463

+

q93463

+

Figure V, Histogram of LCM Random Data with seed 29345

+

hist29345

+

Figure VI, Q-Q Plot of LCM Random Data with seed 29345

+

q29345

+

Figure VII, Histogram of LCM Random Data with seed 68237

+

hist68237

+

Figure VIII, Q-Q Plot of LCM Random Data with seed 68237

+

q68237

+

Figure IX, Histogram of R Random Uniform Data

+

histunif

+

Figure X, Q-Q Plot of R Random Uniform Data

+

qunif

+

Figure XI, Histogram of Exponential Data from LCM Random

+

histexplcm

+

Figure XII, Histogram of Exponential Data from LCM Random without Outlier Above 2

+

histexplcm_nooutlier

+

Figure XIII, Q-Q Plot of Exponential Data from LCM Rnadom

+

qexplcm

+

Figure XIV, Histogram of Exponential Data from R Random Uniform

+

histexpunif

+

Figure XV, Q-Q Plot of Exponential Data from R Random Uniform

+

qexpunif

+

Figure XVI, Histogram of R Generated Exponential Data

+

histexp

+

Figure XVII, Q-Q Plot of R Generated Exponential Data

+

qexp

+

Tables

+

Table I, Uniform Distribution Sample Data

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodMean ($\bar{x}$)Median ($\tilde{x}$)$\mu - \bar{x}$$m - \tilde{x}$
LCM with seed 555550.5050.521-0.005-0.021
LCM with seed 934630.4520.4020.0480.098
LCM with seed 293450.5200.502-0.020-0.002
LCM with seed 682370.4890.5170.011-0.017
R Random Uniform0.4800.4710.0200.029
+

Table II, Exponential Distribution Sample Data

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodMeanMedian$\mu - \bar{x}$$m - \tilde{x}$
LCM Transform0.3800.246-0.047-0.015
RUnif Transform0.2830.2180.0500.013
R Exponential0.3630.278-0.030-0.047
+

R Code

+
library(ggplot2)
+linear_congruential = function(seed) {
+  a = 69069
+  c = 0
+  m = 2^31
+  x = numeric(100)
+  x[1] = seed
+  for (i in 2:100) {
+    x[i] = (a * x[i-1] + c) %% m 
+  }
+  xnew = x / (max(x) + 1)
+  xnew
+}
+
+gcd = function(x,y) {
+  r = x %% y;
+  return(ifelse(r, gcd(y, r), y))
+}
+check_seed = function(seed) {
+  if (gcd(seed, 2^31) == 1) {
+    print(paste("The seed value of", seed, "is co-prime"))
+  } else {
+    print(paste("The seed value of", seed, "is NOT co-prime"))
+  }
+}
+
+check_data = function(data, distribution, title) {
+  print(paste("Currently looking at", title))
+  print(summary(data))
+  print(ggplot(data.frame(data), aes(x = data)) +
+    geom_histogram(fill = 'white', color = 'black', bins = 10) +
+    xlab("Date") +
+    ylab("Frequency") + 
+    ggtitle(paste("Histogram of", title)) +
+    theme_bw())
+  uqs = (1:100) / 100
+  if (distribution == "Uniform") {
+    qqplot(data, uqs, pch = 1, col = '#001155', main = paste("QQ Plot of", title), xlab = "Sample Data", ylab = "Theoretical Data")
+    qqline(uqs, distribution = qunif, col="red", lty=2)
+  } else if (distribution == "Exponential") {
+    eqs = -log(1-uqs) / 3
+    qqplot(data, eqs, pch = 1, col = '#001155', main = paste("QQ Plot of", title), xlab = "Sample Data", ylab = "Theoretical Data")
+    qqline(eqs, distribution=function(p) { qexp(p, rate = 3)}, col="#AA0000", lty=2)
+  }
+}
+
+seed1 = 55555
+seed2 = 93463
+seed3 = 29345
+seed4 = 68237
+
+check_seed(seed1)
+lin_cong = linear_congruential(seed1)
+check_data(lin_cong, "Uniform", paste("LCM Random Data with seed", seed1))
+
+check_seed(seed2)
+lin_cong2 = linear_congruential(seed2)
+check_data(lin_cong2, "Uniform", paste("LCM Random Data with seed", seed2))
+
+check_seed(seed3)
+lin_cong3 = linear_congruential(seed3)
+check_data(lin_cong3, "Uniform", paste("LCM Random Data with seed", seed3))
+
+check_seed(seed4)
+lin_cong4 = linear_congruential(seed4)
+check_data(lin_cong4, "Uniform", paste("LCM Random Data with seed", seed4))
+
+# Using the standard built-in R function
+unif = runif(100, 0, 1)
+check_data(unif, "Uniform", "R Random Uniform Data")
+
+# Building exponential from linear congruence method
+exp1 = -log(1 - lin_cong) / 3
+check_data(exp1, "Exponential", "Exponential Data from LCM Random")
+
+# Building exponential from runif
+exp2 = -log(1 - unif) / 3
+check_data(exp2, "Exponential", "Exponential Data from R Random Uniform")
+
+# Building exponential from rexp
+exp3 = rexp(100, rate = 3)
+check_data(exp3, "Exponential", "R Generated Exponential Data")
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses%2Fstat381%2Frandomwalk.html b/static/~brozek/index.html?courses%2Fstat381%2Frandomwalk.html new file mode 100644 index 0000000..cb2261e --- /dev/null +++ b/static/~brozek/index.html?courses%2Fstat381%2Frandomwalk.html @@ -0,0 +1,702 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Random Walk

+

Introduction

+

This lab features a random walk simulation that answers the following question: Given the radius of a circular room, how many random steps does it take to reach to reach the wall from the center? To explore this, we will look at the distribution of steps required and describe it in terms of a discrete probability distribution. Later on, we will look at the radius parameter and find relationships between it and the different summary statistics that we compute (mean, median, range, variance, skewness).

+

The paper will start off with the methods used in this lab. The programming language R was used and a simulation was created to simulate a random walk according to the description above. It will also discuss the methods used to find the discrete probability distribution that best fits the data and how the relationship between the radii and the summary statistics were found using regression.

+

After discussing the methods, the paper goes into the results. The discrete probability distribution of the data is revealed and the equations of the different summary statistics based on a regression of the radius is shared.

+

Methods

+

Obtaining the distribution of steps required

+

The simulation written performs the following steps given the size of a room:

+
    +
  1. Start off in the center of the room
  2. +
  3. Calculate a random angle $\theta$
  4. +
  5. Step in the X direction by $cos(\theta)$
  6. +
  7. Step in the Y direction by $sin(\theta)$
  8. +
  9. Repeat steps 2-4 until the wall is reached
  10. +
+

The number of steps required is then recorded into a vector and the simulation is performed 999 more times. This gives us the distribution of steps required to reach the wall given the room size.

+

Computing summary statistics

+

Given the distribution vector pertaining to the room size, we then find the following information:

+ +

For every room size selected, a total of three trials of 1000 simulations each is conducted.

+

Fitting the data to a distribution

+

Since the simulation counts the steps required before reaching the walls of the room, it describes the process of a geometric distribution. To confirm the suspicion, the function fitdistr inside the package MASS was used to find the parameter (probability) of the geometric distribution to best fit the simulation data. In this case the simulation data used is of room size 100.

+

The probability density histogram of the data is then shown with the overlay of the geometric distribution that best fit the data.

+

Another more robust way to visually see the goodness of fit of the distribution is to use what is called a Quantile-Quantile Plot (Q-Q Plot), Using the quantiles from the theoretical distribution, we compare it to the quantiles of the simulated data and check to see that it follows the Q-Q line closely.

+

Finding relationships between the radii and the summary statistics

+

From the simulations performed, vectors have been saved containing the summary statistics for the different room sizes. Vectors are then created from these vectors as columns inside a data frame. Having this data frame allows us to use ggplot to graph the data using scatter plots.

+

ggplot was used as opposed to the conventional base package since it allows us to add layers to the graphs, which was used to show the geometric distribution on top of the density histogram in the previous section. ggplot is also aesthetically more pleasing as it decreases the margins and makes smart choices on the shadings of the axes on the graph.

+

After plotting the data, regressions are then taken with respect to different polynomial degrees of radii and analyzed for best fit using the adjusted r squared value as a means for comparison.

+

The adjusted r squared value is a good comparator since it tells us a proportion of how much the variation in the data is accounted for by the model.

+

Results

+

The shape of the distribution matches the geometric distribution as shown in Figure IX & X. Figure IX shows how the probability density histogram nicely fits the overlay of the geometric distribution with the fitted parameters. The description of the problem closely matches the description of the geometric probability distribution and both distributions are skewed right. These observations increase our confidence that the distribution is a good fit. This can further be verified with the Q-Q Plot.

+

The Q-Q Plot in Figure X shows how the theoretical quantiles compare with the quantiles from the distribution. Since the observed sample quantiles start off in one side of the Q-Q line and ends up on the other side at the end, we can say that the data is not skewed with respect to the theoretical distribution. This along with the fact that the sample quantiles closely fit the Q-Q line supports the proposition that the geometric distribution is a good fit for the steps required in the random walk.

+

Regressions were then performed for each summary statistic and the models that had the lowest degree polynomial with respect to radii and with relatively small standard error were chosen.

+

For the mean, quadratic regression was performed and it produces the following model +$$ +\mu(Steps) = -31.409 + 7.800(radii) + 0.837(radii^2) +$$ +With this model, the adjusted $r^2$ value is 99.938%, which tells us that 99.938% of the variation in means is accounted for by the quadratic regression above. It's fit to the observed values can be seen in Figure XI.

+

For the median, quadratic regression was performed and produces the following model +$$ +\widetilde{Steps} = -19.525 + 5.096(radii) + 0.687(radii^2) +$$ +The model above has an adjusted $r^2$ value of 99.957% which tells us that 99.957% of the variation in medians is accounted for by the regression above. It's fit to the observed values can be seen in Figure XIII.

+

For the range, the quadratic regression performed creates the following model +$$ +Range(Steps) = 63.873 - 9.073(radii) + 5.572(radii^2) +$$ +The model has an adjusted $r^2$ value of 99.278% which tells us that 99.278% of the variation in the ranges of steps is accounted for by the regression above. It's fit to the observed values can be seen in Figure XV.

+

For the variance, the cubic regression performed creates the following model +$$ +\sigma^2(Steps) = -88471.866 + 32256.076(radii) - 2418.835(radii^2) + 61.650(radii^3) +$$ +The model has an adjusted $r^2$ value of 99.779% which tells us that 99.779% of the variation in the variations of steps is accounted for by the regression above. It's fit to the observed values can be seen in Figure XVII

+

Looking at the scatter plot of radii vs skewness of steps shown in Figure XVIII, there appears to be no relationship between the radii and skewness of steps. What the scatter plot suggests that the skewness is uniformly distributed.

+

Conclusions

+

In summation, the distribution of steps required to reach the end of the wall follow a geometric distribution. This was backed up using the probability density histogram and the Q-Q Plot.

+

Most of the summary statistics follow a quadratic regression while the variation follows a cubic regression. Skewness are uniformly distributed across the different simulations.

+

In other words, the mean, median, and range follow a function that is a second degree polynomial based on the size of the room ($r^2$) and the variation follows a function that is a third degree polynomial based on the size of the room $(r^3)$

+

Appendix

+

Tables

+

Table I, Summary Statistics for Room Radius of 2

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrialMeanMedianVarianceRangeSkewness
15.8275.00013.47136.0002.446
25.7615.00010.63522.0001.780
35.8055.00011.43021.0001.882
+

Table II, Summary Statistics for Room Radius of 3

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrialMeanMedianVarianceRangeSkewness
111.5669.00059.05560.0001.854
211.94010.00074.48768.0002.467
311.2429.00053.41748.0001.922
+

Table III, Summary Statistics for Room Radius of 4

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrialMeanMedianVarianceRangeSkewness
119.30615.000171.68890.0001.721
218.12715.000143.28474.0001.712
318.99315.000180.892111.0002.089
+

Table IV, Summary Statistics for Room Radius of 5

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrialMeanMedianVarianceRangeSkewness
129.27223.000405.817150.0001.737
228.38222.000402.801146.0001.862
327.89122.000390.221211.0002.308
+

Table V, Summary Statistics for Room Radius of 10

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrialMeanMedianVarianceRangeSkewness
1110.23487.0006070.976547.0001.780
2109.59488.0005928.037542.0001.864
3108.39886.0006469.467621.0002.191
+

Table VI, Summary Statistics for Room Radius of 25

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrialMeanMedianVarianceRangeSkewness
1623.260492.000197161.832621.965
2637.890511.000212826.633942.009
3653.661528.5211126.236941.841
+

Table VII, Summary Statistics for Room Radius of 50

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrialMeanMedianVarianceRangeSkewness
12507.9351939.03231980114711.726
224675.6151992.03248443141502.060
32488.7952001.53038915146891.843
+

Table VIII, Summary Statistics for Room Radius of 100

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrialMeanMedianVarianceRangeSkewness
18983.4067257.038271895525492.027
29372.9177537.041658620518101.867
38974.5497294.541868765603262.420
+

Figures

+

Figure I, Histogram of Room Radius 2

+

img

+

Figure II, Histogram of Room Radius 3

+

img

+

Figure III, Histogram of Radius 4

+

img

+

Figure IV, Histogram of Radius 5

+

img

+

Figure V, Histogram of Radius 10

+

img

+

Figure VI, Histogram of Radius 25

+

img

+

Figure VII, Histogram of Radius 50

+

img

+

Figure VIII, Histogram of Radius 100

+

img

+

Figure IX, Probability Density Histogram

+

img

+

Figure X, QQ-Plot of Theoretical vs Sample Data

+

img

+

Figure XI, Scatterplot of Radii vs Mean Steps

+

img

+

Figure XII, Scatterplot with Quadratic Regression of Radii vs Mean Steps

+

img

+

Figure XIII, Scatterplot of Radii vs Median Steps

+

img

+

Figure XIV, Scatterplot with Quadratic Regression of Radii vs Median Steps

+

img

+

Figure XV, Scatterplot of Radii vs Range of Steps

+

img

+

Figure XVI, Scatterplot with Quadratic Regression of Radii vs Range of Steps

+

img

+

Figure XVII, Scatterplot of Radii vs Variance of Steps

+

img

+

Figure XVIII, Scatterplot with Cubic Regression of Radii vs Variance of Steps

+

img

+

Figure XIX, Scatterplot of Radii vs Skewness

+

img

+

R Code

+
rm(list=ls())
+library(moments)
+library(ggplot2)
+
+simulateRoom = function(r) {
+  n = 1000
+  results = numeric(n)
+  x = 0
+  y = 0
+  dist = 0
+  num = 0 
+  for (i in 1:n) {
+    while(dist < r) {
+      deg = runif(1, min=0, max=360)
+      newx = cos(deg)
+      newy = sin(deg)
+      x = x + newx
+      y = y + newy
+      num = num+ 1
+      dist=(x^2 + y^2)^0.5
+    }
+    results[i] = num
+    x= 0
+    y = 0
+    dist = 0
+    num = 0
+    i = i + 1
+  }
+  return(results)
+}
+
+repetitions = 3
+radii = c(2, 3, 4, 5, 10, 25, 50, 100)
+
+median_stepcount = c()
+mean_stepcount = c()
+variance_stepcount = c()
+range_stepcount = c()
+skewness_stepcount = c()
+for (r in radii) {
+  room_data = data.frame()
+  print(paste("Currently simulating r =", r))
+  for (i in 1:repetitions) {
+    simulation = simulateRoom(r)
+
+    ## Summary Statistics
+    variance = var(simulation)
+    skewness_ = skewness(simulation)
+    range_data = range(simulation)
+
+    room_data_temp = data.frame(i, mean(simulation), median(simulation), variance, range_data[2] - range_data[1], skewness_)
+    names(room_data_temp) = c("Trial", "Mean", "Median", "Variance", "Range", "Skewness")
+    room_data = rbind(room_data, room_data_temp)
+
+    median_stepcount = c(median_stepcount, median(simulation))
+    mean_stepcount = c(mean_stepcount, mean(simulation))
+    variance_stepcount = c(variance_stepcount, variance)
+    range_stepcount = c(range_stepcount, range_data[2] - range_data[1])
+    skewness_stepcount = c(skewness_stepcount, skewness_)
+
+    simulation = data.frame(simulation)
+    print(ggplot(simulation, aes(x = simulation)) +
+      geom_histogram(color = 'black', fill = 'white') + 
+      xlab("Steps") + 
+      ylab("Count") +
+      ggtitle(paste("Distribution of r =", r)) +
+      theme_bw())
+  }
+  print(room_data)
+}
+
+## Show the probability distribution
+library(MASS)
+distribution = fitdistr(simulation$simulation, "geometric")
+probability_simulation = data.frame(simulation, 
+                          rgeom(1:1000, distribution$estimate['prob']))
+names(probability_simulation) = c("simulation", "geometric")
+ggplot(data = probability_simulation, aes(x = simulation)) + 
+  geom_histogram(aes(y = ..density..), color = 'black', fill = 'white') +
+  geom_density(aes(x = geometric), fill = '#0000AA', alpha = .5) +
+  xlab("Steps") +
+  ylab("Probability Density") +
+  ggtitle("Probability Density Histogram with Geometric Overlay") +
+  theme_bw()
+
+## Calculate QQ Plot of Geometric Distribution and Sample
+yquantiles = quantile(simulation$simulation, c(0.25, 0.75))
+xquantiles = qgeom(prob = distribution$estimate['prob'], c(0.25, 0.75)) 
+slope = diff(yquantiles) / diff(xquantiles)
+intercept = yquantiles[1] - slope * xquantiles[1]
+ggplot() + aes(sample=simulation$simulation) + 
+  stat_qq(distribution=qgeom, dparams = distribution$estimate['prob']) + 
+  geom_abline(intercept=intercept, slope=slope) +
+  ggtitle("QQ Plot of Geometric Distribution") +
+  xlab("Theoretical Quantiles") +
+  ylab("Sample Quantiles") +
+  theme_bw()
+
+## Create a dataframe
+room_simulation_data = data.frame(as.vector(sapply(radii, function(x) { rep(x, repetitions)})), mean_stepcount, median_stepcount, range_stepcount, skewness_stepcount, variance_stepcount)
+names(room_simulation_data) = c("radii", "mean_stepcount", "median_stepcount", "range_stepcount", "skewness_stepcount", "variance_stepcount")
+######### ANALYSIS OF MEANS
+ggplot(room_simulation_data, aes(x = radii, y = mean_stepcount)) +
+  geom_point(shape = 21, size = 2) + 
+  xlab("Radii") +
+  ylab("Mean Steps") +
+  ggtitle("Radii vs Mean Steps") +
+  theme_bw()
+
+## Quadratic Regression of Means
+quadratic_mean_model = lm(mean_stepcount ~ poly(radii, 2, raw = T), data = room_simulation_data)
+quadratic_mean_model_summary = summary(quadratic_mean_model)
+ggplot(room_simulation_data, aes(x = radii, y = mean_stepcount)) +
+  geom_point(shape = 21, size = 2) + 
+  geom_smooth(method = "lm", formula = y ~ poly(x, 2, raw = T), se = T) +
+  xlab("Radii") +
+  ylab("Mean Steps") +
+  ggtitle("Radii vs Mean Steps") +
+  theme_bw()
+
+## Analysis of Quadratic Regression of Means
+quadratic_mean_coefficients = as.vector(quadratic_mean_model$coefficients)
+print(paste("The quadratic regression equation is: Mean Steps =", quadratic_mean_coefficients[1], "+", quadratic_mean_coefficients[2], "radii", quadratic_mean_coefficients[3], "radii^2"))
+print(paste(quadratic_mean_model_summary$adj.r.squared * 100, "% of the variation of the means is accounted for by the Quadratic Model", sep = ""))
+
+######### ANALYSIS OF MEDIANS
+ggplot(room_simulation_data, aes(x = radii, y = median_stepcount)) +
+  geom_point(shape = 21, size = 2) + 
+  xlab("Radii") +
+  ylab("Median Steps") +
+  ggtitle("Radii vs Median Steps") +
+  theme_bw()
+
+## Quadratic Regression of Medians
+quadratic_median_model = lm(median_stepcount ~ poly(radii, 2, raw = T), data = room_simulation_data)
+quadratic_median_model_summary = summary(quadratic_median_model)
+ggplot(room_simulation_data, aes(x = radii, y = median_stepcount)) +
+  geom_point(shape = 21, size = 2) + 
+  geom_smooth(method = "lm", formula = y ~ poly(x, 2, raw = T), se = T) +
+  xlab("Radii") +
+  ylab("Median Steps") +
+  ggtitle("Radii vs Median Steps") +
+  theme_bw()
+
+## Analysis of Quadratic Regression of Medians
+quadratic_median_coefficients = as.vector(quadratic_median_model$coefficients)
+print(paste("The Quadratic Regression Equation is: Median Steps =", quadratic_median_coefficients[1], "+", quadratic_median_coefficients[2], "radii", quadratic_median_coefficients[3], "radii^2"))
+print(paste(quadratic_median_model_summary$adj.r.squared * 100, "% of the variation of the medians is accounted for by the Quadratic Model", sep = ""))
+
+######### ANALYSIS OF RANGES
+ggplot(room_simulation_data, aes(x = radii, y = range_stepcount)) +
+  geom_point(shape = 21, size = 2) + 
+  xlab("Radii") +
+  ylab("Range of Steps") +
+  ggtitle("Radii vs Range Steps") +
+  theme_bw()
+
+## Quadratic Regression of Ranges
+quadratic_range_model = lm(range_stepcount ~ poly(radii, 2, raw = T), data = room_simulation_data)
+quadratic_range_model_summary = summary(quadratic_range_model)
+ggplot(room_simulation_data, aes(x = radii, y = range_stepcount)) +
+  geom_point(shape = 21, size = 2) + 
+  geom_smooth(method = "lm", formula = y ~ poly(x, 2, raw = T), se = T) +
+  xlab("Radii") +
+  ylab("Range of Steps") +
+  ggtitle("Radii vs Range of Steps") +
+  theme_bw()
+
+## Analysis of Quadratic Regression of Ranges
+quadratic_range_coefficients = as.vector(quadratic_range_model$coefficients)
+print(paste("The Quadratic Regression Equation is: Range of Steps =", quadratic_range_coefficients[1], "+", quadratic_range_coefficients[2], "radii", quadratic_range_coefficients[3], "radii^2"))
+print(paste(quadratic_range_model_summary$adj.r.squared * 100, "% of the variation of the ranges is accounted for by the Quadratic Model", sep = ""))
+
+######### ANALYSIS OF SKEWNESS
+ggplot(room_simulation_data, aes(x = radii, y = skewness_stepcount)) +
+  geom_point(shape = 21, size = 2) + 
+  xlab("Radii") +
+  ylab("Skewness") +
+  ggtitle("Radii vs Skewness Steps") +
+  theme_bw()
+
+######### ANALYSIS OF VARIANCES
+ggplot(room_simulation_data, aes(x = radii, y = variance_stepcount)) +
+  geom_point(shape = 21, size = 2) + 
+  xlab("Radii") +
+  ylab("Variance of Steps") +
+  ggtitle("Radii vs Variance Steps") +
+  theme_bw()
+
+## Cubic Regression of Variance
+cubic_variance_model = lm(variance_stepcount ~ poly(radii, 3, raw = T), data = room_simulation_data)
+cubic_variance_model_summary = summary(cubic_variance_model)
+ggplot(room_simulation_data, aes(x = radii, y = variance_stepcount)) +
+  geom_point(shape = 21, size = 2) + 
+  geom_smooth(method = "lm", formula = y ~ poly(x, 3, raw = T), se = T) +
+  xlab("Radii") +
+  ylab("Variance of Steps") +
+  ggtitle("Radii vs Variance of Steps") +
+  theme_bw()
+
+## Analysis of Cubic Regression
+cubic_variance_coefficients = as.vector(cubic_variance_model$coefficients)
+print(paste("The Cubic Regression Equation is: Variance of Steps =", cubic_variance_coefficients[1], "+", cubic_variance_coefficients[2], "radii", cubic_variance_coefficients[3], "radii^2", cubic_variance_coefficients[4], "radii^3"))
+print(paste(cubic_variance_model_summary$adj.r.squared * 100, "% of the variation of the variations is accounted for by the Cubic Model", sep = ""))
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?courses.html b/static/~brozek/index.html?courses.html new file mode 100644 index 0000000..0996c91 --- /dev/null +++ b/static/~brozek/index.html?courses.html @@ -0,0 +1,90 @@ + + + + + + + + + Courses | Brandon Rozek + + + + + + +
+
+

Courses

+

Below are the courses that I have documents up online for.

+

Probability and Statistical Inference I

+

Coursera Courses

+

Occassionally during breaks, I like to take some coursera courses. I will post my notes from the lecture here as well.

+

Bayesian Statistics

+

Reproducible Research

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?index.html b/static/~brozek/index.html?index.html new file mode 100644 index 0000000..a34b626 --- /dev/null +++ b/static/~brozek/index.html?index.html @@ -0,0 +1,89 @@ + + + + + + + + + Home | Brandon Rozek + + + + + + +
+
+

Brandon Rozek's Tilda Space

+

Welcome

+

My main website is https://brandonrozek.com. Though I like the customization that Wordpress allows, it does come with additional overhead.

+

Therefore, I decided to use the Tilda space offered by the Computer Science department to host content pertaining to my Academic Life.

+

As such, my research and other class documents will appear here.

+

For the curious, this website was built with Pico CMS using the BitsAndPieces theme.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fdec6.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fdec6.html new file mode 100644 index 0000000..280af3f --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fdec6.html @@ -0,0 +1,162 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Final Review December 6

+

Classes

+

Here is how you can create a class called "Employee" with a non-default constructor (a constructor that takes parameters) and a getter and setter

+
public class Employee {
+  // Our private variables
+  private String name;
+  private double salary;
+  // Non-default constructor
+  public Employee(String name, double salary) {
+    this.name = name;
+    this.salarly = salary;
+  }
+  // This is a getter
+  public string getName() {
+    return name;
+  }
+  public double setSalarly(double salary) {
+    this.salary = salary;
+  }
+}
+

For Loops + Arrays

+

For loops are constructed in the following way

+

for (initialization; condition to stop; increment to get closer to condition to stop)

+
//Assume an array with variable name array is declared before
+for (int i = 0; i < array.length; i++) {
+  // This code will loop through every entry in the array
+}
+

Note that you don't always have to start from zero, you can start anywhere from the array.

+

For Loops + Arrays + Methods

+

This is an example of how you can take in an array in a method

+
public static boolean isEven(int[] array) { // <-- Note the int[] array
+  for (int i = 0; i < array.length; i++) { // Iterate through the entire array
+    // If you find an odd number, return false
+    if (array[i] % 2 == 1) {
+      return false;
+    }
+  }
+  // If you didn't find any odd numbers, return true
+  return true;
+}
+

File I/O

+

Let's say that you have the following file

+
4
+chicken
+3
+salad
+

And you want to make it so that you take the number, and print the word after it a certain number of times. For this example we would want to see the following

+
chicken chicken chicken chicken
+salad salad salad
+

Here is the code to write it

+
public static void printStrings() {
+  FileInputStream file = new FileInputStream("stuff.txt"); // File contents are in stuff.txt
+  Scanner scnr = new Scanner(file); // Scanner takes in a file to read
+  while (scnr.hasNext()) { // While there are still stuff in the file to read
+    int number = scnr.nextInt(); // Grab the number
+    String word = scnr.next(); // Grab the word after the number
+    // Print the word number times
+    for (int i = 0; i < number; i++) {
+      System.out.print(word); 
+    }
+    // Put a new line here
+    System.out.println();
+  }
+
+}
+

Recursion

+

Look at handout and carefully trace recursion problems

+

2D Arrays

+

Declare a 2D int array with 4 rows and 7 columns

+
int[][] dataVals = new int[4][7];
+

A 2D array with 4 rows and 7 columns has 7 * 4 = 28 entries.

+

If you want to sum up all the numbers in a 2 dimensional array, do the following

+
// Assume numbers is declared beforehand
+int sum = 0;
+for (int i = 0; i < numbers.length; i++) { // Loop through every row in the 2D array
+  for (int j = 0; j < numbers[i].length; j++) { // Loop through every column in a row
+    // This code now looks at one entry in a 2D array
+    sum += numbers[i][j];
+  }
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fexam2review.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fexam2review.html new file mode 100644 index 0000000..589ae08 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fexam2review.html @@ -0,0 +1,124 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Exam Review Partial Answer Sheet

+

Write a Java method to sum values of an array

+
// Assume variable numbers is an array of 10 integers
+int sum = 0;
+for (int i = 0; i < numbers.length; i++) {
+    sum += numbers[i];
+}
+

Write a Java method to test if an array contains a specific value

+
// Assume variable numbers is an array of 10 integers
+int numWanted = 4;
+boolean found = false;
+for (int i = 0; i < numbers.length; i++) {
+    if (numbers[i] == numWanted) {
+      System.out.println("The number " + numWanted + " was found!");
+      found = true;
+    }
+}
+if (!found) {
+    System.out.println("The number " + numWanted + " was not found!");
+}
+

Write a Java method to find the index of an array element

+
// Assume variable numbers is an array of 10 integers
+int numWanted = 4;
+boolean found = false;
+for (int i = 0; i < numbers.length; i++) {
+    if (numbers[i] == numWanted) {
+      System.out.println("The index of number " + numWanted + " is " + i);
+    }
+}
+

How many lines will the following loop print when it is run?

+
int i = 0;
+while (i <= 6) {
+  System.out.println("i is now " + (i));
+  i++;
+}
+
i is now 0
+i is now 1
+i is now 2
+i is now 3
+i is now 4
+i is now 5
+i is now 6
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov13.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov13.html new file mode 100644 index 0000000..9969a85 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov13.html @@ -0,0 +1,222 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for November 13

+

File IO (Cont.)

+

Last class we talked about reading from files, we can also write to files.

+

Import necessary libraries

+

First you must import all of the necessary libraries

+
// To read 
+import java.util.Scanner; 
+import java.io.FileOutputStream;
+// To Write
+import java.io.FileReader;
+import java.io.PrintWriter;
+// For Exception Handling
+import java.io.IOException;
+

Then in your main, declare a FileOutputStream and PrintWriter

+
FileOutputStream file;
+PrintWriter print;
+

Try-Catch-Finally

+

Create a try block to open a file for writing

+
try {
+      // If the file doesn't exist, it'll create it
+      file = new FileOutputStream("output.txt"); 
+      print = new PrintWriter(file);
+} catch (IOException except) {
+      // Prints out the error message
+      System.out.println("File error " + except.getMessage()); 
+} 
+

Adding a finally block allows the program to clean up before it closes

+
    try {
+      file = new FileOutputStream("output.txt"); 
+      print = new PrintWriter(file);
+    } catch (IOException except) {
+      System.out.println("File error " + except.getMessage()); 
+    } finally { // It starts here!
+      delete file;
+      delete print;
+      file.close();
+      return;
+    }
+

Write to the file :)

+

Then you can write the to file!

+
// Do you notice the following methods?
+  print.println("Your number is");
+  print.print("My name is..\n");
+  print.printf("%s %d", "Hello ", 5);
+  print.flush(); //Clears the output stream
+  file.close(); //Closes the file
+
+

Extra Note: Disk fragmentation is a way of cleaning up memory that isn't being used by any of the code on your computer.

+

Swing Graphics

+

Importing Necessary Libraries

+

You need to import all the necessary libraries first

+
import javax.swing.*;
+import java.awt.FlowLayout;
+import java.awt.event.ActionListener;
+

Changing the class header

+

Your class file needs to extend JFrame that way it can use a bunch of the already existent code written for Swing applications

+
public class firstGUi extends JFrame {
+  //....
+

Swing Components

+

Java Swing makes use of what is called Swing Components. These are basic building blocks of GUI items you can add to the screen. For example, a checkbox, a radio button, text field. These are all swing components.

+

I wrote a blog post back in the summer which is an overview of them. You can check it out here: https://brandonrozek.com/2017/06/java-swing-components/

+

Inside your firstGUI class, declare some Swing components you would like to use in the program

+
public class firstGUI extends JFrame {
+  JButton button1;
+  JTextArea area;
+  JTextField text;
+  // ....
+
+

Constructor

+

You need to create a constructor for this class that way you can initiate all of the swing component values.

+
// ...
+JButton button1;
+JTextArea area;
+JTextField text;
+
+// Begin Constructor
+firstGUI() {
+  // Define the components
+  JLabel name = new JLabel("Enter in your name:");
+  text = new JTextField("Jennifer", 20); // 20 characters long, default value: Jennifer
+  area = new JTextArea(10, 10); //Width and Height is 10 characters big
+  JScrollPane sp = new JScrollPane(area); //Adds a scroll bar for the text area
+  button1 = new JButton("Press Me");
+
+  // Set the Layout
+  // FlowLayout organizes each of the components top to bottom, left to right
+  setLayout(new FlowLayout()); 
+
+  // Add the components to the screen
+  add(name);
+  add(text);
+  add(sp); // never add the textarea when surrounded by a ScrollPane
+  add(button1);
+}
+

New Main Method

+

Finally, you need to create the Main method which will initiate it all

+
public static void main(String[] args) {
+  firstGUI myFrame = new firstGUI();
+
+  // End the program when the 'x' button (not keyboard) is pressed
+  myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+  myFrame.setTitle("My title"); // Titles the window
+  myFrame.pack(); // Packs it all into the frame
+  myFrame.setVisible(true); // Makes the frame appear on the screen
+}
+

Making it interactive

+

You need to change your class header to the following

+
public class firstGUI extends JFrame implements ActionListener {
+  // ...
+

Then in your class, add the following method

+
@Override public void actionPerformed(ActionEvent event) {
+  // Do stuff as a result of an event here
+  area.append("You Pressed the Button");
+}
+

To make it actually activate as a result of an event. You need to attach it to a swing component.

+

For example, I want the code in actionPerformed to activate in result of a button press.

+

Add the following line to your code in the constructor.

+
//...
+button1 = new JButton("Press Me");
+button1.addActionListener(this); // New Code
+//....
+

Identifying Button Pressed

+

How do you know which button was pressed in the actionPerformed method?

+

You can use event.getSource() to find out.

+

Example:

+
@Override public void actionPerformed(ActionEvent event) {
+  if (event.getSource() == button1) { // Replace button1 with appropriate variable name
+    // Do things as a result of a specific button being pressed
+  }
+}
+

Summary

+

To use Swing, do the following steps

+
    +
  1. Import Libraries
  2. +
  3. Declare J___ variables
  4. +
  5. New the J___ variables
  6. +
  7. Add the J___ variables to the frame
  8. +
  9. Add the ActionListener to the components you wish to monitor
  10. +
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov15.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov15.html new file mode 100644 index 0000000..445925b --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov15.html @@ -0,0 +1,175 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture Notes for November 15th

+

Import the necessary libraries

+
import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+

This time we'll be using the null layout. This will require you to set the x, and y positions of each of the elements on the screen

+

First we'll make a class called GUILayout which will extend JPanel and contain our layout and components

+
import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+public class GUILayout extends JPanel {
+  private JButton one, two;
+  private JTextField text;
+  private JTextArea area;
+  private int count; // Used to keep track of button pushes
+  private int number = 0;
+
+  GUILayout() {
+    // Set the layout to the null layout
+    setLayout(null);
+    // Tells the computer that you wish to have the size of your program to be 500x500
+    setPreferredSize(new Dimension(500, 500));
+
+    // Create the buttons
+    one = new JButton("Change color");
+    two = new JButton("Count Pushes");
+
+    // Set the x, y, width, height inside parenthesis
+    // This places the buttons on the specified locations on the screen
+    one.setBounds(10, 10, 100, 24);
+    two.setBounds(120, 10, 100, 24);
+
+    // Sets the color of the text of button 1 to blue
+    one.setForeground(Color.BLUE); 
+
+    // Add the components to the screen
+    add(one);
+    add(two);
+
+    text = new JTextField("Today is Wednesday, a photographer is here.");
+    text.setBounds(10, 40 ,480, 24);
+    add(text);
+
+    area = new JTextArea(20, 20); 
+    // Wrap the text area into the scroll pane
+    // This adds the scroll bars (vertical/horizontal)
+    JScrollPane sp = new JScrollPane(area);
+    sp.setBounds(10, 75, 490, 400);
+    add(sp);
+
+    // Bind the Listener class to the button one
+    one.addActionListener(new Listener());
+
+    // Bind it to two and text
+    two.addActionListener(new Listener());
+    text.addActionListener(new Listener());
+
+  }
+
+  // Create the class for the listener
+  private class Listener implements ActionListener {
+    // Define what you want to occur after an event
+    public void actionPerformed(ActionEvent event) {
+      if (event.getSource() == one) {
+
+      } else if (event.getSource() == two) {
+        count++;
+        // \n is needed to prevent scrolling
+        area.append("You pressed the button " + count + " times!"); 
+      } else if (event.getSource() == text) {
+        // Grab the number inside the text area and set it to the variable number
+        number = Integer.paseInt(text.getText());
+        number += 10;
+        // add "" to number so that it converts number to a String
+        text.setText(number + ""); 
+        // Convert the number to a String
+        String temp = Integer.toString(number);
+        area.setText(temp);
+      }
+
+    }
+  }
+}
+

The main code is really short, you just need to extend JFrame and some short code seen last class to set it up.

+
public class mainTester extends JFrame {
+  public static void main(String[] args) {
+    JFrame frame = new JFrame("Sample GUI"); // Sets the title to "Sample GUI"
+    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+    // Instantiate the GUILayout file you made before
+    frame.getContentPane().add(new GUILayout()); 
+  }
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov20.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov20.html new file mode 100644 index 0000000..a1a1624 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov20.html @@ -0,0 +1,174 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for November 20

+

Adding a drawing panel to the GUI

+

You can't put swing and graphics together, therefore you need to make a seperate JPanels for swing and graphics.

+

Add necessary libraries

+
import java.awt.*;
+import java.awt.Graphics;
+import java.awt.event.*;
+import javax.swing.*;
+
public class drawingWindow extends JPanel {
+  JTextField field;
+  JButton draw;
+  DrawingPanel drawingPanel;
+
+  public drawingWindow() {
+    // Each new component would be vertically stacked upon each other
+    setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+
+    JPanel swingSTuff = new JPanel();
+
+    // Add things to the screen    
+    draw = new JButton("Draw");
+    field = new JTextField();
+    swingStuff.add(field);
+    swingStuff.add(draw)
+
+    // Add the drawing panel onto the screen
+    drawingPanel = new DrawingPanel(200, 400);
+    add(drawingPanel);
+
+    // Activate the listener if the button was pressed
+    draw.addActionListener(new Listener());
+  }
+
+  // Add the listener to respond to events
+  private class listener implements ActionListener {
+    public void actionPerformed(ActionEvent event) {
+      if (event.getSource() == draw) {
+        drawingPanel.setFlag(1);
+        // Repaints the screen so the oval can appear
+        drawingPanel.repaint();
+      }
+    }
+  }
+
+  // Create the draw panel so we can add it to the screen
+  private class DrawingPanel extends JPanel {
+    private int width, height;
+    DrawingPanel(int width, int height) {
+      this.width = width;
+      this.height = height;
+      setPreferredSize(new Dimension(width, height));
+    }
+    public void setFlag(int flag) {
+      this.flag = flag;
+    }
+    public void paintComponent(Graphics g) {
+        super.paintComponent(g);
+
+        // Every time the flag is set, draw an oval at a random location and color
+        if (flag == 1) {
+        Random rand = new Random();
+        int x = rand.nextInt(width);
+        int y = rand.nextInt(height);
+        g.setColor(Color.RED);
+        g.fillOval(x, y, 20, 30);
+        }
+    }
+  }
+}
+

There are a myriad of different methods you can use.

+
// Assume width, height, y, x, etc are defined above 
+public void paintComponent(Graphics g) {
+  //....
+  g.dispose(); // Flushes the graphics buffer
+}
+

You have the traditional fill and draw methods. Fill creates the shape shaded in with a color. Draw creates an outline of the shape.

+

+// ...
+g.fillRect(x ,y, width, height);
+  g.drawRect(x, y, width, height);
+  g.fillOval(x, y, width, height);
+  g.drawOval(x, y, width, height);
+  //g.drawPoly(parematers...);
+  //g.fillPoly(parameters...);
+  g.drawArc(x, y, width, height, startingAngle, sweepingAngle);
+  g.fillArc(x, y, width, height, startingAngle, sweepingAngle);
+

You can also create complex shapes like a polygon. When adding points, you need to make sure you add them Clockwise or Counterclockwise (but NOT both)

+
  Polygon tri = new Polygon();
+  tri.addPoint(150, 10);
+  tri.addPoint(175, 100);
+  tri.addPoint(125, 100);
+  // Add points clockwise or counterclockwise (NOT BOTH)
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov27.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov27.html new file mode 100644 index 0000000..72bd436 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov27.html @@ -0,0 +1,257 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for November 27

+

Recursion

+

When doing recursion, make sure not to use loops.

+

Recursion is when a function makes a function call to itself.

+

It consists of two parts:

+ +

You can have one or more base cases or caller cases.

+

To teach recursion, we'll start with a problem that should be written iteratively (with loops) but we'll show how to do it with recursion.

+

Example: Counting Down

+
void CountDown(int number) {
+  while (number > 0) {
+    System.out.println(number + " ");
+    number = number - 1;
+  }
+  System.out.println("Blast Off")
+}
+
    +
  1. How does this loop stop? -- Base Case
  2. +
  3. How does this loop change each time through? -- Smaller caller case
  4. +
+

Base Case: It stops when the number equals 0

+
// Base Case
+if (number == 0) {
+  System.out.println("Blast Off");
+  return;
+}
+

Smaller Caller Case: It decreases number by 1

+
// Smaller Caller Case
+System.out.print(number + " ");
+countDownRecursive(number - 1);
+

Put it together...

+
void countDownRecursive(int number) {
+  if (number == 0) {
+    System.out.println("Blast Off");
+  } else {
+    System.out.print(number + " ");
+    countDownRecursive(number - 1);
+  }
+}
+

Prints 10 9 8 7 6 5 4 3 2 1 Blast Off

+

Stack Snapshots

+

Every time you make a recursive call, it keeps track of all the local variables at the current function call and pushes it onto the stack.

+

That means if you make 10 recursive calls, you'll have 10 slots added onto the stack. If you want to return back to the beginning, you would need to return 10 times.

+

Order Matters

+

Whether you do the recursive step first or some other action, it completely changes the output. Look at the following example that's similar to countDownRecursive.

+
void countUpRecursive(int number) {
+  if (number == 0) {
+    System.out.println("Blast Off");
+  } else {
+    // Notice the swapping of the next two lines
+    countUpRecursive(number - 1);
+    System.out.print(number + " ");
+  }
+}
+

This would print out Blast Off 1 2 3 4 5 6 7 8 9 10

+

Example: Summing up to a number

+

This would be our iterative solution

+
int sum(int number) {
+  int sum = 0;
+  while (number > 0) {
+    sum += number;
+    number--;
+  }
+  return sum;
+}
+

How does this loop stop?

+

​ Same as before. Think about it, if the number you pass in is zero, what should be the result of sum? Zero. Since adding up from 0 to 0 is just 0.

+
if (number == 0) {
+  return 0;
+}
+

How does this loop change each time through?

+

​ You want to update your sum, so return the sum of the next call to the current sum.

+
return (number + sum(number - 1));
+

Putting it all together

+
int sumRecursive(int number) {
+  if (number == 0) {
+    return 0;
+  } else {
+    return number + sumRecursive(number - 1);   
+  }
+}
+

Example: Linear Search

+

How to do it iteratively.

+
void linearSearch(int[] array, int number) {
+  int i = 0;
+  while (i < array.length && number != array[i]) {
+    i++;
+  }
+  if (i == array.length) {
+    System.out.println("Not Found");
+  } else {
+    System.out.println("Found");
+  }
+}
+

Base Case: There are two base cases, when it reaches the end of the array and when it finds the number

+
if (array.length == i) {
+  System.out.println("Not Found");
+} else (array[i] == number) {
+  System.out.println(number + " found at index " + i);
+}
+

Smaller Caller Case: Check the next element

+
linearSearchRecursion(number, array, i + 1);
+

Putting it all together...

+
void linearSearchRecursion(int[] array, int number) {
+  if (array.length == i) {
+    System.out.println("Not Found");
+  } else if (array[i] == number) {
+    System.out.println(number + " found at index " + index);
+  } else {
+    linearSearchRecursion(number, array, i + 1);
+  }
+}
+

Binary Search

+

This is a much more efficient search than the linear search we have been doing. The only condition is that your array must be sorted beforehand.

+

A regular linear search O(n) -- Check at most all of the elements of the array.

+

Binary Search O(log(n)) -- Checks at most ceil(log(n)) elements of an array.

+

To demonstrate this with real numbers, let's take an array of 100 elements

+ +

Crazy right?

+

Implementation

+

Iterative approach

+
void binarySearch(int number, int[] array) {
+  int lower = 0;
+  int upper = array.length - 1;
+  int mid = (lower + upper) / 2
+  while (lower <= upper && array[mid] != number) {
+    mid = (lower + upper) / 2;
+    if (array[mid] < number) {
+      lower = mid + 1;
+    } else if () {
+      upper = mid -1;
+    }
+  }
+  if (lower > upper) {
+    System.out.println("Not Found");
+  } else {
+    System.out.println(number + " found at index " + mid);
+  }
+}
+

Recursive Approach

+

Base Case: There are two cases, you either found it, or you made it to the end of the array without finding it

+
if (lower > upper) {
+  System.out.println("Not Found");
+} else if (array[mid] == number) {
+  System.out.println(number + " found at index " + mid);
+}
+

Smaller Caller Case: Change the lower or upper bounds to cut the search in half

+
if (array[mid] < number) {
+  lower = mid + 1;
+  binarySearchRecursive(number, array, lower, upper);
+} else if (array[mid] > number) {
+  upper = mid - 1;
+  binarySearchRecursive(number, array, lower, upper);
+}
+

Putting it together....

+
binarySearch(int number, int[] array, int lower, int upper) {
+  if (lower > upper) {
+    System.out.println("Not Found");
+  } else if (array[mid] == number) {
+    System.out.println(number + " found at index " + mid);
+  }
+  else if (array[mid] < number) {
+    lower = mid + 1;
+    binarySearchRecursive(number, array, lower, upper);
+  } else if (array[mid] > number) {
+    upper = mid - 1;
+    binarySearchRecursive(number, array, lower, upper);
+  }
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov6.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov6.html new file mode 100644 index 0000000..8a34092 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fnov6.html @@ -0,0 +1,182 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

November 6th Lecture

+

Compare cont.

+

Continuing from last week's topic, writing a function called compare in your custom class.

+

For example, for your project:

+
public bool compare(ResearchProject right, int type) {
+  if (type == 0) { // Is last lastname greater than right lastname alphabeticallly
+    if (lastname.compareTo(right.lastname) > 0) {
+      return true;
+    } else {
+      return false;
+    }
+  } else if (type == 1) { // Implement a different type of comparison
+
+  }
+}
+

You can then use the sorting algorithms discussed previously to sort the ResearchProjects using the compare method.

+

File IO

+

First start by importing the required libraries.

+
import java.io.FileInputStream;
+import java.io.IOException; // For error handling
+import java.io.FileNotFoundException; // For error handling
+import java.util.Scanner;
+

Then inside your main method which throws an IOException (see example "Reading the filename from the keyboard")

+
FileStream file;
+Scanner in;
+try { // Try something
+  file = new FileInputStream("test.txt");
+  in = new Scanner(file);
+} catch (FileNotFoundException e) { // Catch IF it fails
+  System.out.println("File not found.");
+  in = new Scanner(System.in); // Read from the keyboard instead
+}
+// Read the file now....
+String name = in.nextLine();
+

Before we had linked the Scanner to the keyboard, now we're doing it to a file.

+

Try-Catch

+

In the code above you see what's called a try-catch block. That means that if something was to happen in the execution of the code. Instead of just crashing as we have been seeing normally. We can deal with the error. In the example above you saw that the program reads from the keyboard instead of the file

+

Reading the filename from the keyboard

+
public static void main(String[] args) throws IOException {
+  FileInputStream file;
+  Scanner in, scnr;
+  // Connect one scanner to the keyboard to get the filename
+  scnr = new Scanner(System.in); 
+
+  System.out.print("Enter file name: ");
+  String filename = in.nextLine();
+
+  // Repeat code from previous example
+  FileStream file;
+  Scanner in;
+  try {
+    file = new FileInputStream(filename); // Only this line changed
+    in = new Scanner(file);
+  } catch (FileNotFoundException e) {
+    System.out.println("File not found.");
+    in = new Scanner(System.in);
+  }
+  String name = in.nextLine();
+  // ....
+}
+

The main throws the IOException since we don't deal with it in any of the catch blocks.

+

Reading names of people from a file into an array

+

Let's say we have a file with the following in it

+
3
+Paul
+Peter
+Mary
+

3 is to indicate the number of names in th file.

+

Let's write code in order to read these names into an array!

+
import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.util.Scanner;
+public static void main(String[] args) throws IOException {
+  FileInputStream file;
+  Scanner in, scnr;
+  scnr = new Scanner(System.in); 
+
+  System.out.print("Enter file name: ");
+  String filename = in.nextLine();
+
+  FileStream file;
+  Scanner in;
+  try {
+    file = new FileInputStream(filename); // Only this line changed
+    in = new Scanner(file);
+  } catch (FileNotFoundException e) {
+    System.out.println("File not found.");
+    in = new Scanner(System.in);
+  }
+
+  // For the size of the array, get the first number in the file
+  int size = in.nextInt();
+  String[] nameArray = new String[size];
+  for (int i = 0; i < size; i++) {
+    namesArray[i] = in.nextLine();
+  }
+
+  // Now all the names in the file is in the namesArray
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct11.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct11.html new file mode 100644 index 0000000..578051b --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct11.html @@ -0,0 +1,157 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture Notes October 11

+

Global Variables

+

Global variables is where you don't declare a variable inside a method. This is generally not a recommended practice. It is recommended to declare variables inside methods so that it is easier to reuse code.

+
public class mainDriver {
+  public static int globalVariable = 5; // I am a global variable
+  public static void main(String[] args) {
+      int localVariable = 4; // I am a local variable
+  }
+}
+

String Formatting

+

You can format strings in java by using the printf method in System.out.

+

Format strings work by using placeholders starting with % to specify where to place the value of a variable.

+

General format of command

+
//System.out.printf(FormatString, variable1, variable2, ....)
+String s = "The number is";
+int x = 5;
+System.out.printf("%s %d", s, x); // Prints "The number is 5"
+

If you want to print out money, you can do it through the following

+
float tax = 0.45698;
+System.out.printf("The tax is %.2f"); //prints "The tax is 0.46"
+

Floating point precision

+

Due to how computers store non-integers, math can be non-precise after some mathematical operations. It is therefore advantageous to do operations on integers to the level of precision you want.

+

For example, instead of working in dollars, work in pennies since it's the smallest division we care about.

+

ArrayList

+

Standard arrays are static, meaning they have no ability to grow. Instead of doing the operations we described last class, in order to add something to an array. We can use something called an ArrayList instead.

+

The methods in the ArrayList library are useful abstractions to make the life of a programmer easier.

+

ArrayLists can also hold only one type. The type cannot be a primitive like a standard array. Instead it must be a class representing the desired type.

+

int -> Integer

+

double -> Double

+

char -> Character

+

float -> String

+

To declare and initialize an ArrayList

+
import java.util.ArrayList;
+public class ArrayListTest {
+    public static void main(String[] args) {
+      ArrayList<Integer> numbers = new ArrayList<Integer>();
+      ArrayList<String> names = new ArrayList<String>();
+    }
+}
+

ArrayLists has a variety of different methods that can be used to access/manipulate it

+ +

If you want to add the numbers 1 through 10 into the ArrayList of numbers

+
for (int i = 1; i < 11; i++) {
+    numbers.add(i);
+}
+

To print out the entire contents of the ArrayList

+
for (int i = 0; i < numbers.size(); i++) {
+    System.out.println(numbers.get(i));
+}
+

How can you replace a value?

+
int n = 5; // Make this the number you wish to replace
+int i = 0;
+while (i < numbers.size() && numbers.get(i) != n) {
+    i++;
+}
+if (i == numbers.size()) {
+    System.out.println(n + " not found.");
+} else {
+  int r = 10; // Make this the value you want to replace n with
+  numbers.set(i, r);
+}
+

The remove method removes an item given an index. This shifts all the elements above the removed index down.

+
numbers.remove(3); // Removes the element in the third index
+

The add method can also take an index. It pushes all the elements at the index specified up.

+
numbers.add(3, 5); // Adds the number 5 to the third index
+

You can clone an array using the clone method

+
ArrayList<Integer> numbers2 = new ArrayList<Integer>();
+numbers2.clone(numbers); // Clones numbers into numbers2
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct18.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct18.html new file mode 100644 index 0000000..f5e63e5 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct18.html @@ -0,0 +1,137 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

October 18th

+

ArrayLists in classes

+
public class Numbers {
+  private ArrayList<Integer> used;
+  private ArrayList<Integer> unused;
+  numbers () {
+    // Debug: System.out.println("1. Constructor Entry Point");
+    used = new ArrayList<Integer>();
+    unused = new ArrayList<Integer>();
+    // Debug: System.out.println("2, Constructor Size of ArrayLists" + used.size() + " " + unused.size())
+  }
+  // Adds the numbers 1-5 into the used ArrayList
+  public void fillUsedArrayList() {
+    for (int i = 0; i < 5; i++) {
+        used.add(i + 1);
+    }
+  }
+  // Move an item from the unused ArrayList to the used ArrayList
+  public int moveIt(int index) {
+    int temp = used.get(index);
+    unused.add(temp);
+    // Debug: System.out.println("Adding to used array:" + (i + 1));
+    used.remove(index);
+    return temp;
+  }
+  // The method below is created for debugging purposes
+  public void printBothArrayLists() {
+    // Print the used arraylist
+    System.out.println("Used ArrayList");
+    for (int i = 0; i < used.size(); i++) {
+        System.out.println(used.get(i));
+    }
+
+    // Print the unused arraylist
+    System.out.println("Unused ArrayList");
+    for (int i = 0; i < unused.size(); i ++) {
+        System.out.println(unused.get(i));
+    }
+  }
+}
+

Recall that you can compile the code above but you cannot run it. To run code, you must have a main method.

+

NumberTester

+
public class NumberTester {
+    public static void main(String[] args) {
+      Numbers list;
+      list = new Numbers();
+      list.fillUsedArrayList();
+      list.printBothArrayLists();
+    }
+}
+

Difference between Array and ArrayList

+

An Array is a static structure of contiguous memory of a single type.

+

An ArrayList is a dynamic structure of contiguous memory of a single type

+

To get the size of an array you use .length

+

To get the size of an ArrayList you use .size()

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct2.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct2.html new file mode 100644 index 0000000..681fe7a --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct2.html @@ -0,0 +1,170 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture Notes Oct 2nd

+

Array

+

array is not a reserved word, it's a concept. Arrays are able to hold multiple values under one name of the same type.

+

For instance, you can have an array of integers.

+

Properties of an array

+ +

You can declare arrays by saying the type '[]' and the name of the array

+
int[] numbers;
+double[] gpas;
+float[] grades;
+

Before you can use the array, you must new it

+
numbers = new int[10];
+

Where 10 is the size of the array.

+

You can combine both the declaration and initialization

+
double[] points = new double[7];
+

You can access individual elements of the array by using its index. Indexes start from zero

+
points[0] = 5.4; // The first element in the point array is 5.4
+

The .length property of an array gives the size of the array

+

For-Loops + Arrays

+

You can print out each element in the array using a for loop

+
for (int i = 0; i < numbers.length; i++) {
+    System.out.println(numbers[i]);
+}
+

You can ask a user to input a value to each element in the array

+
for (int i = 0; i < points.length; i++) {
+    System.out.print("Enter a number: ");
+    points[i] = scnr.nextInt();
+}
+

While-Loops + Arrays

+

You can use a while loop to search the array

+
int i = 0;
+int number = 5;
+// While the index is within the array size and the number isn't found
+while (i != number.length && number != numbers[i]) {
+    i++
+}
+if (i == numbers.length) {
+    System.out.println(number + " was not found.")
+} else {
+    System.out.println(number + " was found at index " + i)
+}
+

If you don't include the i != number.length you will obtain an IndexOutOfBounds error.

+

The example above is called a Linear Search.

+

Linear searches work on an unsorted and sorted arrays.

+

Methods + Arrays

+

You can pass an array into a method

+
public static void exampleMethod(int[] sample) {
+    // Do something
+}
+public static void main(String[] args) {
+    int[] s = new int[30];
+    exampleMethod(s);
+}
+

Do-While Loops

+

For-loops can run 0 or more times. If you want something to execute at least once. Use a do-while loop.

+
do {
+    // Code
+} while (condition);
+

For example, to search at least once and asking whether the user wants to search again

+
// Assume linearSearch and array are defined
+char answer;
+Scanner input = new Scanner(System.in);
+do { 
+  linearSearch(array, input);
+  System.out.print("Do you want to search again? (Y/N) ");
+  input.nextLine();
+  answer = input.next().charAt(0);
+} while( answer != 'N');
+

You can create any type of loop just by using a while loop.

+

Example: Finding the Max

+

You can find the max of an array using the following method

+
double max = arrayName[0];
+for (int i = 1; i < arrayName.length; i++) {
+    if (max < arrayName[i]) {
+        max = arrayName[i];
+    }
+}
+System.out.println("The max is " + max);
+

Example: Summing up an array

+

You can sum the array using the following method

+
double sum = 0;
+for (int i = 0; i < arrayName.length; i++) {
+    sum += arrayName[i];
+}
+System.out.println("The sum is " + sum);
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct23.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct23.html new file mode 100644 index 0000000..c35b022 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct23.html @@ -0,0 +1,125 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for October 23

+

Two-Dimensional Arrays

+

You can think of a two dimensional array as a grid that is organized by rows then columns.

+

To declare a two dimensional array do the following

+
int[][] grid  = new int[5][5];  // Declares a 2D array of 5 rows and 5 columns
+

You can have as many dimensions as you want. For graphics a 3-dimensional array would render 3D points.

+

It doesn't have to be inherently visual though, you can have the n-dimensional array look at the interaction between n different variables. For example, the relationships to different questions in a survey.

+

Strings are essentially a char array with extra methods attached. We can imitate an array of strings with a 2D char array.

+
char[][] helloWorld = new char[5][5];
+hello[0][0] = 'h';
+hello[0][1] = 'e';
+hello[0][2] = 'l';
+hello[0][3] = 'l';
+hello[0][4] = 'o';
+hello[1][0] = 'w';
+hello[1][1] = 'o';
+hello[1][2] = 'r';
+hello[1][3] = 'l';
+hello[1][4] = 'd';
+
+

Nested-For Loops

+

To access the elements in a 2D array, you need to use a nested for-loop.

+

Here is how you print out the hello world example above

+
for (int row = 0; row < helloWorld.length; row++) {
+  for (int col = 0; col < helloWorld[row].length; col++) {
+      System.out.print(helloWorld[row][col]);
+  }
+  System.out.print(" ")
+}
+

The code above prints out "hello world"

+

2D Arrays in methods

+

You can write a get like method in the following way

+
public static void get(int[][] array, int row, int col) {
+    return array[row][col];
+}
+

Arrays in Java are pass by reference not pass by value. Meaning that if you change the array within the method then it will change outside the method.

+
public static void insert(int[][] array, int row, int col, int numToInsert) {
+    array[row][col] = numToInsert;
+}
+

To make it not be able to change the array inside the method, use the keyword const inside the method header. To code below will throw a compiler error.

+
public static void insert(const int[][] array, int row, int col, int numToInsert) {
+    array[row][col] = numToInsert; // This line will throw an errror
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct25.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct25.html new file mode 100644 index 0000000..2385267 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct25.html @@ -0,0 +1,93 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture on Oct 25

+

2 Dimension Array of Objects

+

You can not only do a two dimensional array of primitive types, but you can also do two dimensional arrays of objects/classes.

+
animalLocation[][] map;
+map = new animalLocation[5][4];
+

Since we are dealing with classes, you cannot use this array right away. The code above creates the space in memory to store the objects. To have the animalLocation objects in the array, you must new each instance of the object.

+
for (int i = 0; i < map.length; i++) {
+    for (int j = 0; j < map[i].length; j++) {
+        map[i][j] = new animalLocation();
+    }
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct30.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct30.html new file mode 100644 index 0000000..ef5eacd --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct30.html @@ -0,0 +1,153 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Oct 30 Lecture

+

Sorting

+

Bubble Sort

+

These instructions are to sort in descending order, to sort in ascending order just negate the condition.

+

This sort is a series of iterations, for each iteration you go to the bottom of the array. Then compare if the value is greater than the element before it. If it is, then you

+
    +
  1. Go to the bottom of the array
  2. +
  3. Compare the value to the one before it +
      +
    1. If it's greater than the element before it -> swap
    2. +
  4. +
  5. Move on to the value before it and repeat step 2.
  6. +
+

Once you go through an iteration, the last thing being compared is the greatest value of the entire array. That means you don't have to check it every time anymore.

+

Keep going through all the iterations until n, where n is the size of the array, iterations have been completed.

+

Swapping Values

+

If you try to swap variables by saying

+
y = x;
+x = y;
+

then you'll end up overwriting y's value with x and both variable would have x's value.

+

If you want to actually swap variables, you must create a temporary variable that saves y's value so that it can be properly assigned to x.

+
int temp;
+temp = y;
+y = x;
+x = temp;
+

Implementation (Not Complete)

+
// Each iteration
+for (int j = 0; j < array.length - 1; j++) {
+  // Each element in the list
+  for (int i = 0; i < array.length - 1; i++) {
+    // Is the element greater than the one after it?
+    if (array[i] > array[i + 1]) {
+     // Swap
+      int temp = array[i + 1];
+      array[i + 1] = array[i];
+      array[i] = temp;
+    }
+  }
+}
+

This here compares each of the values each time. If you remember before, I said that you don't have to compare the topmost each time.

+

Implementation

+

To change this, just change the second loop condition

+
// Each iteration
+for (int j = 0; j < array.length - 1; j++) {
+  // Each element in the list
+  for (int i = 0; i < array.length - 1 - i; i++) { // Note this line
+    // Is the element greater than the one after it?
+    if (array[i] > array[i + 1]) {
+     // Swap
+      int temp = array[i + 1];
+      array[i + 1] = array[i];
+      array[i] = temp;
+    }
+  }
+}
+

Compare

+

In Java, you can compare numbers, strings, and even your own customized objects. To compare your own customize object, you must write a method called compare in your class.

+

To use your compare method in the sorting algorithm

+
// Each iteration
+for (int j = 0; j < array.length - 1; j++) {
+  // Each element in the list
+  for (int i = 0; i < array.length - 1 - i; i++) {
+    // Is the element greater than the one after it?
+    if (array[i].compare(array[i + 1])) { // Note this line
+     // Swap
+      int temp = array[i + 1];
+      array[i + 1] = array[i];
+      array[i] = temp;
+    }
+  }
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct4.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct4.html new file mode 100644 index 0000000..7743869 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct4.html @@ -0,0 +1,98 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture on October 4th

+

Pass by Copy vs Pass by Reference

+

Pass by Copy

+

When you pass a primitive type into a method (int, char, double, float, etc), it makes a copy of the value of the variable and brings it into the method

+

Pass by Reference

+

When you pass an array into a method (int[], char[], double[], etc[]), it passes in the reference of the variable into the method. In other words, you give the actual array into the method and allows the method to change it.

+

What's the Implication?

+

If you change the primitive in a method, it doesn't actually change the value of the variable.

+

If you pass in an array and change it in the method, it has been permanently changed outside the method as well.

+

How do I make it so I can't change my array by accident?

+

Use the finalkeyword in the method header

+
public static void printAll(final int[] array) {
+    for (int i = 0; i < array.length; i++) {
+        System.out.println("Number " + (i + 1) + " is " + array[i])
+    }
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct9.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct9.html new file mode 100644 index 0000000..062c43e --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Foct9.html @@ -0,0 +1,107 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture Notes October 9th

+

Arrays (Cont.)

+

Another way of Array Initialization

+
String[] names = {"Jennifer", "Noodle", "Fluffy", "Rosie", "Cinnamon", "Brianne", "Oliver"}
+

Everything between the {} is the initial values in the names array in the order that it is written.

+

Recall that arrays are of a fixed size. The names array above has 7 elements.

+

What can I do if I want to add something to the names array?

+

Do the following steps:

+
    +
  1. Create an empty array with the same size as the array
  2. +
  3. Take all the contents in the array and store it in a temporary array
  4. +
  5. Set names equal to another array of a bigger size
  6. +
  7. Take all the contents in temp and store it back to the array of choice
  8. +
  9. Add an element to the array by index
  10. +
+
// (1)
+String[] temp = new String[7];
+// (2)
+temp.clone(names);
+// (3)
+names = new String[20]; // Now it can hold up to 20 names
+// (4)
+names.clone(temp);
+// (5)
+names[7] = "New name!";
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fsept11.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fsept11.html new file mode 100644 index 0000000..0055c4e --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fsept11.html @@ -0,0 +1,239 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

CPSC 220 Lecture 4

+

Practice Problem

+
    +
  1. Create a class called Car
  2. +
  3. +
      +
    • Create a private variable of int type called year
    • +
    • Create a private variable of String type called make
    • +
    +
  4. +
  5. Create accessor methods for all data members.
  6. +
  7. Create mutator methods for all data methods.
  8. +
+
public class car { // begin car
+  private int year;
+  private String make;
+  public int getYear(void) {
+      return year;
+  }
+  public String getMake() {
+      return make;
+  }
+  public void setYear(int y) {
+    if (y > 1890) {
+        year = y;
+    } else {
+        System.out.println(y + " is not a valid year.");
+    }
+  }
+  public void setMake(String m) {
+      make = m;
+  }
+}
+

Local variables are only existent within the curly braces that it is defined in.

+

If Statements and Boolean Expressions

+

Boolean expressions return a boolean

+
1 < 4; // 1 is less than 4: TRUE
+3 > 5; // 3 is greater than 5: FALSE
+5 == 5; // 5 is equal to 5: TRUE
+5 != 5; // 5 is not equal to 5: FALSE
+1 >= 1; // 1 is greater than or equal to 1: TRUE
+5 <= 1; // 5 is less than or equal to 1: FALSE
+

If statements only occur if the boolean expression is true, otherwise the else block is executed.

+
if (true) {
+  System.out.println("I am always printed");
+} else {
+  System.out.println("I am never printed");
+}
+

You can only have one else per if. If you have an if you don't necessarily need an else

+

Local vs Class Variables

+

If you have a local variable and the class variable sharing the same name, then the local variable is always used first.

+
public class car { // begin car
+    private int year;
+  public void setYear(int year) {
+     year = year;
+  }
+}
+

This is a redundant statement, it makes the argument that is passed in equal to itself.

+

To avoid this situation, use the keyword this to access the class variable

+
public class car { 
+  private int year;  
+  public void setYear(int year) {     
+    this.year = year;  
+  }
+}
+

The code above runs as expected.

+

Rewriting our class with this

+
public class car { // begin car
+  private int year;
+  private String make;
+  public int getYear(void) {
+      return year;
+  }
+  public String getMake() {
+      return make;
+  }
+  public void setYear(int year) {
+    if (y > 1890) {
+        this.year = year;
+    } else {
+        System.out.println(y + " is not a valid year.");
+    }
+  }
+  public void setMake(String make) {
+      this.make = make;
+  }
+}
+

Unreachable Code

+

When the code hits a return statement, it stops executing the rest of the code in the method. Also throws an Unreachable Code Error.

+
public int add(int x, int y) {
+  return x + y;
+  System.out.println("x + y = " + x + y);
+}
+add();
+System.out.println("Hello");
+

Here the code above will not compile, though assuming the error doesn't exist then it would only print out "Hello"

+

Constructors

+

You cannot have a private or protected constructors.

+

Constructors are used to initialize your objects.

+

You want to have the class variables to the left of the assignment statement.

+
public class car {
+  private int year;
+  private String make;
+  car() {
+    year = 1890;
+    make = "Ford";
+  }
+  car(int year, String make) {
+    this.year = year;
+    this.make = make;
+  }
+}
+

Testers

+

Testers are useful to check that the class is implemented correctly. Both the tester and the class have to be in the same folder/directory.

+
public class carTester {
+  public static void main(String[] args) {
+    Car myCar; // Declaration
+    myCar = new Car(); // Initilization
+    Car yourCar = new Car(2009, "Hyundai"); // Declaration + Initialization
+  }
+}
+

More about classes

+
public class Car {
+  private String name;
+  private int odometer;
+  public void setOdometer(int od) {
+    odometer = od;
+  }
+  public void setName(String n) {
+      this.name = n;
+  }
+  public void changeOilRequest(String name, int od) {
+    if (name == this.name) {
+      int difference = od - this.odometer;
+      if (difference > = 3000) {
+        // You can call other methods in the class
+        setOdo(od);  // Equivalent to "this.setOdo(od);"
+        this.odometer = od;
+        System.out.println("Ready for oil change.");
+      } else {
+        System.out.println(name + " not ready for oil change.")
+      }
+    } // end if
+  } // end changeOil request
+} // end class
+

To call public methods outside the class use the variable name to do so.

+
public class CarTester {
+  public static void main(String[] args) {
+    Car myCar = new Car();
+    myCar.setName("Honda")
+    myCar.changeOilRequest("Honda", 3400);
+  }
+}
+

Math library

+

The ceil method rounds up while the floor method runs down.

+
Math.ceil(3.2); // 4
+Math.ceil(4.1); // 4
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fsept20.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fsept20.html new file mode 100644 index 0000000..70bcfb1 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fsept20.html @@ -0,0 +1,190 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Counting Loop

+

Looking at the following example code

+
int i;
+for (i = 0; i < 3; i++) { //begin for
+  System.out.println("i = " + i); //body
+} //end for
+System.out.println("After loop, i = " + i);
+

i = 0 is the initializing statement

+

i < 3 is the conditional, that is when the loop ends

+

i++ is the increment/decrement

+

i++ is synonymous with i = i + 1

+

The initialization statement only occurs once at the beginning of the loop.

+

Execution Example

+

Let us go through this for loop example

+ +

Exit loop. Print "After loop, i = 3"

+

Condensing Syntax

+

You can also do the declaration in the initialization statement

+
for (int i = 0; i < 3; i++) {
+    System.out.println("i = " + i);
+}
+

This now runs like above without the "After loop, i = 3" print. You cannot access the variable i outside the for loop since in this example, it belongs to the for loop's scope.

+

Logic Expressions

+

And Statements

+

With the AND operator && both the left and right side needs to be true for the expression to be true.

+
true && true // true
+true && false // false
+false && true // false
+false && false // false
+

Or Statements

+

With the OR operator || either the left or right side needs to be true for the expression to be true.

+
true || true // true
+true || false // true
+false || true // true
+false || false // false
+

Examples

+

Example: Print out the number n if it is between 10 and 20 (inclusive)

+
if (n >= 10 && n <= 20) {
+    System.out.println(n);
+}
+

Example: Print out the age if it is not of young adult age. Young adult range is from 18 to 39 (inclusive)

+
if (!(age >= 18 && age <= 39)) {
+    System.out.println(age);
+}
+

Or you can use De Morgan's Law (for the curious)

+
if (age < 18 || age > 39) {
+    System.out.println(age);
+}
+

For Loops (Cont.)

+

Backwards counting

+

You can use the loop to count backwards

+
for (int i = 10; i > -1; i--) {
+    System.out.println(i);
+}
+

This prints the following

+
10
+9
+8
+7
+6
+5
+4
+3
+2
+0
+

Rows-Columns

+

You can make rows and columns of asterisks

+
for (int j = 0; j < someNumber; j++) { // Corresponds to rows
+  for (int i = 0; i < someNumber2; i++) { // Corresponds to columns
+    System.out.print("*"); 
+  }
+  System.out.println(""); // Goes to the next row
+}
+

If someNumber equals someNumber2, then we have the same amount of rows as columns.

+

Let someNumber equal to 2 and someNumber2 equal to 2

+

Output:

+
**
+**
+

Right Triangles

+

You can make a right triangle of Tilda with the following code

+
for (int i = 1; i <= num; i++) { // Corresponds to the row
+  for (int j = 0; j < i; j++) { // Corresponds to the column and stops at the current row number
+      System.out.print("~");
+  }
+  System.out.println(""); // Moves to next row
+}
+
What are for-loops used for? Reusing code
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fsept25.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fsept25.html new file mode 100644 index 0000000..f1aacff --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fsept25.html @@ -0,0 +1,136 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture in CPSC 220 Sept 25 2017

+

Constants

+

Adding the keyword final in front of a variable declaration makes the variable constant. Meaning you cannot later change it in the code.

+
final int MAX = 10;
+

By industry norm, the style of the variable is to have it in all caps.

+

You CANNOT do the following

+
final int MAX = 10;
+MAX = 15;
+

Using Libraries

+
    +
  1. Import the library
  2. +
  3. Find the method that is appropriate
  4. +
  5. Use it
  6. +
+

Example:

+
import java.util.Math;
+public class MathTest {
+    public static void main(String[] args) {
+        double answer = Math.ceil(5.4);
+        System.out.println(Math.ceil(4.5));
+    }
+}
+

Typecasting / Type Conversions

+

You can only cast a variable if you are casting it to a type that is larger than the one it was previously. The expression Polack used is that you cannot fit into super skinny jeans, but you can fit into bigger pants.

+
double dnum;
+float fnum;
+int inum;
+dnum = (double)fnum * (double)inum;
+

Char vs String

+

Strings are initialized in Java with double quotes while chars are initialized with single quotes

+
char initial = 'j';
+String name = "Jennifer";
+

Characters can be read in as an integer.

+

Random Numbers

+
    +
  1. Import java.util.Random;
  2. +
  3. Declare the random number generator
  4. +
  5. Initialize with new
  6. +
  7. Use it
  8. +
+
import java.util.Random;
+public class RandTest {
+    public static void main(String[] args) {
+      Random rand;
+      rand = new Random();
+      int number = rand.nextInt(100); // Random generates number between 0-99
+    }
+}
+

How do you generate numbers in a different range? [50, 150]

+
rand.nextInt(100); // 0-99
+rand.nextInt(101) // 0 - 100
+rand.nextInt(101) + 50 //50-150
+

In more general terms

+
rand.nextInt(end - start + 1) + start
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fsept6.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fsept6.html new file mode 100644 index 0000000..2312cbb --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220%2Fsept6.html @@ -0,0 +1,297 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

CPSC 220 Lecture 3

+

Variables

+

Variable -- Storage of information

+

The type cannot change in a variable.

+

Examples of types include

+ +

Declaration: int num;

+

Initialization: num = 5;

+

Declaration + Initialization: int num = 5;

+

Possible Errors

+

You cannot declare a variable multiple times.

+

Undefined variables are when you do not declare a variable before attempting to use it.

+

Casting

+

You need to cast if you are attempting to lose data or store a larger memory type into a smaller one.

+

double -> float -> int (casting required)

+
double gpa = 3.2;
+int num1 = 10 * (int)gpa // 30
+

Operations

+

The basic number operations are

+ +

Examples

+
0 % 2 // 0
+1 % 2 // 1
+2 % 2 // 0
+
+3 % 2 // 1
+4 % 2 // 0
+5 % 2 // 1
+
+3 % 5 // 3
+7 % 5 // 2
+

You can test if something is even using modulus %

+
// Assuming i was initiliazed to a value earlier
+if (i % 2 == 0) {
+  System.out.println("i is even");
+} else {
+  System.out.println("i is odd");
+}
+

System input

+

Here is sample code using a Scanner as input

+
import java.util.Scanner;
+public class ScannerExample {
+  public static void main(String[] args) {
+    Scanner in;
+    in = new Scanner(System.in);
+
+    // Grab numerical values
+    int num = in.nextInt();
+    float gpa = in.nextFloat();
+    double weight = in.nextDouble();
+
+    // Grab a single character
+    in.nextLine()
+    char initial = in.next().charAt(0);
+
+    // To get the entire line of a string
+    in.nextLine();
+    String name = in.nextLine();
+  }
+}
+

You need to use in.nextLine() to grab the carriage return that is left after grabbing a numeric value.

+

Classes and Objects

+

Classes are a new type that you can have multiple things of.

+

These classes are blueprints that are made up of primitives or more basic types.

+

First create a Pet.java file (Name of the class must match the name of the file)

+
public class Pet {
+  private String name;
+  private int years;
+}
+

You can then use the Pet class in your main program. The terminology here is that you can create instances or objects of the class.

+

In PetTester.java

+
public class PetTester {
+  public static void main(String[] args) {
+    Pet myPet;
+    myPet = new Pet();
+  }
+}
+

Both Pet.java and PetTester.java must be in the same directory/folder

+

Mutators/Accessors

+

Since the variables are private we cannot access them in the main program. To work around this, we can write what is called a mutator method.

+
public class Pet {
+  private String name;
+  private int years;
+
+  // Mutators
+  public void setName(String n) {
+      name = n;
+  }
+  public void setYears(int y) {
+      if (y >= 0) {
+          years = y;
+      } else {
+          System.out.println("No one is less than 0 years old.")
+      }
+  }
+}
+

Now let's use these new methods

+
public class PetTester {
+  public static void main(String[] args) {
+    Pet mypet;
+    myPet = new Pet();
+    myPet.setName("Fred");
+    myPet.setAge(20);
+  }
+}
+

We need a method that will allow us to access the data type. Let's add accessors to our pet class.

+
public class Pet {
+  private String name;
+  private int years;
+
+  // Mutators
+  public void setName(String n) {
+    name = n;
+  }
+  public void setYears(int y) {
+    if (y >= 0) {
+      years = y;
+    } else {
+      System.out.println("No one is less than 0 years old.")
+    }
+  }
+
+  // Accessors
+  public String getName() {
+    return name;
+  }
+  public int getYears() {
+    return years;
+  }
+}
+

Now let's get some information from the pet object, such as the age.

+
public class PetTester {
+  public static void main(String[] args) {
+    Pet mypet;
+    myPet = new Pet();
+    myPet.setName("Fred");
+    myPet.setYears(20);
+
+    int year = myPet.getYears();
+  }
+}
+

Constructors

+

Constructors lets us initialize variables in the class without having to use mutator methods.

+
public class Pet {
+  private String name;
+  private int years;
+
+  // Default Constructor
+  public Pet() {
+    name = "";
+    years = 0;
+  }
+  // Non-Default Constructor
+  public Pet(int y, String n) {
+    name = n;
+    years = y;
+  }
+
+  // Mutator Methods
+  public void setName(String n) {
+    name = n;
+  }
+  public void setYears(int y) {
+    if (y >= 0) {
+      years = y;
+    } else {
+      System.out.println("No one is less than 0 years old.")
+    }
+  }
+
+  // Accessor Methods
+  public String getName() {
+    return name;
+  }
+  public int getYears() {
+    return years;
+  }
+}
+

Now let us see this in action.

+
public class PetTester {
+  public static void main(String[] args) {
+    Pet yourPet = new Pet(10, "Fluffy");
+  }
+}
+

You can have as many constructors as you want, but they must be different.

+

Example:

+
public class Pet {
+  ...
+  pet() {
+    name = "";
+    years = 0;
+  }
+  pet(int y, String n) {
+    name = n;
+    years = y;
+  }
+  pet(String n) {
+    years = 1;
+    name = n;
+  }
+  ...
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220.html b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220.html new file mode 100644 index 0000000..2342e6c --- /dev/null +++ b/static/~brozek/index.html?labaide%2Ffall2017%2Fcpsc220.html @@ -0,0 +1,102 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

CPSC 220 Computer Programming and Problem Solving Fall 2017

+

Lecture 3 -- September 6

+

Lecture 4 -- September 11

+

Lecture 7 -- September 20

+

Lecture 9 -- September 25

+

Lecture 10 -- October 2

+

Lecture 11 -- October 4

+

Lecture 12 -- October 9

+

Lecture 13 -- October 11

+

Lecture 15 -- October 18

+

Lecture 16 -- October 23

+

Lecture 17 -- October 25

+

Lecture 18 -- October 30

+

Exam 2 Review -- October 30

+

Lecture 19 -- November 6

+

Lecture 20 -- November 13

+

Lecture 21 -- November 15

+

Lecture 22 -- November 20

+

Lecture 23 -- November 27

+

Lecture 25 -- December 6

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fapr3.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fapr3.html new file mode 100644 index 0000000..bb40b48 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fapr3.html @@ -0,0 +1,105 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for April 3rd

+

Inheritance

+

The base class, super class, or parent class is the initial class that we are working with. Let's say that you want to extend the class, or add additional functionality. The class that inherits from the parent class is called the child class, subclass or derived class.

+

Child Class Syntax

+
public class Truck extends Car {
+    // Truck Appropriate Fields
+    // Necessary methods for truck
+}
+

This code adds all the methods from Car into the Truck class. You can then add methods that is specific to a Truck into the Truck class.

+

A child class has all parent fields and access to all parent methods!

+

Visibility Modifiers

+

Recall the words public and private

+

The public modifier makes the field/method accessible by any class

+

The private modifier makes the field/method only accessible within the method itself

+

The protected modifier makes the field/method accessible within the same class or any subclasses.

+

Overriding a Method

+

You can override a parent class method by declaring a method in the child class with the same...

+ +

but this method would have different behavior!

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb1.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb1.html new file mode 100644 index 0000000..602dfff --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb1.html @@ -0,0 +1,120 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for February 1st

+

Control Structures

+

In this class we will talk about three types of control structures

+ +

Sequential is what is most familiar to us. Write the lines from top to bottom and it executes it in that order

+

Selection

+

Selection depends on the question of if.

+

If it is raining, wear boots

+
if (raining) {
+  wearingBoots = true;
+}
+

If you want something to happen also when it is not true, consider an if-else statement

+

If the light is off, turn it on.

+

Otherwise, turn it on

+
if (lightIsOn) {
+  lightIsOn = false;
+} else {
+  lightIsOn = true;
+}
+

Sometimes you can have multiple branches depending on a condition. Let us take a stop light as an example

+
if (light == "red") {
+  car.stop()
+} else if (light == "yellow") {
+  car.slow()
+} else {
+  car.go()
+}
+

String comparison

+

There is a specific method in the String class when it comes to checking for string equality

+
boolean equals(String s)
+

Let us look at an example

+
String word = "hello";
+boolean ans = word.equals("hello"); // Returns true
+boolean ans2 = word.equals("Hello"); // Returns false
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb13.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb13.html new file mode 100644 index 0000000..40efeec --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb13.html @@ -0,0 +1,130 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for February 13

+

Loops

+

Why Loops?

+

While some check is true, repeat the work.

+

While the cookies aren't baked, keep baking

+

Loop Building Process

+
    +
  1. Identify one test that must be true when the loop is finished
  2. +
  3. Use the opposite form of the test
  4. +
  5. Within loop, make progress towards completion of the goal.
  6. +
+

While syntax

+
while (expression) {
+  // Loop body executes if expression is true
+}
+// Statements execute after expression is false
+

Getting Input (Songs in a Playlist Psuedocode)

+
// Ask user about first song
+while (user says play next song) {
+    // play next song
+    // ask user about next song
+}
+

Nested Loops

+

You can have loops inside loops

+
int outer = 1;
+while (outer < 4) {
+  int inner = 1;
+  while (inner < 4) {
+    System.out.println(outer + ":" + inner);
+    inner++;
+  }
+  outer++;
+}
+

This code does the following

+
1:1
+1:2
+1:3
+2:1
+2:2
+2:3
+3:1
+3:2
+3:3
+

Break Down the Problem

+

Never write the entire program at once! This makes it incredibly hard to debug. Instead break it into small parts.

+

Write one part -> debug until it works

+

Write second part -> debug until it works

+

This way you know which part of your code failed, instead of having everything fail.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb20.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb20.html new file mode 100644 index 0000000..cc865fc --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb20.html @@ -0,0 +1,131 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for February 20th

+

Reading a File

+

You can get input from a file instead of from the terminal

+
FileInputStream fileIn = new FileInputStream("myFile.txt");
+// Our familiar Scanner
+Scanner scnr = new Scanner(fileIn);
+// We can use our usual Scanner methods
+String line = scnr.nextLine();
+fileIn.close(); // Remember to close the file when you're finished with it!
+

Reviewing Scanner Methods

+

To understand some of the Scanner methods we need to be aware of the "newline" character. This character is equivalent to the Enter button on the keyboard.

+

scnr.nextLine() This get's all the characters in the buffer up to the newline character.

+

scnr.next() Grabs the characters in the next "token". Tokens are usually separated by any whitespace type character (spaces, enters, tabs, etc.)

+

Writing to a File

+

Prints information to a file instead of to the screen

+
FileOutputStream fileOut = new FileOutputStream("myOutfile.txt");
+PrintWriter out = new PrintWriter(fileOut);
+out.println("Print this as the first line.");
+out.flush(); // Pushes the file changes to the file
+fileOut.close(); // If you forget this then it won't remember your changes
+

Arrays

+

Arrays are containers of fixed size. It contains a fixed number of values of the same type. (Ex: 10 integers, 2 strings, 5 booleans)

+

Declaration

+
int[] array; // This declares an integer array
+

Initialization

+
array = new int[7]; // This states that this array can hold up to 7 integers
+

Storing a value in an array

+ +
int[] array = new int[7];
+array[0] = 5; // Stores 5 into the first slot
+

Now let us attempt to retrieve the value

+
int temp = array[0];
+System.out.println(temp); // Prints "5"
+

Traversing an Array

+

Let's say we have the following array

+
int[] numbers = {3, 5, 2, 7, 9};
+

Let's print out each of the values in the array

+
for (int i = 0; i < numbers.length; i++) {
+    System.out.print("value in " + i " is " + numbers[i]);
+}
+

Finding the maximum value in an Array

+
int highest = numbers[0];
+for (int i = 0; i < numbers.length; i++) {
+    if (numbers[i] > highest) {
+        highest = numbers[x];
+    }
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb27.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb27.html new file mode 100644 index 0000000..36ede8c --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb27.html @@ -0,0 +1,130 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for February 27th

+

Review for midterm

+

Chapter 1 -- Code Style, API

+

Chapter 2 -- Variables & Assignments, strings

+

Chapter 3 -- input & output

+

Chapter 4 -- branches (if, if/else, switch)

+

Chapter 5 -- loops (while, for), scope

+

Chapter 6 -- File Reading and Writing

+

Separated vs Connected Branches

+

What is the output of this code?

+
String preferredLanguage = "Spanish";
+if (preferredLanguage.equals("Chinese")) {
+    System.out.println("Ni hao!");
+}
+if (preferredLanguage.equals("Spanish")) {
+    System.out.println("Hola!");
+}
+if (preferredLanguage.equals("French")) {
+    System.out.println("Bonjour!");
+}
+if (preferredLanguage.equals("German")) {
+    System.out.println("Gutentag!")
+} else {
+    System.out.println("Hello!")
+}
+

The output is

+
Hola!
+Hello!
+

This is because each of the if statements are independent from each other. Whether or not the if statement gets check is not affected by the if statements around it.

+

Since the preferred language equals Spanish it outputs Hola! But since the language is also not German it prints out Hello! as well.

+

Using an Array

+

Square brackets notation is used to access elements, array slots can be used as variables

+
int[] array = new int[7]; // Creates an integer array of size 7
+array[0] = 5;
+

Swapping Elements

+

You can swap x and y in the following way with a temporary variable

+
int x = 6;
+int y = 1;
+
+int temp = x;
+
+x = y;
+y = temp;
+

Two-Dimensional Arrays

+
// Creates a 2D array of two rows and three columns
+int[][] a = new int[2][3]
+

You can access an element of this 2D array using the conventional square bracket notation

+
a[0][0] = 5;
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb6.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb6.html new file mode 100644 index 0000000..cd49767 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb6.html @@ -0,0 +1,475 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for February 6th

+

If Statements -- Cont.

+

Inside the parenthesis of the if statement must be a boolean expression. This is an expression that evaluates to either true or false. We can do more complex boolean expressions through logical operators.

+

Logical Operators

+

NOT !a this is true when a is false

+

AND a && b this is true when both operands are true

+

OR a || b this is true when either a is true OR b is true

+

Truth Tables

+ +

Not

+

Let's look at the most simplest case. Not.

+ + + + + + + + + + + + + + + + + +
a!a
truefalse
falsetrue
+

AND

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba && b
truetruetrue
truefalsefalse
falsetruefalse
falsefalsefalse
+

Notice here that a && b is only true when both a and b are true.

+

OR

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba \\b
truetruetrue
truefalsetrue
falsetruetrue
falsefalsefalse
+

Notice here that a || b is only false when both a and b are false.

+

Precedence (Order of Operations)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parenthesis()
Logical Not!
Arithmetic Operators* / % + -
Relational Operators< <= > >=
Equality and Inequality operators== !=
Logical AND&&
Logical OR||
+

Playing with Truth Tables Example

+

a && !b

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ab!ba && !b
truetruefalsefalse
truefalsetruetrue
falsetruefalsefalse
falsefalsetruefalse
+

!a || b

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ab!a!a \\b
truetruefalsetrue
truefalsefalsefalse
falsetruetruetrue
falsefalsetruetrue
+

!(a || b && c)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
abcb && ca \\(b && c)!(a \\b && c)
truetruetruetruetruefalse
truetruefalsefalsetruefalse
truefalsetruefalsetruefalse
falsetruetruetruetruefalse
truetruefalsefalsetruefalse
truefalsetruefalsetruefalse
falsetruetruetruetruefalse
falsefalsefalsefalsefalsetrue
+

!a || b && c

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
abc!ab && c!a \\b && c
truetruetruefalsetruetrue
truetruefalsefalsefalsefalse
truefalsetruefalsefalsefalse
falsetruetruetruetruetrue
truefalsefalsefalsefalsefalse
falsetruefalsetruefalsetrue
falsefalsetruetruefalsetrue
falsefalsefalsetruefalsetrue
+

Distributive Property of Logical Operators

+

The following statements are equivalent

+

!(a && b) is equivalent to !a || !b

+

Notice how when you distribute the ! you have to flip the operand as well. && becomes ||

+

Same is true for the following example

+

!(a || b) is equivalent to !a && !b

+

!(a || b && c) is equivalent to !a && (!b || !c)

+

Short Circuit Evaluation

+

In an && (AND) statement, if the left side is false, there is no need to evaluate the right side. Since it's going to be false anyways!!

+
false && true; // FALSE no matter what the right side is
+

In an || (OR) statement, if the left side is `true, there is no need to evaluate the right side. Since it's going to be true by default!!

+
true || false; // TRUE no matter what the right side is
+

Java takes this shortcut by default for efficiency reasons

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb8.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb8.html new file mode 100644 index 0000000..a938baa --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Ffeb8.html @@ -0,0 +1,149 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for February 8th

+

Switch Statements

+

Another way to perform multiway branching. Comparing a variable and constant values (String, int, char)

+

Switch statements cannot be used with boolean, double, or floats

+

Syntax

+
switch (variable) {
+  case value1:
+    // Do something
+    break;
+  case value2:
+    // Do something else
+    break;
+  //...
+  default:
+    // If all else fails do this
+    break;
+}
+

case is a reserved word that means "when our variable in consideration is equal to..."

+

If you forget the break keyword, then the program will keep doing the work of all the statements until it hits a break keyword.

+

Example Switch Syntax

+
switch (birthday) {
+  case 1: 
+    birthstone = "garnet";
+    break;
+  case 2:
+    birthstone = "amethyst";
+    break;
+  // ....
+  default:
+    System.out.println("Not valid");
+    break;
+}
+

Comparing Strings Relationally

+

Comparing strings are based on the ASCII value of characters

+

Sorting strings will result in strings being in alphabetical or reverse alphabetical order. The values of the strings are compared character by character from the left with each ASCII value.

+

To compare strings use the compareTo() method. Here is the format of the call

+
str1.compareTo(str2)
+

This returns a negative number when str1 is less than str2

+

This returns 0 when str1 is equal to str1

+

This returns a positive number when str1 is greater than str2

+

Example

+
String a = "apple";
+String b = "banana";
+
+int x = a.compareTo(b); // x = -1
+
+int y = b.compareTo(a); // y = 1
+

Ternary Operator

+

With a ternary operator, you can shorten statements where a value is determined by an if statement

+
String output = "";
+if (movieRating > 4) {
+  output = "Fan favorite";
+} else {
+  output = "Alright";
+}
+

Is equivalent to

+
String output = "";
+output = (movieRating > 4)? "Fan favorite": "Alright";
+

Another Example

+
double shipping;
+if (isPrimeMember) {
+  shipping = 0;
+} else {
+  shipping = 3.99;
+}
+

Is equivalent to

+
double shipping = (isPrimeMember)? 0: 3.99;
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan16.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan16.html new file mode 100644 index 0000000..9a99a9f --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan16.html @@ -0,0 +1,111 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for January 16 2018

+

Comments

+

You can use multi-line comments or single line comments to note about a piece of code. This helps you so that you don't forget what was happening in the code

+
/* Multi Line Comment
+I am multiple lines woo!
+*/
+
+System.out.println("Hello"); // I am an inline comment
+

Javadocs

+

This is a standardized method in Java to describe your functions and classes

+
/**
+ * This is a Javadoc comment. A description of your class should appear here
+ * @author Brandon
+ * @version 2018
+ */
+public class Example{
+  /** Another Javadoc comment.
+   * A description of your program should go here
+   */
+  public static void main(String[] args) {
+
+  }
+}
+

Variables

+

Convention in Java is for all of your functions/method names to be lowercase.

+

Class names should be title cased, each word is capitalized ex: IntroExample

+

Java API

+

The Java API is publicly accessible and is extremely useful for finding methods in existing classes.

+

The API documentation for the String class is located here: https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/String.html

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan18.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan18.html new file mode 100644 index 0000000..679774b --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan18.html @@ -0,0 +1,222 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for January 18

+

Variables and Assignment

+

Think about variables as buckets that hold information. Once the bucket is created, only one type of item can go in the bucket.

+
sand bucket1;
+

We can say that bucket1 is of type sand, that means the only thing that can go in the bucket is sand.

+
int bucket1;
+double bucket2;
+

From the two lines above, we have declared the variable.

+

Variables store state, they are a name for a location in memory.

+

Always remember to initialize your variables. Otherwise there's nothing in the bucket!

+
bucket1 = 5;
+

You can combine both the declaration and initialization

+
int count = 15;
+

Remember when dealing with variables to stay true with the type, don't mix a bucket of water with a bucket of sand.

+

We can update count to contain a true value

+
count = 55;
+

count no longer has the value of 15 in it. There's no record of it! It has been overwritten with the value 55

+

Primitive Types

+

There are 8 primitive types in Java

+ +

byte through double are all numeric types

+

Boolean

+

boolean can only be equal to true or false

+
boolean student = true;
+

Char

+

Stores a single character from the Unicode set

+

There are 16 bits per character which adds up to 65,536 characters

+

ASCII is the US subset of the characters. You can look this up online when needing to deal with ASCII values

+
char firstLetter = 'A';
+

Numeric types

+

The different numeric types determine the precision of your number. Since numbers are not represented the same in the computer as they are in real life, there are some approximations.

+

The default type you can use your code is int for integers and double for numbers with a decimal point

+

There are certain types of operations you can perform on numeric type

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SymbolMeaningExampleValue
+addition43 + 851
-subtraction43.0-8.035.0
*multiplication43 * 8344
/division43.0 / 8.05.375
%remainder / mod43 % 83
-unary minus-43-43
+

Increment/ Decrement

+

There are two types of in/decrementers postfix and prefix

+

Postfix:

+
int x = 0;
+int y = 7;
+x++; // Shortcut for x = x + 1
+y--; // Shortcut for y = y - 1
+

Prefix

+
int x = 0, y = 7, z;
+z = y * x++; // Equivalent to (y * x) + 1 = 7 * 0
+z = y * ++x; // Equivalent to y * (x + 1) = 7 * 1
+

Data Conversion

+

There are two types of data conversion, implicit and explicit

+

The compiler can perform implicit data conversion automatically.

+

Performing an explicit data conversion requires additional work on the programmer's part

+

A conversion is implicit if you do not lose any information in it

+
double price = 6.99;
+int sale = 3;
+double total = price - sale;
+

A cast is an explicit data conversion. This is requested by a programmer, this can lead to loss of information

+
int nextChar = 'b';
+Character.isAlphabetic( (char) nextChar); // Let's you print the actual letter 'b' instead of the number corresponding to it
+
+float price = 6.99;
+int cost = (int) price; // cost is now 6
+

Printing variables

+

You can print the values of variables using System.out.println and System.out.print

+

The difference is that System.out.println adds a new line at the end. Meaning the next print out will be on the next line.

+
int cost = 5;
+double sale = .30;
+System.out.print(cost);
+System.out.print(sale);
+// Prints out '5.30`
+System.out.println(cost);
+System.out.println(sale);
+// Prints out '5'
+// Prints out '0.30'
+

To add a space between two variables in a print, add " " to the expression in between the two variables

+
System.out.println("The total cost is " + 5 " dollars and" + " " + 93 + " cents");
+// The total cost is 5 dollars and 94 cents
+

Input from User

+

You can get import from the user, we can do this using the Scanner class.

+

First import it at the top of your file

+
import java.util.Scanner;
+

All you can do with Scanner is outlined in the Java API at this link https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Scanner.html

+

Create a Scanner object

+
Scanner input = new Scanner(System.in);
+System.out.print("Please enter an integer: ");
+price = input.nextInt(); // The integer that the user inputs is now stored in price
+System.out.println("Your input: " + price);
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan23.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan23.html new file mode 100644 index 0000000..5d516d8 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan23.html @@ -0,0 +1,169 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for January 23

+

Java Class

+

In Java, your code must live in a class.

+
public class NameOfClass {
+  public static void main(String[] args) {
+    // All program code
+  }
+}
+

It is important that NameOfClass is named meaningfully for the code. It is convention to use CamelCase when using classes. (Capitalize your class names!)

+

All methods have a method signature, it is unique to it. For main it is the words public static void and the argument String[] args.

+

public means that any other piece of code can reference it.

+

void means that the method returns nothing

+

main is the name of the method. It is important to have main since that tells the Java Interpreter where to start in your program.

+

String[] args is the command line arguments inputted into the program. For this part of the class, we don't need to worry about it.

+

If you noticed String is a class, it is not a primitive type. This is denoted in Java by having it capitalized.

+

Arithmetic Expressions

+

There is an order of operations in programming as well. It goes like this:

+
    +
  1. Parenthesis
  2. +
  3. Unary Operations
  4. +
  5. *, /, %
  6. +
  7. +, -
  8. +
+

And from there you read from left to right.

+

Constant Variables

+

These are variables that can never be changed

+
final int MINUTES_PER_HOUR = 60
+

The keyword final indicates to the Java compiler that it is a constant variable.

+

By convention, constants are in all caps with underscores being separated between the words

+

Java Math Library

+

There are some arithmetic expressions that we want to be able to do and we cannot achieve that simply with the standard operations

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodDescription
Math.sqrt(x)square root
Math.abs(x)absolute value
Math.pow(a, b)exponentiation $a^b$
Math.max(a, b)returns the maximum of a or b
Math.min(a, b)returns the minimum of a or b
Math.round(x)rounds to the nearest integer
+

Example: Finding Areas

+
public class MoreVariables
+  public static void main(String[] args) {
+    // Decrate a variable
+    int x;
+
+    // Initialize ia variable
+    x = 5;
+
+    // Area of a square
+    int squareArea = x * x;
+    System.out.println("Area of a square: " + squareArea);
+    double newSquare = Math.pow(x, 2);
+    System.out.println("Area of square: " + newSquare);
+
+    // Area of Circle
+    final double PI = 3.14159;
+    double radius = 3;
+    double circleArea = radius * radius * PI;
+    System.out.println("Area of circle: " + circleArea);
+
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan25.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan25.html new file mode 100644 index 0000000..45b2685 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan25.html @@ -0,0 +1,161 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for January 25

+

Strings

+

These are concatenated chars

+
'd' + 'o' + 'g' // equivalent to "dog"
+
"straw" + "berry" // strawberry
+

Strings are denoted by double quotes "" rather than a string which is denoted by single quotes ''

+

String is not a primitive type, it is a class. Hence, why it is capitalized in Java.

+

The java.lang.String is automatically imported in Java.

+

To declare and initialize a String

+
String name = "Henry";
+

In memory it appears as

+ + + + + + + + + + + + + + + + + + + +
H'e''n''r''y'
+

String Methods

+
int length()
+
boolean equals(String another)
+
boolean startsWith(String prefix)
+
boolean endsWith(String suffix)
+
String substring(int start, int end)
+
int indexOf(int ch)
+
String toLowerCase()
+

Using String Methods

+
char first = name.charAt(0);
+

Remember in Java, that it starts counting from zero! If you try to access a letter that doesn't exist, it will produce an IndexOutOfBounds error.

+

Errors

+

There are two types of errors, compile-type errors and run-time errors. Later we will talk about debugging skills such as making "breakpoints" in your code so you can analyze the different variable values.

+

Compile Time Errors

+

Compile time errors are generated due to syntax errors. Forgot a semicolon? Missing a brace?

+

Run-time Errors

+

These are logic errors. Not derived from syntax errors. An example of one that was discussed earlier is the IndexOutOfBounds error.

+

Tricky Thing About Input

+

Let's talk about input right now. Let's say you have the following scenario

+
Scanner input = new Scanner(System.in);
+System.out.println("Enter pet's age: ");
+int age = input.nextInt();
+System.out.println("Enter pet's name: ");
+String name = input.nextLine();
+System.out.println("Enter pet's breed: ");
+String breed = input.next();
+

Then when we start to run the program...

+
Enter pet's age: 
+14
+Enter pet's name:
+Enter pet's breed:
+Labradoodle
+

Why did it skip pet's name? Let's run through the process again

+
Enter pet's age: 
+14 [ENTER]
+Enter pet's name:
+Enter pet's breed:
+Labradoodle
+

Here the [ENTER] key gets saved into name.

+

To resolve this, just use an input.nextLine() to throw away that [ENTER]

+
Scanner input = new Scanner(System.in);
+System.out.println("Enter pet's age: ");
+int age = input.nextInt();
+System.out.println("Enter pet's name: ");
+input.nextLine();
+String name = input.nextLine();
+System.out.println("Enter pet's breed: ");
+String breed = input.next();
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan30.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan30.html new file mode 100644 index 0000000..71748e8 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fjan30.html @@ -0,0 +1,122 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for January 30

+

Random Number Generator

+

One of the ways you can do a random number generator is through this method:

+

Import a class called random

+
import java.util.Random;
+

Then you need to create a Random object

+
Random rand = new Random();
+

After this you can call the nextInt() method to get a random number between 0 and $2^{32}$

+
int randInt = rand.nextInt();
+

If you don't want a random number between 0 and $2^{32}$ but instead to another maximum value, then you can call the nextInt method inserting the max integer as a parameter.

+

Random Integer from 0-10 (not including 10)

+
int randInt2 = rand.nextInt(10);
+

Output

+

We have already encountered System.out.println and System.out.print but let us go over the differences again.

+

System.out.println() prints the contents inside the parenthesis and appends a newline character afterwards so that the next output is on a new line

+

System.out.print() prints the contents inside the parenthesis and does not output a newline character

+

Formatting Output

+

If you want more control on how your output is displayed, it is recommended that you use System.out.printf to format your output

+

First, you need to specify your type using the % instruction

+ +

Example:

+
int sum = 50;
+System.out.printf("Total = %d", sum);
+

This outputs

+
Total = 50
+

Notice here that there is no concatenation required like the previous two methods, instead you insert the variables as parameters

+

Let us deconstruct the % instruction

+

% .

+

The first underline is the + - 0 space (sometimes we want to pad the money with zeros)

+

The second underline is the width of the text

+

The third underline is the number of decimal places

+

The the final underline is the specifier f for decimal and d for integer

+

Example

+
double amount = 0.5;
+System.out.printf("Total Due: %0.2f")
+

This outputs

+
Total Due: 0.50
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar13.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar13.html new file mode 100644 index 0000000..241975a --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar13.html @@ -0,0 +1,128 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for March 13th

+

Methods

+

Methods are small blocks of statements that make it easier to solve a problem. It usually focuses on solving a small part of the overall problem.

+

Usually in methods you provide some sort of input and get some output out of it.

+

Advantages

+ +

Method definition

+

Consists of a method name, input and output and the block of statements.

+

Usually this is succinctly written using JavaDocs which is what you see in the JavaAPI

+

Method Call

+

A method call is the execution of the method. The statements defined in the method is what will execute.

+

Method Stubs

+

Recall from method definition the parts of the method definition. Now look at the following method

+
String[] split(String s)
+

The output here is String[]

+

The method name is split

+

The input is String s

+

Modular Programming

+

Let us look at the following example:

+

The program should have a list of grocery prices. It should be able to calculate the total cost of groceries. The store gives a student discount of 5%. The program should calculate this discount and update the total, it should calculate and add the 2.5% tax.

+ +

Parts of a method definition

+
public static int timesTwo(int num) {
+    int two = num * 2;
+    return two;
+}
+

It first starts off by declaring the visibility public

+

The return type if int

+

The method name is timesTwo

+

The input parameter is int num

+

Between the curly braces is the body of the method

+

Calling a Method

+
int a = 5;
+int b = 3;
+
+int ans = multiply(a, b)
+

The method call is multiply(a, b) and the result is stored in the variable ans

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar20.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar20.html new file mode 100644 index 0000000..5cc81bf --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar20.html @@ -0,0 +1,98 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for March 20th

+

Unit Testing

+

With unit testing you are able to test small parts as you go. With unit testing, you can test many examples and border cases (extreme inputs) to see how your code reacts to different input.

+

Variable Scope

+

A variable declared inside a method is only accessible inside that method.

+

A good rule of thumb is that if a variable is declared within curly braces {} then it does not exist outside that curly brace.

+

Method Overloading

+

Sometimes we need to have methods with the same name but different input parameters.

+
public static int multiply(int a, int b) {
+    return a * b;
+}
+

This method only works with integers, what if we want to multiply two doubles?

+

We can overload the method by declaring another method with the same name.

+
public static double multiply(double a, double b) {
+    return a * b;
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar22.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar22.html new file mode 100644 index 0000000..28daeca --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar22.html @@ -0,0 +1,123 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture on March 22nd

+

Method Documentation

+

Java has a special way that you can document your methods such that it will create documentation for you if you follow the convention.

+

The Java API actually uses this technique to produce its own documentation.

+

To create this, indicate a method with special comments that begin with /** and ends with */

+

It contains block tags that describe input and output parameters

+

@param and @return

+

Example

+
/**
+ * @param y an integer to sum
+ * @param x an integer to sum
+ * @return the sum of x and y
+ */
+public int multiply(int x, int y) {
+    return x + y;
+}
+

Passing a Scanner

+

We only want to create one user input scanner per program, we also only want one file input scanner per program.

+

If a method needs a scanner, you can pass the one you already created in as an input parameter.

+

Array as Input Parameter

+

Primitive types (int, char, double, etc.) are passed by value. Modifications made inside a method cannot be seen outside the method.

+

Arrays on the other hand, is pass by reference. Changes made to an array inside the method can be seen outside the method.

+
public static void main(String[] args) {
+    int[] nums = {1, 3, 5, 7, 9};
+
+    timesTwo(nums);
+}
+public static void timesTwo(int[] arr) {
+    for (int i = 0; i < arr.length; i++) {
+        arr[i] *= 2;
+    }
+}
+

At the end of the timesTwo method call, the variable nums would have {2, 6, 10, 14, 18}

+

Sizes of Arrays

+

Perfect Size Arrays

+

When we declare an array, Java automatically fills every slot of the array with the type in memory. So if you know that you need exactly 8 slots, then you only ask for 8.

+

Oversize Arrays

+

This is when we don't know how many slots we need. Therefore, we ask for more than we think we'll need. That way we don't go out of bounds.

+

If we do this, then we don't know how many elements we have already inserted into the array. Since the length is the number of slots.

+

So we can create another variable, which will keep track of the index in where we can add the next element.

+

We use oversized arrays when the size of the array is unknown or may change.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar27.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar27.html new file mode 100644 index 0000000..6abc56d --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar27.html @@ -0,0 +1,181 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for March 27

+

In the Real World...

+

Objects are known for having characteristics. A car has on average 4 wheels, 2-4 doors, a steering wheel.

+

Objects can perform actions. A car can drive, hold cargo, and honk.

+

In the Programming World...

+

Object-Oriented Programming

+ +

Class Structure

+
public class Classname {
+    // Fields
+    // Constructors
+    // Methods
+}
+

Fields

+

Fields are instance variables, they store values, help define state, and exist in memory for the lifetime of the object.

+
public class Car {
+    private double price;
+    private double gas;
+}
+

Constructor

+

We can build an object through a constructor. It is a special kind of method, this method requires that you not have a return type and that you name it the same as the class itself.

+

Constructors help set default field values for the different properties of our class.

+
public class Car {
+    // Begin Constructor
+    public Car(double cost) {
+        this.price = cost;
+        this.gas = 0;
+    }
+    // End Constructor
+    private double price;
+    private double gas;
+}
+

Note: The this keyword refers to the object's fields. This helps keep it separate from other variables you can create in the method and the input parameters you receive.

+

Accessor Method - "Getter"

+

We like to classify methods into two types, accessors and mutators.

+

Getter methods return a copy of an instance field. It does not change the state of the object.

+
public double getPrice() {
+    return this.price;
+}
+

Mutator Method - "Setter"

+

This type of method modifies an instance field. It does not return anything and changes the state of the object.

+
public void setPrice(double cost) {
+    this.price = cost;
+}
+

Example of Car Class In All Its Glory

+
public class Car {
+    // Instance Variables
+    private int mpg;
+    private double price;
+
+    // Constructors
+    public Car() {
+        this.price = 0;
+        this.mpg = 0;
+    }
+    public Car(double cost, int mpg) {
+        this.price = cost;
+        this.mpg = mpg;
+    }
+
+    // Accessors
+    public double getPrice() {
+        return this.price''
+    }
+    public int getMpg() {
+        return this.mpg;
+    }
+
+    // Mutators
+    public void setPrice(double cost) {
+        this.price = cost;
+    }
+    public void setMpg(int mpg) {
+        this.mpg = mpg;
+    }
+}
+

Using Classes

+

Just like how we used the Scanner class, we can also use our new Car class.

+
public class TestCar {
+    public static void main(String[] args) {
+        // Declare an object reference
+        Car c;
+
+        // Initialize the object
+        c = new Car();
+
+        // Update the fields of the object
+        c.setPrice(3000);
+        c.setMpg(22);
+
+        // Print object information
+        System.out.println("Price is " + c.getPrice() )
+    }
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar29.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar29.html new file mode 100644 index 0000000..9139a99 --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmar29.html @@ -0,0 +1,114 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture for March 29th

+

Enumerated Types

+

These represent a fixed set of constants and include all possible values within them.

+

Let's look at coins. On a daily basis in the US, we use the following coins:

+ +

Other examples include the days of the week, clothes sizes, etc.

+

Enum Syntax

+

Let's define an enum type

+
public enum Coin { PENNY, NICKEL, DIME, QUARTER}
+

Now declare and initialize a variable

+
Coin myCoin = Coin.PENNY
+

Arrays vs ArrayList

+

Arrays require you to say upfront, how many slots you need. ArrayLists are more flexible since you can change the length of the array during Runtime.

+

Arrays can store objects and primitives such as int, char, boolean, etc.

+

ArrayLists can only store objects.

+

How to declare an ArrayList

+
ArrayList<objectType> list = new ArrayList<objectType>();
+

Differences between getting the length of the array

+

Array

+
int length = array.length;
+

ArrayList

+
int length = array.size();
+

For Each Loop

+

This is a special loop in where you tell it to go through all the elements of the array, without specifying an index.

+
for (String b : buildings) {
+    System.out.print(b);
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmidtermreview.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmidtermreview.html new file mode 100644 index 0000000..ed765ac --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220%2Fmidtermreview.html @@ -0,0 +1,102 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

More Midterm Review

+

Let us suppose that we have the following array

+
int[] b = {11, 12, 15, 16, 21}
+

Increase all elements by 2

+
for (int i = 0; i < b.length; i++) {
+    b[i] += 2;
+}
+

Print all elements of array

+
for (int i = 0; i < b.length; i++) {
+    System.out.println(b[i]);
+}
+

Sum all the elements of an array

+
int sum = 0;
+for (int i = 0; i < b.length; i++) {
+    sum += b[i];
+}
+

Access Last Element of Array

+
System.out.println(b[b.length - 1]);
+

Access the middle element

+
System.out.println(b[b.length / 2]);
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220.html b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220.html new file mode 100644 index 0000000..7cc8c3c --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fspring2018%2Fcpsc220.html @@ -0,0 +1,101 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

CPSC 220 Computer Programming and Problem Solving Spring 2018

+

Lecture 1 -- January 16

+

Lecture 2 -- January 18

+

Lecture 3 -- January 23

+

Lecture 4 -- January 25

+

Lecture 5 -- January 30

+

Lecture 6 -- February 1

+

Lecture 7 -- February 6

+

Lecture 8 -- February 8

+

Lecture 9 -- February 13

+

Lecture 10 -- February 20

+

Lecture 11 -- February 27

+

Midterm Review

+

Lecture 12 -- March 13

+

Lecture 13 -- March 20

+

Lecture 14 -- March 22

+

Lecture 15 -- March 27

+

Lecture 16 -- March 29

+

Lecture 17 -- April 3

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide%2Fsummer2017%2Fcpsc110.html b/static/~brozek/index.html?labaide%2Fsummer2017%2Fcpsc110.html new file mode 100644 index 0000000..3abdd5a --- /dev/null +++ b/static/~brozek/index.html?labaide%2Fsummer2017%2Fcpsc110.html @@ -0,0 +1,89 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

CPSC 110 Introduction to Computer Science Summer 2017

+

For the summer session, I didn't write in depth lecture notes. Instead I wrote short complementary material on my old website to help out with the labs.

+

Viewing Java Applets

+

Using System Themes in Java Swing

+

Java Swing Components

+

Escape Sequences in Java

+

Obtaining Command Line Input in Java

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?labaide.html b/static/~brozek/index.html?labaide.html new file mode 100644 index 0000000..734c45a --- /dev/null +++ b/static/~brozek/index.html?labaide.html @@ -0,0 +1,95 @@ + + + + + + + + + Lab Aide | Brandon Rozek + + + + + + +
+
+

Lab Aide

+

Dr. Zeitz Self

+

I am the lab aide one of her sections on Computer Programming and Problem Solving (CPSC 220).

+

My role in this class is to help students during lab time and to create lecture notes based on the lectures given in class.

+

Spring 2018/CPSC 220 Notes

+

Dr. Jennifer Polack

+

I've been the lab aide for two of Polack's classes so far: Introduction to Computer Science (CPSC 110) and Computer Programming and Problem Solving (CPSC 220).

+

My role involves helping students debug during the lab time. I also create lecture notes for students to look over while working on projects.

+

Summer 2017/CPSC 110 Notes

+

Fall 2017/CPSC 220 Lecture Notes

+

Dr. Ron Zacharski

+

I was the lab aide for Zacharski's DATA 101 class. My role in his class mostly involved helping students debug during lab time and grading student's demonstrations of what they've done in a lab.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?presentations.html b/static/~brozek/index.html?presentations.html new file mode 100644 index 0000000..322b5d4 --- /dev/null +++ b/static/~brozek/index.html?presentations.html @@ -0,0 +1,90 @@ + + + + + + + + + Presentations | Brandon Rozek + + + + + + +
+
+

Presentations

+

Embezzlement of Parking Meter Funds: A Computational Approach to Hypothesis Testing

+

I was invited to give a talk to the Data Science Group at the University of Mary Washington called the Data Mavens. It was a 25 minute presentation on the bootstrap resampling technique with code on how to get started.

+

Slides PDF

+

Similyrics: A Music Recommendation Engine Based on Lyrics

+

At the VCU RamHacks hackathon, Clare Arrington, Harrison Crosse, and I demoed our product Similyrics. It's a web application that takes your favorite song, grabs the lyrics, and finds a song from a database that closely matches to the song you have chosen lyric wise.

+

Slides PDF

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec1.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec1.html new file mode 100644 index 0000000..3c763a8 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec1.html @@ -0,0 +1,302 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Measures of similarity

+

To identify clusters of observations we need to know how close individuals are to each other or how far apart they are.

+

Two individuals are 'close' when their dissimilarity of distance is small and their similarity large.

+

Special attention will be paid to proximity measures suitable for data consisting of repeated measures of the same variable, for example taken at different time points.

+

Similarity Measures for Categorical Data

+

Measures are generally scaled to be in the interval $[0, 1]$, although occasionally they are expressed as percentages in the range $0-100\%$

+

Similarity value of unity indicates that both observations have identical values for all variables

+

Similarity value of zero indicates that the two individuals differ maximally for all variables.

+

Similarity Measures for Binary Data

+

An extensive list of similarity measures for binary data exist, the reason for such is that a large number of possible measures has to do with the apparent uncertainty as to how to deal with the count of zero-zero matches

+

In some cases, zero-zero matches are equivalent to one-one matches and therefore should be included in the calculated similarity measure

+

Example: Gender, where there is no preference as to which of the two categories should be coded as zero or one

+

In other cases the inclusion or otherwise of the matches is more problematic

+

Example: When the zero category corresponds to the genuine absence of some property, such as wings in a study of insects

+

The question that then needs to be asked is do the co-absences contain useful information about the similarity of the two objects?

+

Attributing a high degree of similarity to a pair of individuals simply because they both lack a large number of attributes may not be sensible in many situations

+

The following table below will help when it comes to interpreting the measures

+

img

+

Measure that ignore the co-absence (lack of both objects having a zero) are Jaccard's Coefficient (S2), Sneath and Sokal (S4)

+

When co-absences are considered informative, the simple matching coefficient (S1) is usually employed.

+

Measures S3 and S5 are further examples of symmetric coefficients that treat positive matches (a) and negative matches (d) in the same way.

+

![BinarySimilarityMeasures](/home/rozek/Documents/Spring2018/Cluster Analysis/BinarySimilarityMeasures.png)

+

Similarity Measures for Categorical Data with More Than Two Levels

+

Categorical data where the variables have more than two levels (for example, eye color) could be dealt with in a similar way to binary data, with each level of a variable being regarded as a single binary variable.

+

This is not an attractive approach, however, simply because of the large number of ‘negative’ matches which will inevitably be involved.

+

A superior method is to allocate a score of zero or one to each variable depending on whether the two observations are the same on that variable. These scores are then averaged over all p variables to give the required similarity coefficient as +$$ +s{ij} = \frac{1}{p}\sum{k = 1}^p{s_{ik}} +$$

+

Dissimilarity and Distance Measures for Continuous Data

+

A metric on a set $X$ is a distance function +$$ +d : X \times X \to [0, \infty) +$$ +where $[0, \infty)$ is the set of non-negative real numbers and for all $x, y, z \in X$, the following conditions are satisfied

+
    +
  1. $d(x, y) \ge 0$ non-negativity or separation axiom +
      +
    1. $d(x, y) = 0 \iff x = y$ identity of indiscernibles
    2. +
  2. +
  3. $d(x, y) = d(y, x)$ symmetry
  4. +
  5. $d(x, z) \le d(x, y) + d(y, z)$ subadditivity or triangle inequality
  6. +
+

Conditions 1 and 2 define a positive-definite function

+

All distance measures are formulated so as to allow for differential weighting of the quantitative variables $w_k$ denotes the nonnegative weights of $p$ variables

+

![continuousdissimilaritymeasures](/home/rozek/Documents/Spring2018/Cluster Analysis/continuousdissimilaritymeasures.png)

+

Proposed dissimilarity measures can be broadly divided into distance measures and correlation-type measures.

+

Distance Measures

+
$L^p$ Space
+

The Minkowski distance is a metric in normed vector space which can be considered as a generalization of both the Euclidean distance and the Manhattan distance +$$ +D(X, Y) = (\sum_{i = 1}^n{w_i^p|x_i - y_i|^p})^{\frac{1}{p}} +$$ +This is a metric for $p > 1$

+
Manhattan Distance
+

This is the case in the Minkowski distance when $p = 1$ +$$ +d(X, Y) = \sum_{i = 1}^n{w_i|x_i - y_i|} +$$ +Manhattan distance depends on the rotation of the coordinate system, but does not depend on its reflection about a coordinate axis or its translation +$$ +d(x, y) = d(-x, -y) +$$

+

$$ +d(x, y) = d(x + a, y + a) +$$

+

Shortest paths are not unique in this metric

+
Euclidean Distance
+

This is the case in the Minkowski distance when $p = 2$. The Euclidean distance between points X and Y is the length of the line segment connection them. +$$ +d(X, Y) = \sqrt{\sum_{i = 1}^n{w_i^2(x_i - y_i)^2}} +$$ +There is a unique path in which it has the shortest distance. This distance metric is also translation and rotation invariant

+
Squared Euclidean Distance
+

The standard Euclidean distance can be squared in order to place progressively greater weight on objects that are farther apart. In this case, the equation becomes +$$ +d(X, Y) = \sum_{i = 1}^n{w_i^2(x_i - y_i)^2} +$$ +Squared Euclidean Distance is not a metric as it does not satisfy the triangle inequality, however, it is frequently used in optimization problems in which distances only have to be compared.

+
Chebyshev Distance
+

The Chebyshev distance is where the distance between two vectors is the greatest of their differences along any coordinate dimension.

+

It is also known as chessboard distance, since in the game of chess the minimum number of moves needed by a king to go from one square on a chessboard to another equals the Chebyshev distance +$$ +d(X, Y) = \lim{p \to \infty}{(\sum{i = 1}^n{|x_i - y_i|^p})}^\frac{1}{p} +$$

+

$$ += max_i(|x_i - y_i|) +$$

+

Chebyshev distance is translation invariant

+
Canberra Distance Measure
+

The Canberra distance (D4) is a weighted version of the $L1$ Manhattan distance. This measure is very sensitive to small changes close to $x{ik} = x_{jk} = 0$.

+

It is often regarded as a generalization of the dissimilarity measure for binary data. In this context the measure can be divided by the number of variables, $p$, to ensure a dissimilarity coefficient in the interval $[0, 1]$

+

It can then be shown that this measure for binary variables is just one minus the matching coefficient.

+

Correlation Measures

+

It has often been suggested that the correlation between two observations can be used to quantify the similarity between them.

+

Since for correlation coefficients we have that $-1 \le \phi{ij} \le 1$ with the value ‘1’ reflecting the strongest possible positive relationship and the value ‘-1’ the strongest possible negative relationship, these coefficients can be transformed into dissimilarities, $d{ij}$, within the interval $[0, 1]$

+

The use of correlation coefficients in this context is far more contentious than its noncontroversial role in assessing the linear relationship between two variables based on $n$ observations.

+

When correlations between two individuals are used to quantify their similarity the rows of the data matrix are standardized, not its columns.

+

Disadvantages

+

When variables are measured on different scales the notion of a difference between variable values and consequently that of a mean variable value or a variance is meaningless.

+

In addition, the correlation coefficient is unable to measure the difference in size between two observations.

+

Advantages

+

However, the use of a correlation coefficient can be justified for situations where all of the variables have been measured on the same scale and precise values taken are important only to the extent that they provide information about the subject's relative profile

+

Example: In classifying animals or plants, the absolute size of the organisms or their parts are often less important than their shapes. In such studies the investigator requires a dissimilarity coefficient that takes the value zero if and only if two individuals' profiles are multiples of each other. The angular separation dissimilarity measure has this property.

+

Further considerations

+

The Pearson correlation is sensitive to outliers. This has prompted a number of suggestions for modifying correlation coefficients when used as similarity measures; for example, robust versions of correlation coefficients such as jackknife correlation or altogether more general association coefficients such as mutual information distance measure

+

Mahalanobis (Maximum) Distance [Not between 2 observations]

+

Mahalanobis distance is a measure of distance between a point P and a distribution D. It is a multi-dimensional generalization of the idea of measuring how many standard deviations away P is from the mean of D

+

Mahalanobis distance is unitless and scale-invariant and takes into account the correlations of the data set +$$ +D(\vec{x}) = \sqrt{(\vec{x} - \vec{\mu})^T S^{-1}(\vec{x}-\vec{\mu})} +$$ +Where $\mu$ is a set of mean observations and $S$ is the covariance matrix

+

If the covariance matrix is diagonal then the resulting distance measure is called a normalized Euclidean distance. +$$ +d(\vec{x}, \vec{y}) = \sqrt{\sum_{i = 1}^N{\frac{(x_i - y_i)^2}{s^2_i}}} +$$ +Where $s_i$ is the standard deviation of the $x_i$ and $y_i$ over the sample set

+

Discrete Metric

+

This metric describes whether or not two observations are equivalent +$$ +\rho(x, y) = \begin{cases} +1 & x \not= y \ +0 & x = y +\end{cases} +$$

+

Similarity Measures for Data Containing both Continuous and Categorical Variables

+

There are a number of approaches to constructing proximities for mixed-mode data, that is, data in which some variables are continuous and some categorical.

+
    +
  1. Dichotomize all variables and use a similarity measure for binary data
  2. +
  3. Rescale all the variables so that they are on the same scale by replacing variable values by their ranks among the objects and then using a measure for continuous data
  4. +
  5. Construct a dissimilarity measure for each type of variable and combine these, either with or without differential weighting into a single coefficient.
  6. +
+

Most general-purpose statistical software implement a number of measurs for converting two-mode data matrix into a one-mode dissimilarity matrix.

+

R has cluster, clusterSim, or proxy

+

Proximity Measures for Structured Data

+

We'll be looking at data that consists of repeated measures of the same outcome variable but under different conditions.

+

The simplest and perhaps most commonly used approach to exploiting the reference variable is in the construction of a reduced set of relevant summaries per object which are then used as the basis for defining object similarity.

+

Here we will look at some approaches for choosing summary measures and resulting proximity measures for the most frequently encountered reference vectors (e.g. time, experimental condition, and underlying factor)

+

Structured data arise when the variables can be assumed to follow a known factor model. Under confirmatory factor analysis model each variable or item can be allocated to one of a set of underlying factors or concepts. The factors cannot be observed directly but are 'indicated' by a number of items that are all measured on the same scale.

+

Note that the summary approach, while typically used with continuous variables, is not limited to variables on an interval scale. The same principles can be applied to dealing with categorical data. The difference is that summary measures now need to capture relevant aspects of the distribution of categorical variables over repeated measures.

+

Rows of $X$ which represent ordered lists of elements, that is all the variables provide a categorical outcome and these variables can be aligned in one dimension, are more generally referred to as sequences. Sequence analysis is an area of research that centers on problems of events and actions in their temporal context and includes the measurements of similarities between sequences.

+

The most popular measure of dissimilarity between two sequences is the Levenhstein distance and counts the minimum number of operations needed to transform one sequence of categories into another, where an operation is an insertion, a deletion, or a substitution of a single category. Each operation may be assigned a penalty weight (a typical choice would be to give double the penalty to a substitution as opposed to an insertion or deletion. The measure is sometimes called the 'edit distance' due to its application in spell checkers.

+

Optimal matching algorithms (OMAs) need to be employed to find the minimum number of operations required to match one sequence to another. One such algorithm for aligning sequences is the Needleman-Wunsch algorithm, which is commonly used in bioinformatics to align proteins.

+

The Jary similarity measure is a related measure of similarity between sequences of categories often used to delete duplicates in the area of record linkage.

+

Inter-group Proximity Measures

+

In clustering applications, it becomes necessary to consider how to measure the proximity between groups of individuals.

+
    +
  1. The proximity between two groups might be defined by a suitable summary of the proximities between individuals from either group
  2. +
  3. Each group might be described by a representative observation by choosing a suitable summary statistic for each variable, and the inter group proximity defined as the proximity between the representative observations.
  4. +
+

Inter-group Proximity Derived from the Proximity Matrix

+

For deriving inter-group proximities from a matrix of inter-individual proximities, there are a variety of possibilities

+ +

Inter-group Proximity Based on Group Summaries for Continuous Data

+

One method for constructing inter-group dissimilarity measures for continuous data is to simply substitute group means (also known as the centroid) for the variable values in the formulae for inter-individual measures

+

More appropriate, however, might be measures which incorporate in one way or another, knowledge of within-group variation. One possibility is to use Mahallanobis's generalized distance.

+

Mahalanobis (Maximum) Distance

+

Mahalanobis distance is a measure of distance between a point P and a distribution D. It is a multi-dimensional generalization of the idea of measuring how many standard deviations away P is from the mean of D

+

Mahalanobis distance is unitless and scale-invariant and takes into account the correlations of the data set +$$ +D(\vec{x}) = \sqrt{(\vec{x} - \vec{\mu})^T S^{-1}(\vec{x}-\vec{\mu})} +$$ +Where $\mu$ is a set of mean observations and $S$ is the covariance matrix

+

If the covariance matrix is diagonal then the resulting distance measure is called a normalized Euclidean distance. +$$ +d(\vec{x}, \vec{y}) = \sqrt{\sum_{i = 1}^N{\frac{(x_i - y_i)^2}{s^2_i}}} +$$ +Where $s_i$ is the standard deviation of the $x_i$ and $y_i$ over the sample set

+

Thus, the Mahalanobis distance incraeses with increasing distances between the two group centers and with decreasing within-group variation.

+

By also employing within-group correlations, the Mahalanobis distance takes account the possibly non-spherical shapes of the groups.

+

The use of Mahalanobis implies that the investigator is willing to assume that the covariance matrices are at least approximately the same in the two groups. When this is not so, this measure is an inappropriate inter-group measure. Other alternatives exist such as the one proposed by Anderson and Bahadur

+equation +

Another alternative is the normal information radius suggested by Jardine and Sibson

+equation +

Inter-group Proximity Based on Group Summaries for Categorical Data

+

Approaches for measuring inter-group dissimilarities between groups of individuals for which categorical variables have been observed have been considered by a number of authors. Balakrishnan and Sanghvi (1968), for example, proposed a dissimilarity index of the form

+

equation

+

where $p{Akl}$ and $p{Bkl}$ are the proportions of the lth category of the kth variable in group A and B respectively, img, ck + 1 is the number of categories for the kth variable and p is the number of variables.

+

Kurczynski (1969) suggested adapting the generalized Mahalanobis distance, with categorical variables replacing quantitative variables. In its most general form, this measure for inter-group distance is given by

+

equation

+

where img contains sample proportions in group A and img is defined in a similar manner, and img is the m × m common sample covariance matrix, where img.

+

Weighting Variables

+

To weight a variable means to give it greater or lesser importance than other variables in determining the proximity between two objects.

+

The question is 'How should the weights be chosen?' Before we discuss this question, it is important to realize that the selection of variables for inclusion into the study already presents a form of weighting, since the variables not included are effectively being given the weight $0$.

+

The weights chosen for the variables reflect the importance that the investigator assigns the variables for the classification task.

+

There are several approaches to this

+ +

The second approach assumed the importance of a variable to be inversely proportional to the total variability of that variable. The total variability of a variable comprises variation both within and between groups which may exist within the set of individuals. The aim of cluster analysis is typically to identify such groups. Hence it can be argued that the importance of a variable should not be reduced because of between-group variation (on the contrary, one might wish to assign more importance to a variable that shows larger between-group variation.)

+

Gnanadesikan et al. (1995) assessed the ability of squared distance functions based on data-determined weights, both those described above and others, to recover groups in eight simulated and real continuous data sets in a subsequent cluster analysis. Their main findings were:

+
    +
  1. Equal weights, (total) standard deviation weights, and range weights were generally ineffective, but range weights were preferable to standard deviation weights.
  2. +
  3. Weighting based on estimates of within-cluster variability worked well overall.
  4. +
  5. Weighting aimed at emphasizing variables with the most potential for identifying clusters did enhance clustering when some variables had a strong cluster structure.
  6. +
  7. Weighting to optimize the fitting of a hierarchical tree was often even less effective than equal weighting or weighting based on (total) standard deviations.
  8. +
  9. Forward variable selection was often among the better performers. (Note that all-subsets variable selection was not assessed at the time.)
  10. +
+

Standardization

+

In many clustering applications, the variables describing the objects to be clustered will not be measured in the same units. A number of variability measures have been used for this purpose

+ +

The second is shown to outperform auto-scaling in many clustering applications. As pointed out in the previous section, standardization of variables to unit variance can be viewed as a special case of weighting.

+

Choice of Proximity Measure

+

Firstly, the nature of the data should strongly influence the choice of the proximity measure.

+

Next, the choice of measure should depend on the scale of the data. Similarity coefficients should be used when the data is binary. For continuous data, distance of correlation-type dissimilarity measure should be used according to whether 'size' or 'shape' of the objects is of interest.

+

Finally, the clustering method to be used might have some implications for the choice of the coefficient. For example, making a choice between several proximity coefficients with similar properties which are also known to be monotonically related can be avoided by employing a cluster method that depends only on the ranking of the proximities, not their absolute values.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec10-1.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec10-1.html new file mode 100644 index 0000000..2f5c83e --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec10-1.html @@ -0,0 +1,106 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Silhouette

+

This technique validates the consistency within clusters of data. It provides a succinct graphical representation of how well each object lies in its cluster.

+

The silhouette ranges from -1 to 1 where a high value indicates that the object is consistent within its own cluster and poorly matched to neighboring clustesr.

+

A low or negative silhouette value can mean that the current clustering configuration has too many or too few clusters.

+

Definition

+

For each datum $i$, let $a(i)$ be the average distance of $i$ with all other data within the same cluster.

+

$a(i)$ can be interpreted as how well $i$ is assigned to its cluster. (lower values mean better agreement)

+

We can then define the average dissimilarity of point $i$ to a cluster $c$ as the average distance from $i$ to all points in $c$.

+

Let $b(i)$ be the lowest average distance of $i$ to all other points in any other cluster in which i is not already a member.

+

The cluster with this lowest average dissimilarity is said to be the neighboring cluster of $i$. From here we can define a silhouette: +$$ +s(i) = \frac{b(i) - a(i)}{max{a(i), b(i)}} +$$ +The average $s(i)$ over all data of a cluster is a measure of how tightly grouped all the data in the cluster are. A silhouette plot may be used to visualize the agreement between each of the data and its cluster.

+

img

+

Properties

+

Recall that $a(i)$ is a measure of how dissimilar $i$ is to its own cluster, a smaller value means that it's in agreement to its cluster. For $s(i)$ to be close to 1, we require $a(i) << b(i)$ .

+

If $s(i)$ is close to negative one, then by the same logic we can see that $i$ would be more appropriate if it was clustered in its neighboring cluster.

+

$s(i)$ near zero means that the datum is on the border of two natural clusters.

+

Determining the number of Clusters

+

This can also be used in helping to determine the number of clusters in a dataset. The ideal number of cluster is one that produces the highest silhouette value.

+

Also a good indication that one has too many clusters is if there are clusters with the majority of observations being under the mean silhouette value.

+

https://kapilddatascience.wordpress.com/2015/11/10/using-silhouette-analysis-for-selecting-the-number-of-cluster-for-k-means-clustering/

+

plot_kmeans_silhouette_analysis_004

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec10-2.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec10-2.html new file mode 100644 index 0000000..a0bf33d --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec10-2.html @@ -0,0 +1,115 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Centroid-based Clustering

+

In centroid-based clustering, clusters are represented by some central vector which may or may not be a member of the dataset. In practice, the number of clusters is fixed to $k$ and the goal is to solve some sort of optimization problem.

+

The similarity of two clusters is defined as the similarity of their centroids.

+

This problem is computationally difficult so there are efficient heuristic algorithms that are commonly employed. These usually converge quickly to a local optimum.

+

K-means clustering

+

This aims to partition $n$ observations into $k$ clusters in which each observation belongs to the cluster with the nearest mean which serves as the centroid of the cluster.

+

This technique results in partitioning the data space into Voronoi cells.

+

Description

+

Given a set of observations $x$, k-means clustering aims to partition the $n$ observations into $k$ sets $S$ so as to minimize the within-cluster sum of squares (i.e. variance). More formally, the objective is to find +$$ +argmins{\sum{i = 1}^k{\sum_{x \in S_i}{||x-\mui||^2}}}= argmin{s}{\sum_{i = 1}^k{|S_i|Var(S_i)}} +$$ +where $\mu_i$ is the mean of points in $S_i$. This is equivalent to minimizing the pairwise squared deviations of points in the same cluster +$$ +argmins{\sum{i = 1}^k{\frac{1}{2|Si|}\sum{x, y \in S_i}{||x-y||^2}}} +$$

+

Algorithm

+

Given an initial set of $k$ means, the algorithm proceeds by alternating between two steps.

+

Assignment step: Assign each observation to the cluster whose mean has the least squared euclidean distance.

+ +

Update Step: Calculate the new means to be the centroids of the observations in the new clusters

+

The algorithm is known to have converged when assignments no longer change. There is no guarantee that the optimum is found using this algorithm.

+

The result depends on the initial clusters. It is common to run this multiple times with different starting conditions.

+

Using a different distance function other than the squared Euclidean distance may stop the algorithm from converging.

+

Initialization methods

+

Commonly used initialization methods are Forgy and Random Partition.

+

Forgy Method: This method randomly chooses $k$ observations from the data set and uses these are the initial means

+

This method is known to spread the initial means out

+

Random Partition Method: This method first randomly assigns a cluster to each observation and then proceeds to the update step.

+

This method is known to place most of the means close to the center of the dataset.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec10-3.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec10-3.html new file mode 100644 index 0000000..0503664 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec10-3.html @@ -0,0 +1,90 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Voronoi Diagram

+

A Voronoi diagram is a partitioning of a plan into regions based on distance to points in a specific subset of the plane.

+

The set of points (often called seeds, sites, or generators) is specified beforehand, and for each seed there is a corresponding region consisting of all points closer to that seed than any other.

+

Different metrics may be used and often result in different Voronoi diagrams

+

Euclidean

+

+

Manhattan

+

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec11-1.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec11-1.html new file mode 100644 index 0000000..d8e4445 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec11-1.html @@ -0,0 +1,95 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

K-means++

+

K-means++ is an algorithm for choosing the initial values or seeds for the k-means clustering algorithm. This was proposed as a way of avoiding the sometimes poor clustering found by a standard k-means algorithm.

+

Intuition

+

The intuition behind this approach involves spreading out the $k$ initial cluster centers. The first cluster center is chosen uniformly at random from the data points that are being clustered, after which each subsequent cluster center is chosen from the remaining data points with probability proportional to its squared distance from the point's closest existing cluster center.

+

Algorithm

+

The exact algorithm is as follows

+
    +
  1. Choose one center uniformly at random from among data points
  2. +
  3. For each data point $x$, compute $D(x)$, the distance between $x$ and the nearest center that has already been chosen.
  4. +
  5. Choose one new data point at random as a new center, using a weighted probability distribution where a point $x$ is chosen with probability proporitonal to $D(x)^2$
  6. +
  7. Repeat steps 2 and 3 until $k$ centers have been chosen
  8. +
  9. Now that the initial centers have been chosen, proceed using standard k-means clustering
  10. +
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec11-2.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec11-2.html new file mode 100644 index 0000000..fdad8d2 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec11-2.html @@ -0,0 +1,118 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

K-Medoids

+

A medoid can be defined as the object of a cluster whose average dissimilarity to all the objects in the cluster is minimal.

+

The K-medoids algorithm is related to k-means and the medoidshift algorithm. Both the k-means and k-medoids algorithms are partition and both attempt to minimize the distance between points in the cluster to it's center. In contrast to k-means, it chooses data points as centers and uses the Manhattan Norm to define the distance between data points instead of the Euclidean.

+

This method is known to be more robust to noise and outliers compared to k-means since it minimizes the sum of pairwise dissimilarities instead of the sum of squared Euclidean distances.

+

Algorithms

+

There are several algorithms that have been created as an optimization to an exhaustive search. In this section, we'll discuss PAM and Voronoi iteration method.

+

Partitioning Around Medoids (PAM)

+
    +
  1. Select $k$ of the $n$ data points as medoids
  2. +
  3. Associate each data point to the closes medoid
  4. +
  5. While the cost of the configuration decreases: +
      +
    1. For each medoid $m$, for each non-medoid data point $o$: +
        +
      1. Swap $m$ and $o$, recompute the cost (sum of distances of points to their medoid)
      2. +
      3. If the total cost of the configuration increased in the previous step, undo the swap
      4. +
    2. +
  6. +
+

Voronoi Iteration Method

+
    +
  1. Select $k$ of the $n$ data points as medoids
  2. +
  3. While the cost of the configuration decreases +
      +
    1. In each cluster, make the point that minimizes the sum of distances within the cluster the medoid
    2. +
    3. Reassign each point to the cluster defined by the closest medoid determined in the previous step.
    4. +
  4. +
+

Clustering Large Applications (CLARA

+

This is a variant of the PAM algorithm that relies on the sampling approach to handle large datasets. The cost of a particular cluster configuration is the mean cost of all the dissimilarities.

+

R Implementations

+

Both PAM and CLARA are defined in the cluster package in R.

+
clara(x, k, metric = "euclidean", stand = FALSE, samples = 5, 
+      sampsize = min(n, 40 + 2 * k), trace = 0, medoids.x = TRUE,
+      keep.data = medoids.x, rngR = FALSE)
+
pam(x, k, metric = "euclidean", stand = FALSE)
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec11-3.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec11-3.html new file mode 100644 index 0000000..1aa9265 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec11-3.html @@ -0,0 +1,94 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

K-Medians

+

This is a variation of k-means clustering where instead of calculating the mean for each cluster to determine its centroid we are going to calculate the median instead.

+

This has the effect of minimizing error over all the clusters with respect to the Manhattan norm as opposed to the Euclidean squared norm which is minimized in K-means

+

Algorithm

+

Given an initial set of $k$ medians, the algorithm proceeds by alternating between two steps.

+

Assignment step: Assign each observation to the cluster whose median has the leas Manhattan distance.

+ +

Update Step: Calculate the new medians to be the centroids of the observations in the new clusters

+

The algorithm is known to have converged when assignments no longer change. There is no guarantee that the optimum is found using this algorithm.

+

The result depends on the initial clusters. It is common to run this multiple times with different starting conditions.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec12.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec12.html new file mode 100644 index 0000000..4a7e463 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec12.html @@ -0,0 +1,124 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Introduction to Density Based Clustering

+

In density-based clustering, clusters are defined as areas of higher density than the remainder of the data sets. Objects in more sparse areas are considered to be outliers or border points. This helps discover clusters of arbitrary shape.

+

DBSCAN

+

Given a set of points in space, it groups together points that are closely packed together while marking points that lie alone in low-density regions as outliers.

+

Preliminary Information

+ +

Non core points can be part of a cluster, but they form its "edge", since they cannot be used to reach more points.

+

Reachability is not a symmetric relation since, by definition, no point may be reachable from a non-core point, regardless of distance.

+

Two points $p$ and $q$ are density-connected if there is a point $o$ such that both $p$ and $q$ are reachable from $o$. Density-connectedness is symmetric.

+

A cluster then satisfies two properties:

+
    +
  1. All points within the cluster are mutually density-connected
  2. +
  3. If a point is density-reachable from any point of the cluster, it is part of the cluster as well.
  4. +
+

Algorithm

+
    +
  1. Find the $\epsilon$ neighbors of every point, and identify the core points with more than $k$ neighbors.
  2. +
  3. Find the connected components of core points on the neighborhood graph, ignoring all non-core points.
  4. +
  5. Assign each non-core point to a nearby cluster if the cluster is an $\epsilon$ (eps) neighbor, otherwise assign it to noise.
  6. +
+

Advantages

+ +

Disadvantages

+ +

Rule of Thumbs for parameters

+

$k$: $k$ must be larger than $(D + 1)$ where $D$ is the number of dimensions in the dataset. Normally $k$ is chosen to be twice the number of dimensions.

+

$\epsilon$: Ideally the $k^{th}$ nearest neighbors are at roughly the same distance. Plot the sorted distance of every point to it's $k^{th}$ nearest neighbor

+

Example of Run Through

+

https://www.cse.buffalo.edu/~jing/cse601/fa12/materials/clustering_density.pdf

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec2-1.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec2-1.html new file mode 100644 index 0000000..9d2fd3c --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec2-1.html @@ -0,0 +1,99 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Why use different distance measures?

+

I made an attempt to find out in what situations people use different distance measures. Looking around in the Internet usually produces the results "It depends on the problem" or "I typically just always use Euclidean"

+

Which as you might imagine, isn't a terribly useful answer. Since it doesn't give me any examples of which types of problems different distances solve.

+

Therefore, let's think about it in a different way. What properties do different distance measures have that make them desirable?

+

Manhattan Advantages

+ +

https://datascience.stackexchange.com/questions/20075/when-would-one-use-manhattan-distance-as-opposite-to-euclidean-distance

+

Mahalanobis Advantages

+

Variables can be on different scales. The Mahalanobis formula has a built in variance-covariance matrix which allows you to rescale your variables to make distances of different variables more comparable.

+

https://stats.stackexchange.com/questions/50949/why-use-the-mahalanobis-distance#50956

+

Euclidean Disadvantages

+

In higher dimensions, the points essentially become uniformly distant from one another. This is a problem observed in most distance metrics but it's more obvious with the Euclidean one.

+

https://stats.stackexchange.com/questions/99171/why-is-euclidean-distance-not-a-good-metric-in-high-dimensions/

+

Hopefully in this course, we'll discover more properties as to why it makes sense to use different distance measures since it can have a impact on how our clusters are formed.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec2-2.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec2-2.html new file mode 100644 index 0000000..c9a4e72 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec2-2.html @@ -0,0 +1,123 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Principal Component Analysis Pt. 1

+

What is PCA?

+

Principal component analysis is a statistical procedure that performs an orthogonal transformation to convert a set of variables into a set of linearly uncorrelated variables called principle components.

+

Number of distinct principle components equals $min(# Variables, # Observations - 1)$

+

The transformation is defined in such a way that the first principle component has the largest possible variance explained in the data.

+

Each succeeding component has the highest possible variance under the constraint of having to be orthogonal to the preceding components.

+

PCA is sensitive to the relative scaling of the original variables.

+

Results of a PCA

+

Results are discussed in terms of component scores which is the transformed variables and loadings which is the weight by which each original variable should be multiplied to get the component score.

+

Assumptions of PCA

+
    +
  1. Linearity
  2. +
  3. Large variances are important and small variances denote noise
  4. +
  5. Principal components are orthogonal
  6. +
+

Why perform PCA?

+ +

Computing PCA

+
    +
  1. Subtract off the mean of each measurement type
  2. +
  3. Compute the covariance matrix
  4. +
  5. Take the eigenvalues/vectors of the covariance matrix
  6. +
+

R Code

+
pcal = function(data) {
+  centered_data = scale(data)
+  covariance = cov(centered_data)
+  eigen_stuff = eigen(covariance)
+  sorted_indices = sort(eigen_stuff$values, 
+                        index.return = T, 
+                        decreasing = T)$ix
+  loadings = eigen_stuff$values[sorted_indices]
+  components = eigen_stuff$vectors[sorted_indices,]
+  combined_list = list(loadings, components)
+  names(combined_list) = c("Loadings", "Components")
+  return(combined_list)
+}
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec4-2.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec4-2.html new file mode 100644 index 0000000..fb1f00b --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec4-2.html @@ -0,0 +1,96 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Revisiting Similarity Measures

+

Manhatten Distance

+

An additional use case for Manhatten distance is when dealing with binary vectors. This approach, otherwise known as the Hamming distance, is the number of bits that are different between two binary vectors.

+

Ordinal Variables

+

Ordinal variables can be treated as if they were on a interval scale.

+

First, replace the ordinal variable value by its rank ($r_{if}$) Then map the range of each variable onto the interval $[0, 1]$ by replacing the $fi$ where f is the variable and i is the object by +$$ +z{if} = \frac{r_{if} - 1}{M_f - 1} +$$ +Where $M_f$ is the maximum rank.

+

Example

+

Freshman = $0$ Sophmore = $\frac{1}{3}$ Junior = $\frac{2}{3}$ Senior = $1$

+

$d(freshman, senior) = 1$

+

$d(junior, senior) = \frac{1}{3}$

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec4-3.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec4-3.html new file mode 100644 index 0000000..0a1a562 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec4-3.html @@ -0,0 +1,103 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Cluster Tendency

+

This is the assessment of the suitability of clustering. Cluster Tendency determines whether the data has any inherent grouping structure.

+

This is a hard task since there are so many different definitions of clusters (portioning, hierarchical, density, graph, etc.) Even after fixing a cluster type, this is still hard in defining an appropriate null model for a data set.

+

One way we can go about measuring cluster tendency is to compare the data against random data. On average, random data should not contain clusters.

+

There are some clusterability assessment methods such as Spatial histogram, distance distribution and Hopkins statistic.

+

Hopkins Statistic

+

Let $X$ be the set of $n$ data points in $d$ dimensional space. Consider a random sample (without replacement) of $m << n$ data points. Also generate a set $Y$ of $m$ uniformly randomly distributed data points.

+

Now define two distance measures $u_i$ to be the distance of $y_i \in Y$ from its nearest neighbor in X and $w_i$ to be the distance of $x_i \in X$ from its nearest neighbor in X

+

We can then define Hopkins statistic as +$$ +H = \frac{\sum_{i = 1}^m{ui^d}}{\sum{i = 1}^m{ui^d} + \sum{i =1}^m{w_i^d}} +$$

+

Properties

+

With this definition, uniform random data should tend to have values near 0.5, and clustered data should tend to have values nearer to 1.

+

Drawbacks

+

However, data containing a single Gaussian will also score close to one. As this statistic measures deviation from a uniform distribution. Making this statistic less useful in application as real data is usually not remotely uniform.

+

Spatial Histogram Approach

+

For this method, I'm not too sure how this works, but here are some key points I found.

+

Divide each dimension in equal width bins, and count how many points lie in each of the bins and obtain the empirical joint probability mass function.

+

Do the same for the randomly sampled data

+

Finally compute how much they differ using the Kullback-Leibler (KL) divergence value. If it differs greatly than we can say that the data is clusterable.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec4.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec4.html new file mode 100644 index 0000000..c41be62 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec4.html @@ -0,0 +1,217 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Principal Component Analysis Part 2: Formal Theory

+

Properties of PCA

+

There are a number of ways to maximize the variance of a principal component. To create an unique solution we should impose a constraint. Let us say that the sum of the square of the coefficients must equal 1. In vector notation this is the same as +$$ +a_i^Ta_i = 1 +$$ +Every future principal component is said to be orthogonal to all the principal components previous to it. +$$ +a_j^Tai = 0, i < j +$$ +The total variance of the $q$ principal components will equal the total variance of the original variables +$$ +\sum{i = 1}^q {\lambda_i} = trace(S) +$$ +Where $S$ is the sample covariance matrix.

+

The proportion of accounted variation in each principle component is +$$ +P_j = \frac{\lambdaj}{trace(S)} +$$ +From this, we can generalize to the first $m$ principal components where $m < q$ and find the proportion $P^{(m)}$ of variation accounted for +$$ +P^{(m)} = \frac{\sum{i = 1}^m{\lambda_i}}{trace(S)} +$$ +You can think of the first principal component as the line of best fit that minimizes the residuals orthogonal to it.

+

What to watch out for

+

As a reminder to the last lecture, PCA is not scale-invariant. Therefore, transformations done to the dataset before PCA and after PCA often lead to different results and possibly conclusions.

+

Additionally, if there are large differences between the variances of the original variables, then those whose variances are largest will tend to dominate the early components.

+

Therefore, principal components should only be extracted from the sample covariance matrix when all of the original variables have roughly the same scale.

+

Alternatives to using the Covariance Matrix

+

But it is rare in practice to have a scenario when all of the variables are of the same scale. Therefore, principal components are typically extracted from the correlation matrix $R$

+

Choosing to work with the correlation matrix rather than the covariance matrix treats the variables as all equally important when performing PCA.

+

Example Derivation: Bivariate Data

+

Let $R$ be the correlation matrix +$$ +R = \begin{pmatrix} +1 & r \ +r & 1 +\end{pmatrix} +$$ +Let us find the eigenvectors and eigenvalues of the correlation matrix +$$ +det(R - \lambda I) = 0 +$$

+

$$ +(1-\lambda)^2 - r^2 = 0 +$$

+

$$ +\lambda_1 = 1 + r, \lambda_2 = 1 - r +$$

+

Let us remember to check the condition "sum of the principal components equals the trace of the correlation matrix": +$$ +\lambda_1 + \lambda_2 = 1+r + (1 - r) = 2 = trace(R) +$$

+

Finding the First Eigenvector

+

Looking back at the characteristic equation +$$ +Ra_1 = \lambda a1 +$$ +We can get the following two formulas +$$ +a{11} + ra{12} = (1+r)a{11} \tag{1} +$$

+

$$ +ra{11} + a{12} = (1 + r)a_{12} \tag{2} +$$

+

Now let us find out what $a{11}$ and $a{12}$ equal. First let us solve for $a{11}$ using equation $(1)$ +$$ +ra{12} = (1+r)a{11} - a{11} +$$

+

$$ +ra{12} = a{11}(1 + r - 1) +$$

+

$$ +ra{12} = ra{11} +$$

+

$$ +a{12} = a{11} +$$

+

Where $r$ does not equal $0$.

+

Now we must apply the condition of sum squares +$$ +a_1^Ta_1 = 1 +$$

+

$$ +a{11}^2 + a{12}^2 = 1 +$$

+

Recall that $a{12} = a{11}$ +$$ +2a_{11}^2 = 1 +$$

+

$$ +a_{11}^2 = \frac{1}{2} +$$

+

$$ +a_{11} =\pm \frac{1}{\sqrt{2}} +$$

+

For sake of choosing a value, let us take the principal root and say $a_{11} = \frac{1}{\sqrt{2}}$

+

Finding the Second Eigenvector

+

Recall the fact that each subsequent eigenvector is orthogonal to the first. This means +$$ +a{11}a{21} + a{12}a{22} = 0 +$$ +Substituting the values for $a{11}$ and $a{12}$ calculated in the previous section +$$ +\frac{1}{\sqrt{2}}a{21} + \frac{1}{\sqrt{2}}a{22} = 0 +$$

+

$$ +a{21} + a{22} = 0 +$$

+

$$ +a{21} = -a{22} +$$

+

Since this eigenvector also needs to satisfy the first condition, we get the following values +$$ +a{21} = \frac{1}{\sqrt{2}} , a{22} = \frac{-1}{\sqrt{2}} +$$

+

Conclusion of Example

+

From this, we can say that the first principal components are given by +$$ +y_1 = \frac{1}{\sqrt{2}}(x_1 + x_2), y_2 = \frac{1}{\sqrt{2}}(x_1-x_2) +$$ +With the variance of the first principal component being given by $(1+r)$ and the second by $(1-r)$

+

Due to this, as $r$ increases, so does the variance explained in the first principal component. This in turn, lowers the variance explained in the second principal component.

+

Choosing a Number of Principal Components

+

Principal Component Analysis is typically used in dimensionality reduction efforts. Therefore, there are several strategies for picking the right number of principal components to keep. Here are a few:

+ +
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec5.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec5.html new file mode 100644 index 0000000..b6d9926 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec5.html @@ -0,0 +1,100 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Introduction to Connectivity Based Models

+

Hierarchical algorithms combine observations to form clusters based on their distance.

+

Connectivity Methods

+

Hierarchal Clustering techniques can be subdivided depending on the method of going about it.

+

First there are two different methods in forming the clusters Agglomerative and Divisive

+

Agglomerative is when you combine the n individuals into groups through each iteration

+

Divisive is when you are separating one giant group into finer groupings with each iteration.

+

Hierarchical methods are an irrevocable algorithm, once it joins or separates a grouping, it cannot be undone. As Kaufman and Rousseeuw (1990) colorfully comment: "A hierarchical method suffers from the defect that it can never repair what was done in previous steps".

+

It is the job of the statistician to decide when to stop the agglomerative or decisive algorithm, since having one giant cluster containing all observations or having each observation be a cluster isn't particularly useful.

+

At different distances, different clusters are formed and are more readily represented using a dendrogram. These algorithms do not provide a unique solution but rather provide an extensive hierarchy of clusters that merge or divide at different distances.

+

Linkage Criterion

+

Apart from the method of forming clusters, the user also needs to decide on a linkage criterion to use. Meaning, how do you want to optimize your clusters.

+

Do you want to group based on the nearest points in each cluster? Nearest Neighbor Clustering

+

Or do you want to based on the farthest observations in each cluster? Farthest neighbor clustering.

+

http://www.multid.se/genex/onlinehelp/clustering_distances.png

+

Shortcomings

+

This method is not very robust towards outliers, which will either show up as additional clusters or even cause other clusters to merge depending on the clustering method.

+

As we go through this section, we will go into detail about the different linkage criterion and other parameters of this model.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec6.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec6.html new file mode 100644 index 0000000..64dee8d --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec6.html @@ -0,0 +1,155 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Agglomerative Methods

+

Single Linkage

+

First let us consider the single linkage (nearest neighbor) approach. The clusters can be found through the following algorithm

+
    +
  1. Find the smallest non-zero distance
  2. +
  3. Group the two objects together as a cluster
  4. +
  5. Recompute the distances in the matrix by taking the minimum distances +
      +
    • Cluster a,b -> c = min(d(a, c), d(b, c))
    • +
  6. +
+

Single linkage can operate directly on a proximity matrix, the actual data is not required.

+

A wonderful visual representation can be found in Everitt Section 4.2

+

Centroid Clustering

+

This is another criterion measure that requires both the data and proximity matrix. These are the following steps of the algorithm. Requires Euclidean distance measure to preserve geometric correctness

+
    +
  1. Find the smallest non-zero distance
  2. +
  3. Group the two objects together as a cluster
  4. +
  5. Recompute the distances by taking the mean of the clustered observations and computing the distances between all of the observations +
      +
    • Cluster a,b -> c = d(mean(a, b), c)
    • +
  6. +
+

Complete Linkage

+

This is like Single Linkage, except now we're taking the farthest distance. The algorithm can be adjusted to the following

+
    +
  1. Find the smallest non-zero distance
  2. +
  3. Group the two objects together as a cluster
  4. +
  5. Recompute the distances in the matrix by taking the maximum distances +
      +
    • Cluster a,b -> c = max(d(a, c), d(b, c))
    • +
  6. +
+

Unweighted Pair-Group Method using the Average Approach (UPGMA)

+

In this criterion, we are no longer summarizing each cluster before taking distances, but instead comparing each observation in the cluster to the outside point and taking the average

+
    +
  1. Find the smallest non-zero distance
  2. +
  3. Group the two objects together as a cluster
  4. +
  5. Recompute the distances in the matrix by taking the mean +
      +
    • Cluster A: a,b -> c = $mean_{i = 0}(d(A_i, c))$
    • +
  6. +
+

Median Linkage

+

This approach is similar to the UPGMA approach, except now we're taking the median instead of the mean

+
    +
  1. Find the smallest non-zero distance
  2. +
  3. Group the two objects together as a cluster
  4. +
  5. Recompute the distances in the matrix by taking the median +
      +
    • Cluster A: a,b -> c = $median_{i = 0}{(d(A_i, c))}$
    • +
  6. +
+

Ward Linkage

+

This one I didn't look too far into but here's the description: With Ward's linkage method, the distance between two clusters is the sum of squared deviations from points to centroids. The objective of Ward's linkage is to minimize the within-cluster sum of squares.

+

When to use different Linkage Types?

+

According to the following two stack overflow posts: https://stats.stackexchange.com/questions/195446/choosing-the-right-linkage-method-for-hierarchical-clustering and https://stats.stackexchange.com/questions/195456/how-to-select-a-clustering-method-how-to-validate-a-cluster-solution-to-warran/195481#195481

+

These are the following ways you can justify a linkage type.

+

Cluster metaphor. "I preferred this method because it constitutes clusters such (or such a way) which meets with my concept of a cluster in my particular project."

+

Data/method assumptions. "I preferred this method because my data nature or format predispose to it."

+

Internal validity. "I preferred this method because it gave me most clear-cut, tight-and-isolated clusters."

+

External validity. "I preferred this method because it gave me clusters which differ by their background or clusters which match with the true ones I know."

+

Cross-validity. "I preferred this method because it is giving me very similar clusters on equivalent samples of the data or extrapolates well onto such samples."

+

Interpretation. "I preferred this method because it gave me clusters which, explained, are most persuasive that there is meaning in the world."

+

Cluster Metaphors

+

Let us explore the idea of cluster metaphors now.

+

Single Linkage or Nearest Neighbor is a spectrum or chain.

+

Since single linkage joins clusters by the shortest link between them, the technique cannot discern poorly separated clusters. On the other hand, single linkage is one of the few clustering methods that can delineate nonelipsodial clusters.

+

Complete Linkage or Farthest Neighbor is a circle.

+

Between-Group Average linkage (UPGMA) is a united *class

+

Centroid method (UPGMC) is proximity of platforms (commonly used in politics)

+

Dendrograms

+

A dendrogram is a tree diagram frequently used to illustrate the arrangement of the clusters produced by hierarchical clustering. It shows how different clusters are formed at different distance groupings.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec7.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec7.html new file mode 100644 index 0000000..8d8d686 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec7.html @@ -0,0 +1,149 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Divisive Methods Pt.1

+

Divisive methods work in the opposite direction of agglomerative methods. They take one large cluster and successively splits it.

+

This is computationally demanding if all $2^{k - 1} - 1$ possible divisions into two sub-clusters of a cluster of $k$ objects are considered at each stage.

+

While less common than Agglomerative methods, divisive methods have the advantage that most users are interested in the main structure in their data, and this is revealed from the outset of a divisive method.

+

Monothetic Divisive Methods

+

For data consisting of $p$ binary variables, there is a computationally efficient method known as monothetic divisive methods available.

+

Monothetic divisions divide clusters according to the presence or absence of each of the $p$ variables, so that at each stage, clusters contain members with certain attributes that are either all present or all absent.

+

The term 'monothetic' refers to the use of a single variable on which to base the split on. Polythetic methods use all the variables at each stage.

+

Choosing the Variable to Split On

+

The choice of the variable on which a split is made depends on optimizing a criterion reflecting either cluster homogeneity or association with other variables.

+

This tends to minimize the number of splits that have to be made.

+

An example of an homogeneity criterion is the information content $C$

+

This is defined with $p$ variables and $n$ objections where $fk$ is the number of individuals with the $k$ attribute +$$ +C = pn\log{n}-\sum{k = 1}^p{(f_k\log{f_k} - (n-f_k)\log{(n-f_k)})} +$$

+

Association with other variables

+

Recall that another way to split is based on the association with other variables. The attribute used at each step can be chosen according to its overall association with all attributes remaining at each step.

+

This is sometimes termed association analysis.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
V1V2
10
1ab
0cd
+

Common measures of association

+

$$ +|ad-bc| \tag{4.6} +$$

+

$$ +(ad-bc)^2 \tag{4.7} +$$

+

$$ +\frac{(ad-bc)^2n}{(a+b)(a+c)(b+d)(c+d)} \tag{4.8} +$$

+

$$ +\sqrt{\frac{(ad-bc)^2n}{(a+b)(a+c)(b+d)(c+d)}} \tag{4.9} +$$

+

$$ +\frac{(ad-bc)^2}{(a+b)(a+c)(b+d)(c+d)} \tag{4.10} +$$

+

$(4.6)$ and $(4.7)$ have the advantage that there is no danger of computational problems if any marginal totals are near zero.

+

The last three, $(4.8)$, $(4.9)$, $(4.10)$, are all related to the $\chi^2$ statistic, its square root, and the Pearson correlation coefficient respectively.

+

Advantages/Disadvantages of Monothetic Methods

+

Appealing features of monothetic divisive methods are the easy classification of new members and the including of cases with missing values.

+

A further advantage of monothetic divisive methods is that it is obvious which variables produce the split at any stage of the process.

+

A disadvantage with these methods is that the possession of a particular attribute which is either rare or rarely found in combination with others may take an individual down a different path.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec8.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec8.html new file mode 100644 index 0000000..67966b7 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec8.html @@ -0,0 +1,120 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Divisive Methods Pt 2.

+

Recall in the previous section that we spoke about Monothetic and Polythetic methods. Monothetic methods only looks at a single variable at a time while Polythetic looks at multiple variables simultaneously. In this section, we will speak more about polythetic divisive methods.

+

Polythetic Divisive Methods

+

Polythetic methods operate via a distance matrix.

+

This procedure avoids considering all possible splits by

+
    +
  1. Finding the object that is furthest away from the others within a group and using that as a seed for a splinter group.
  2. +
  3. Each object is then considered for entry to that separate splinter group: any that are closer to the splinter group than the main group is moved to the splinter one.
  4. +
  5. The step is then repeated.
  6. +
+

This process has been developed into a program named DIANA (DIvisive ANAlysis Clustering) which is implemented in R.

+

Similarities to Politics

+

This somewhat resembles a way a political party might split due to inner conflicts.

+

Firstly, the most discontented member leaves the party and starts a new one, and then some others follow him until a kind of equilibrium is attained.

+

Methods for Large Data Sets

+

There are two common hierarchical methods used for large data sets BIRCH and CURE. Both of these algorithms employ a pre-clustering phase in where dense regions are summarized, the summaries being then clustered using a hierarchical method based on centroids.

+

CURE

+
    +
  1. CURE starts with a random sample of points and represents clusters by a smaller number of points that capture the shape of the cluster
  2. +
  3. Which are then shrunk towards the centroid as to dampen the effect of the outliers
  4. +
  5. Hierarchical clustering then operates on the representative points
  6. +
+

CURE has been shown to be able to cope with arbitrary-shaped clusters and in that respect may be superior to BIRCH, although it does require judgment as to the number of clusters and also a parameter which favors either more or less compact clusters.

+

Revisiting Topics: Cluster Dissimilarity

+

In order to decide where clusters should be combined (for agglomerative), or where a cluster should be split (for divisive), a measure of dissimilarity between sets of observations is required.

+

In most methods of hierarchical clustering this is achieved by a use of an appropriate

+ +

Advantages of Hierarchical Clustering

+ +
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec9-1.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec9-1.html new file mode 100644 index 0000000..027b277 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec9-1.html @@ -0,0 +1,131 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

CURE and TSNE

+

Clustering Using Representatives (CURE)

+

Clustering using Representatives is a Hierarchical clustering technique in which you can represent a cluster using a set of well-scattered representative points.

+

This algorithm has a parameter $\alpha$ which defines the factor of the points in which to shrink towards the centroid.

+

CURE is known to be robust to outliers and able to identify clusters that have a non-spherical shape and size variance.

+

The clusters with the closest pair of representatives are the clusters that are merged at each step of CURE's algorithm.

+

This algorithm cannot be directly applied to large datasets due to high runtime complexity. Several enhancements were added to address this requirement

+ +

Youtube Video: https://www.youtube.com/watch?v=JrOJspZ1CUw

+

Steps

+
    +
  1. Pick a random sample of points that fit in main memory
  2. +
  3. Cluster sample points hierarchically to create the initial clusters
  4. +
  5. Pick representative points +
      +
    1. For each cluster, pick $k$ representative points, as dispersed as possible
    2. +
    3. Move each representative points to a fixed fraction $\alpha$ toward the centroid of the cluster
    4. +
  6. +
  7. Rescan the whole dataset and visit each point $p$ in the data set
  8. +
  9. Place it in the "closest cluster" +
      +
    1. Closest as in shortest distance among all the representative points.
    2. +
  10. +
+

TSNE

+

TSNE allows us to reduce the dimensionality of a dataset to two which allows us to visualize the data.

+

It is able to do this since many real-world datasets have a low intrinsic dimensionality embedded within the high-dimensional space.

+

Since the technique needs to conserve the structure of the data, two corresponding mapped points must be close to each other distance wise as well. Let $|x_i - x_j|$ be the Euclidean distance between two data points, and $|y_i - yj|$ he distance between the map points. This conditional similarity between two data points is: +$$ +p{j|i} = \frac{exp(-|x_i-x_j|^2 / (2\sigmai^2))}{\sum{k \ne i}{exp(-|x_i-x_k|^2/(2\sigma_i^2))}} +$$ +Where we are considering the Gaussian distribution surrounding the distance between $x_j$ from $x_i$ with a given variance $\sigma_i^2$. The variance is different for every point; it is chosen such that points in dense areas are given a smaller variance than points in sparse areas.

+

Now the similarity matrix for mapped points are +$$ +q_{ij} = \frac{f(|x_i - xj|)}{\sum{k \ne i}{f(|x_i - x_k)}} +$$ +Where $f(z) = \frac{1}{1 + z^2}$

+

This has the same idea as the conditional similarity between two data points, except this is based on the Cauchy distribution.

+

TSNE works at minimizing the Kullback-Leiber divergence between the two distributions $p{ij}$ and $q{ij}$ +$$ +KL(P || Q) = \sum{i,j}{p{i,j} \log{\frac{p{ij}}{q{ij}}}} +$$ +To minimize this score, gradient descent is typically performed +$$ +\frac{\partial KL(P||Q)}{\partial y_i} = 4\sumj{(p{ij} - q_{ij})} +$$

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec9-2.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec9-2.html new file mode 100644 index 0000000..cce6627 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes%2Flec9-2.html @@ -0,0 +1,133 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Cluster Validation

+

There are multiple approaches to validating your cluster models

+ +

Some Problems With These Evaluations

+

Internal evaluation measures suffer form the problem that they represent functions that are objectives for many clustering algorithms. So of course the result of the clustering algorithm will be such that the objective would be minimized.

+

External evaluation suffers from the fact that if we had labels to begin with then we wouldn't need to cluster. Practical applications of clustering occur usually when we don't have labels. On the other hand, possible labeling can reflect one possible partitioning of the data set. There could exist different, perhaps even better clustering.

+

Internal Evaluation

+

We like to see a few qualities in cluster models

+ +

Let us focus on the second and third bullet point for now. Internal evaluation measures are best suited to get some insight into situations where one algorithm performs better than another, this does not imply that one algorithm produces more valid results than another.

+

Davies-Bouldin Index

+

$$ +DB = \frac{1}{n}\sum{i=1}^n{max{j\ne i}{(\frac{\sigma_i + \sigma_j}{d(c_i,c_j)})}} +$$

+

Where $n$ is the number of clusters, $c$ indicates a centroid, and $\sigma$ represents the deviation from the centroid.

+

Better clustering algorithms are indicated by smaller DB values.

+

Dunn Index

+

$$ +D= \frac{min{1\le i < j \le n}{d(i,j)}}{max{1\le k \le n}{d^\prime(k)}} +$$

+

The Dunn index aims to identify dense and well-separated clusters. This is defined as the ratio between the minimal inter-cluster distance to maximal intra-cluster distance.

+

High Dunn Index values are more desirable.

+

Bootstrapping

+

In terms of robustness we can measure uncertainty in each of the individual clusters. This can be examined using a bootstrapping approach by Suzuki and Shimodaira (2006). The probability or "p-value" is the proportion of bootstrapped samples that contain the cluster. Larger p-values in this case indicate more support for the cluster.

+

This is available in R via Pvclust

+

Split-Sample Validation

+

One approach to assess the effects of perturbations of the data is by randomly dividing the data into two subsets and performing an analysis on each subset separately. This method was proposed by McIntyre and Blashfield in 1980; their method involves the following steps

+ +

Adjusted Index

+

Influence of Individual Points

+

Using internal evaluation metrics, you can see the impact of each point by doing a "leave one out" analysis. Here you evaluate the dataset minus one point for each of the points. If a positive difference is found, the point is regarded as a facilitator, whereas if it is negative then it is considered an inhibitor. once an influential inhibitor is found, the suggestion is to normally omit it from the clustering.

+

R Package

+

clValid contains a variety of internal validation measures.

+

Paper: https://cran.r-project.org/web/packages/clValid/vignettes/clValid.pdf

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes.html new file mode 100644 index 0000000..50b0ea8 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fnotes.html @@ -0,0 +1,103 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture Notes for Cluster Analysis

+

Lecture 1: Measures of Similarity

+

Lecture 2.1: Distance Measures Reasoning

+

Lecture 2.2: Principle Component Analysis Pt. 1

+

Lecture 3: Discussion of Dataset

+

Lecture 4: Principal Component Analysis Pt. 2

+

Lecture 4.2: Revisiting Measures

+

Lecture 4.3: Cluster Tendency

+

Lecture 5: Introduction to Connectivity Based Models

+

Lecture 6: Agglomerative Methods

+

Lecture 7: Divisive Methods Part 1: Monothetic

+

Lecture 8: Divisive Methods Part 2: Polythetic

+

Lecture 9.1: CURE and TSNE

+

Lecture 9.2: Cluster Validation Part I

+

Lecture 10.1: Silhouette Coefficient

+

Lecture 10.2: Centroid-Based Clustering

+

Lecture 10.3: Voronoi Diagrams

+

Lecture 11.1: K-means++

+

Lecture 11.2: K-medoids

+

Lecture 11.3: K-medians

+

Lecture 12: Introduction to Density Based Clustering

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Freadings.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Freadings.html new file mode 100644 index 0000000..43334a4 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Freadings.html @@ -0,0 +1,104 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Readings for Lectures of Cluster Analysis

+

Lecture 1

+

Garson Textbook Chapter 3

+

Lecture 2

+

A Tutorial on Principal Component Analysis

+

Lecture 3

+

No Readings

+

Lecture 4

+

An Introduction to Applied Multivariate Analysis with R by Brian Evveritt and Torsten Horthorn.

+

Sections 3.0-3.9 Everitt

+

Lecture 5

+

Section 4.1 Everitt

+

Lecture 6

+

Section 4.2 Everitt

+

Applied Multivariate Statistical Analysis Johnson Section 12.3

+

Linkage Methods for Cluster Observations

+

Lecture 7

+

Section 4.3 Everitt

+

Lecture 8

+

Introduction to the TSNE Algorithm

+

Lecture 9

+

Section 9.5 Everitt

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis%2Fsyllabus.html b/static/~brozek/index.html?research%2FClusterAnalysis%2Fsyllabus.html new file mode 100644 index 0000000..1e8efd9 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis%2Fsyllabus.html @@ -0,0 +1,193 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Cluster Analysis Spring 2018

+

Distance, Dimensionality Reduction, and Tendency

+ +

Validating Clustering Models

+ +

Connectivity Models

+ +

Cluster Evaluation

+ +

Centroid Models

+ +

Density Models

+ +

Analysis of Model Appropriateness

+ +

Distribution Models (If time permits)

+ +

Textbooks

+

Cluster Analysis 5th Edition

+ +

Cluster Analysis: 2014 Edition (Statistical Associates Blue Book Series 24)

+ +

Schedule

+

In an ideal world, the topics below I estimated being a certain time period for learning them. Of course you have more experience when it comes to how long it actually takes to learn these topics, so I'll leave this mostly to your discretion.

+

Distance, Dimensionality Reduction, and Tendency -- 3 Weeks

+

Validating Cluster Models -- 1 Week

+

Connectivity Models -- 2 Weeks

+

Cluster Evaluation -- 1 Week

+

Centroid Models -- 3 Weeks

+

Density Models -- 3 Weeks

+

Analysis of Model Appropriateness -- 1 Week

+

The schedule above accounts for 14 weeks, so there is a week that is free as a buffer.

+

Conclusion

+

Creating this document got me really excited for this independent study. Feel free to give me feedback :)

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FClusterAnalysis.html b/static/~brozek/index.html?research%2FClusterAnalysis.html new file mode 100644 index 0000000..ef43513 --- /dev/null +++ b/static/~brozek/index.html?research%2FClusterAnalysis.html @@ -0,0 +1,92 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Cluster Analysis

+

Cluster Analysis is the art of finding inherent structures in data to form groups of similar observations. This has a myriad of applications from recommendation engines to social network analysis.

+

This is an independent study, meaning that I will be studying this topic under the direction of a professor, in this case being Dr. Denhere.

+

I have provided a list of topics that I wish to explore in a syllabus

+

Dr. Denhere likes to approach independent studies from a theoretical and applied sense. Meaning, I will learn the theory of the different algorithms, and then figure out a way to apply them onto a dataset.

+

Readings

+

There is no definitive textbook for this course. Instead I and Dr. Denhere search for materials that we think best demonstrates the topic at hand.

+

I have created a Reading Page to keep track of the different reading materials.

+

Learning Notes

+

I like to type of the content I learn from different sources. A notes page is created to keep track of the content discussed each meeting.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fbandits.html b/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fbandits.html new file mode 100644 index 0000000..f1ba9d8 --- /dev/null +++ b/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fbandits.html @@ -0,0 +1,175 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Chapter 2: Multi-armed Bandits

+

Reinforcement learning evaluates the actions taken rather than accepting $instructions$ of the correct actions. This creates the need for active exploration.

+

This chapter of the book goes over a simplified version of the reinforcement learning problem, that does not involve learning to act in more than one situation. This is called a nonassociative setting.

+

In summation, the type of problem we are about to study is a nonassociative, evaluative feedback problem that is a simplified version of the $k$-armed bandit problem.

+

$K$-armed bandit problem

+

Consider the following learning problem. You are faced repeatedly with a choice among $k$ different options/actions. After each choice you receive a numerical reward chosen from a stationary probability distribution that depends on the action you selected.

+

Your objective (if you choose to accept it) is to maximize the expected total reward over some time period. Let's say $1000$ time steps.

+

Analogy

+

This is called the $k$-armed bandit problem because it's an analogy of a slot machine. Slot machines are nick-named the "one-armed bandit", and the goal here is to play the slot machine that has the greatest value return.

+

Sub-goal

+

We want to figure out which slot machine produces the greatest value. Therefore, we want to be able to estimate the value of a slot machine as close to the actual value as possible.

+

Exploration vs Exploitation

+

If we maintain estimates of the action values, then at any time step there is at least one action whose estimated value is the greatest. We call these greedy actions. When you select one of these actions we say that you are exploiting your current knowledge of the values of the actions.

+

If you instead select a non-greedy action, then you are exploring, because this enables you to better improve your estimate of the non-greedy action's value.

+

Uncertainty is such that at least one of the other actions probably better than the greedy action, you just don't know which one yet.

+

Action-value Methods

+

In this section, we will look at simple balancing methods in how to gain the greatest reward through exploration and exploitation.

+

We begin by looking more closely at some simple methods for estimating the values of actions and for using said estimates to make action selection decisions.

+

Sample-average method

+

One natural way to estimate this is by averaging the rewards actually received +$$ +Qt(a) = \frac{\sum{i = 1}^{t - 1}Ri * \mathbb{I}{Ai = 1}}{\sum{i = 1}^{t - 1}\mathbb{I}_{Ai = 1}} +$$ +where $\mathbb{I}{predicate}$ denotes the random variable that is 1 if the predicate is true and 0 if it is not. If the denominator is zero (we have not experienced the reward), then we assume some default value such as zero.

+

Greedy action selection

+

This is where you choose greedily all the time. +$$ +A_t = argmax_a(Q_t(a)) +$$

+

$\epsilon$-greedy action selection

+

This is where we choose greedily most of the time, except for a small probability $\epsilon$. Where instead of selecting greedily, we select randomly from among all the actions with equal probability.

+

Comparison of greedy and $\epsilon$-greedy methods

+

The advantage of $\epsilon$-greedy over greedy methods depends on the task. With noisier rewards it takes more exploration to find the optimal action, and $\epsilon$-greedy methods should fare better relative to the greedy method. However, if the reward variances were zero, then the greedy method would know the true value of each action after trying it once.

+

Suppose the bandit task were non-stationary, that is, the true values of actions changed over time. In this case exploration is needed to make sure one of the non-greedy actions has not changed to become better than the greedy one.

+

Incremental Implementation

+

There is a way to update averages using small constant computations rather than storing the the numerators and denominators separate.

+

Note the derivation for the update formula +$$ +\begin{align} +Q{n + 1} &= \frac{1}{n}\sum{i = 1}^n{R_i} \ +&= \frac{1}{n}(Rn + \sum{i = 1}^{n - 1}{R_i}) \ +&= \frac{1}{n}(Rn + (n - 1)\frac{1}{n-1}\sum{i = 1}^{n - 1}{R_i}) \ +&= \frac{1}{n}{R_n + (n - 1)Q_n} \ +&= \frac{1}{n}(R_n + nQ_n - Q_n) \ +&= Q_n + \frac{1}{n}(R_n - Q_n) \tag{2.3} +\end{align} +$$ +With formula 2.3, the implementation requires memory of only $Q_n$ and $n$.

+

This update rule is a form that occurs frequently throughout the book. The general form is +$$ +NewEstimate = OldEstimate + StepSize(Target - OldEstimate) +$$

+

Tracking a Nonstationary Problem

+

As noted earlier, we often encounter problems that are nonstationary, in such cases it makes sense to give more weight to recent rewards than to long-past rewards. One of the most popular ways to do this is to use a constant value for the $StepSize​$ parameter. We modify formula 2.3 to be +$$ +\begin{align} +Q_{n + 1} &= Q_n + \alpha(R_n - Q_n) \ +&= \alpha R_n + Q_n - \alpha Q_n \ +&= \alpha R_n + (1 - \alpha)Q_n \ +&= \alpha Rn + (1 - \alpha)(\alpha R{n - 1} + (1-\alpha)Q_{n - 1}) \ +&= \alpha Rn + (1 - \alpha)(\alpha R{n - 1} + (1-\alpha)(\alpha R{n - 2} + (1 - a)Q{n - 2})) \ +&= \alpha Rn + (1-\alpha)\alpha R{n - 1} + (1-\alpha)^2\alpha R_{n - 2} + \dots + (1-\alpha)^nQ_1 \ +&= (1-\alpha)^nQ1 + \sum{i = 1}^n{\alpha(1-\alpha)^{n - i}R_i} +\end{align} +$$ +This is a weighted average since the summation of all the weights equal one. Note here that the farther away a value is from the current time, the more times $(1-\alpha)$ gets multiplied by itself. Hence making it less influential. This is sometimes called an exponential recency-weighted average.

+

Manipulating $\alpha_n(a)$

+

Sometimes it is convenient to vary the step-size parameter from step to step. We can denote $\alpha_n(a)$ to be a function that determines the step-size parameter after the $n$th selection of action $a$. As noted before $\alpha_n(a) = \frac{1}{n}$ results in the sample average method which is guaranteed to converge to the truth action values assuming a large number of trials.

+

A well known result in stochastic approximation theory gives us the following conditions to assure convergence with probability 1: +$$ +\sum_{n = 1}^\infty{\alphan(a) = \infty} \and \sum{n = 1}^{\infty}{\alpha_n^2(a) \lt \infty} +$$ +The first condition is required to guarantee that the steps are large enough to overcome any initial conditions or random fluctuations. The second condition guarantees that eventually the steps become small enough to assure convergence.

+

Note: Both convergence conditions are met for the sample-average case but not for the constant step-size parameter. The latter condition is violated in the constant parameter case. This is desirable since if the rewards are changing then we don't want it to converge to any one parameter.

+

Optimistic Initial Values

+

The methods discussed so far are biased by their initial estimates. Another downside is that these values are another set of parameters that must be chosen by the user. Though these initial values can be used as a simple way to encourage exploration.

+

Let's say you set an initial estimate that is wildly optimistic. Whichever actions are initially selected, the reward is less than the starting estimates. Therefore, the learner switches to other actions, being disappointed with the rewards it was receiving.

+

The result of this is that all actions are tried several times before their values converge. It even does this if the algorithm is set to choose greedily most of the time!

+

1536284892566

+

This simple trick is quite effective for stationary problems. Not so much for nonstationary problems since the drive for exploration only happens at the beginning. If the task changes, creating a renewed need for exploration, this method would not catch it.

+

Upper-Confidence-Bound Action Selection

+

Exploration is needed because there is always uncertainty about the accuracy of the action-value estimates. The greedy actions are those that look best at the present but some other options may actually be better. Let's choose options that have potential for being optimal, taking into account how close their estimates are to being maximal and the uncertainties in those estimates. +$$ +A_t = argmax_a{(Q_t(a) + c\sqrt{\frac{ln(t)}{N_t(a)}})} +$$ +where $N_t(a)$ denotes the number of times that $a$ has been selected prior to time $t$ and $c > 0$ controls the degree of exploration.

+

Associative Search (Contextual Bandits)

+

So far, we've only considered nonassociative tasks, where there is no need to associate different actions with different situations. However, in a general reinforcement learning task there is more than one situation and the goal is to learn a policy: a mapping from situations to the actions that are best in those situations.

+

For sake of continuing our example, let us suppose that there are several different $k$-armed bandit tasks, and that on each step you confront one of these chosen at random. To you, this would appear as a single, nonstationry $k$-armed bandit task whose true action values change randomly from step to step. You could try using one of the previous methods, but unless the true action values change slowly, these methods will not work very well.

+

Now suppose, that when a bandit task is selected for you, you are given some clue about its identity. Now you can learn a policy association each task, singled by the clue, with the best action to take when facing that task.

+

This is an example of an associative search task, so called because it involves both trial-and-error learning to search for the best actions, and association of these actions with situations in which they are best. Nowadays they're called contextual bandits in literature.

+

If actions are allowed to affect the next situation as well as the reward, then we have the full reinforcement learning problem. This will be presented in the next chapter of the book with its ramifications appearing throughout the rest of the book.

+

1536321791927

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fdynamic.html b/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fdynamic.html new file mode 100644 index 0000000..410ae9a --- /dev/null +++ b/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fdynamic.html @@ -0,0 +1,169 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Chapter 4: Dynamic Programming

+

Dynamic programming refers to a collection of algorithms that can be used to compute optimal policies given a perfect model of the environment as a Markov decision process (MDP).

+

Classic DP algorithms are of limited utility due to their assumption of a perfect model and their great computational expense.

+

Let's assume that the environment is a finite MDP. We assume its state, action, and reward sets, $\mathcal{S}, \mathcal{A}, \mathcal{R}$ are finite, and that its dynamics are given by a set of probabilities $p(s^\prime, r | s , a)$.

+

The key idea of dynamic programming, and of reinforcement learning is the use of value functions to organize and structure the search for good policies. In this chapter, we show how dynamic programming can be used to compute the value functions defined in Chapter 3. We can easily obtain optimal policies once we have found the optimal value functions which satisfy the Bellman optimality equations.

+

Policy Evaluation

+

First we consider how to compute the state-value function for an arbitrary policy. The existence and uniqueness of a state-value function for an arbitrary policy are guaranteed as long as either the discount rate is less than one or eventual termination is guaranteed from all states under the given policy.

+

Consider a sequence of approximate value functions. The initial approximation, $v0$, is chosen arbitrarily (except that the terminal state must be given a value of zero) and each successive approximation is obtained by using the Bellman equation for $v\pi$ as an update rule: +$$ +v{k + 1} = \sum{a}{\pi(a |s)\sum_{s^\prime, r}{p(s^\prime,r|s,a)[r + \gamma v_k(s^\prime)]}} +$$ +This algorithm is called iterative policy evaluation.

+

To produce each successive approximation, $v_{k + 1}$ from $v_k$, iterative policy evaluation applies the same operation to each state $s$: it replaces the old value of $s$ with a new value obtained from the old values of the successor states of $s$, and the expected immediate rewards, along all the one-step transitions possible under the policy being evaluated.

+

Iterative Policy Evaluation

+
Input π, the policy to be evaluated
+Initialize an array V(s) = 0, for all s ∈ S+
+Repeat
+  ∆ ← 0
+  For each s ∈ S:
+    v ← V(s)
+    V(s) ← ∑_a π(a|s) ∑_s′,r p(s′,r|s,a)[r+γV(s′)]
+    ∆ ← max(∆,|v−V(s)|)
+until ∆ < θ (a small positive number)
+Output V ≈ v_π
+

Grid World Example

+

Consider a grid world where the top left and bottom right squares are the terminal state. Now consider that every other square, produces a reward of -1, and the available actions on each state is {up, down, left, right} as long as that action keeps the agent on the grid. Suppose our agent follows the equiprobable random policy.

+

![1540262811089](/home/rozek/Documents/Research/Reinforcement Learning/1540262811089.png)

+

Policy Improvement

+

One reason for computing the value function for a policy is to help find better policies. Suppose we have determined the value function $v\pi$ for an arbitrary deterministic policy $\pi$. For some state $s$ we would like to know whether or not we should change the policy to determinatically chose another action. We know how good it is to follow the current policy from $s$, that is $v\pi(s)$, but would it be better or worse to change to the new policy?

+

One way to answer this question is to consider selecting $a$ in $s$ and thereafter follow the existing policy, $\pi$. The key criterion is whether the this produces a value greater than or less than $v_\pi(s)$. If it is greater, then one would expect it to be better still to select $a$ every time $s$ is encountered, and that the new policy would in fact be a better one overall.

+

That this is true is a special case of a general result called the policy improvement theorem. Let $\pi$ and $\pi^\prime$ be any pair of deterministic policies such that for all $s \in \mathcal{S}$. +$$ +q\pi(s, \pi^\prime(s)) \ge v\pi(s) +$$ +So far we have seen how, given a policy and its value function, we can easily evaluate a change in the policy at a single state to a particular action. It is a natural extension to consider changes at all states and to all possible actions, selecting at each state the action that appears best according to $q\pi(s, a)$. In other words, to consider the new greedy policy, $\pi^\prime$, given by: +$$ +\pi^\prime = argmax (q\pi(s, a)) +$$ +So far in this section we have considered the case of deterministic policies. We will not go through the details, but in fact all the ideas of this section extend easily to stochastic policies.

+

Policy Iteration

+

Once a policy, $\pi$, has been improved using $v\pi$ to yield a better policy, $\pi^\prime$, we can then compute $v{\pi^\prime}$ and improve it again to yield an even better $\pi^{\prime\prime}$. We can thus obtain a sequence of monotonically improving policies and value functions.

+

Each policy is guaranteed to be a strict improvement over the previous one (unless its already optimal). Since a finite MDP has only a finite number of policies, this process must converge to an optimal policy and optimal value function in a finite number of iterations.

+

This way of finding an optimal policy is called policy iteration.

+

Algorithm

+
1.  Initialization
+  V(s) ∈ R and π(s) ∈ A(s) arbitrarily for all s ∈ S
+2.  Policy Evaluation
+  Repeat
+    ∆ ← 0
+    For each s∈S:
+      v ← V(s)
+      V(s) ← ∑_{s′,r} p(s′,r|s,π(s))[r + γV(s′)]
+      ∆ ← max(∆,|v − V(s)|)
+  until ∆ < θ (a small positive number)
+3.  Policy Improvement
+  policy-stable ← true
+  For each s ∈ S:
+    old-action ← π(s)
+    π(s) ← arg max_a ∑_{s′,r} p(s′,r|s,a)[r + γV(s′)]
+    If old-action != π(s), then policy-stable ← false
+  If policy-stable, then stop and return V ≈ v_∗,
+  and π ≈ π_∗; else go to 2
+

Value Iteration

+

One drawback to policy iteration is that each of its iterations involve policy evaluation, which may itself be a protracted iterative computation requiring multiple sweeps through the state set. If policy evaluation is done iteratively, then convergence exactly to $v_\pi$ occurs only in the limit. Must we wait for exact convergence, or can we stop short of that?

+

In fact, the policy evaluation step of policy iteration can be truncated in several ways without losing the convergence guarantee of policy iteration. One important special case is when policy evaluation is stopped after one sweep. This algorithm is called value iteration.

+

Another way of understanding value iteration is by reference to the Bellman optimality equation. Note that value iteration is obtained simply by turning the Bellman optimality equation into an update rule. Also note how value iteration is identical to the policy evaluation update except that it requires the maximum to be taken over all actions.

+

Finally, let us consider how value iteration terminates. Like policy evaluation, value iteration formally requires an infinite number of iterations to converge exactly. In practice, we stop once the value function changes by only a small amount.

+
Initialize array V arbitrarily (e.g., V(s) = 0 for all
+s ∈ S+)
+
+Repeat
+  ∆ ← 0
+  For each s ∈ S:
+    v ← V(s)
+    V(s) ← max_a∑_{s′,r} p(s′,r|s,a)[r + γV(s′)]
+    ∆ ← max(∆, |v − V(s)|)
+until ∆ < θ (a small positive number)
+
+Output a deterministic policy, π ≈ π_∗, such that
+  π(s) = arg max_a ∑_{s′,r} p(s′,r|s,a)[r + γV(s′)]
+

Value iteration effectively combines, in each of its sweeps, one sweep of policy evaluation and one sweep of policy improvement. Faster convergence is often achieved by interposing multiple policy evaluation sweeps between each policy improvement sweep.

+

Asynchronous Dynamic Programming

+

Asynchronous DP algorithms are in-place DP algorithms that are not organized in terms of systematic sweeps of the state set. These algorithms update the values of states in any order whatsoever, using whatever value of other states happen to be available.

+

To converge correctly, however, an asynchronous algorithm must continue to update the value of all the states: it can't ignore any state after some point in the computation.

+

Generalized Policy Iteration

+

Policy iteration consists of two simultaneous, iterating processes, one making the value function consistent with the current policy (policy evaluation) and the other making the policy greedy with respect to the current value function (policy improvement).

+

We use the term generalized policy iteration (GPI) to competing and cooperating. They compete in the sense that they pull in opposing directions. Making the policy greedy with respect to the value function typically makes the value function incorrect for the changed policy. Making the value function consistent with the policy typically causes the policy to be greedy. In the long run, however, the two processes interact to find a single joint solution.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fintro.html b/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fintro.html new file mode 100644 index 0000000..f3ca50b --- /dev/null +++ b/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fintro.html @@ -0,0 +1,104 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Introduction to Reinforcement Learning Day 1

+

Recall that this course is based on the book --

+

Reinforcement Learning: An Introduction by Richard S. Sutton and Andrew G. Barto

+

These notes really serve as talking points for the overall concepts described in the chapter and are not meant to stand for themselves. Check out the book for more complete thoughts :)

+

Reinforcement Learning is learning what to do -- how to map situations to actions -- so as to maximize a numerical reward signal. There are two characteristics, trial-and-error search and delayed reward, that are the two most important distinguishing features of reinforcement learning.

+

Markov decision processes are intended to include just these three aspects: sensation, action, and goal(s).

+

Reinforcement learning is different than the following categories

+ +

One of the challenges that arise in reinforcement learning is the trade-off between exploration and exploitation. The dilemma is that neither exploration nor exploitation can be pursued exclusively without failing at the task.

+

Another key feature of reinforcement learning is that it explicitly considers the whole problem of a goal-directed agent interacting with an uncertain environment. This is different than supervised learning since they're concerned with finding the best classifier/regression without explicitly specifying how such an ability would finally be useful.

+

A complete, interactive, goal-seeking agent can also be a component of a larger behaving system. A simple example is an agent that monitors the charge level of a robot's battery and sends commands to the robot's control architecture. This agent's environment is the rest of the robot together with the robot's environment.

+

Definitions

+

A policy defines the learning agent's way of behaving at a given time

+

A reward signal defines the goal in a reinforcement learning problem. The agent's sole objective is to maximize the total reward it receives over the long run

+

A value function specifies what is good in the long run. Roughly speaking, the value of a state is the total amount of reward an agent can expect to accumulate over the future, starting from that state. Without rewards there could be no value,s and the only purpose of estimating values is to achieve more reward. We seek actions that bring about states of highest value.

+

Unfortunately, it is much harder to determine values than it is to determine rewards. The most important component of almost all reinforcement learning algorithms we consider is a method for efficiently estimating values.

+

Look at Tic-Tac-Toe example

+

Most of the time in a reinforcement learning algorithm, we move greedily, selecting the move that leads to the state with greatest value. Occasionally, however, we select randomly from amoung the other moves instead. These are called exploratory moves because they cause us to experience states that we might otherwise never see.

+

Summary: Reinforcement learning is learning by an agent from direct interaction wit its environment, without relying on exemplary supervision or complete models of the environment.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fmcmethods.html b/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fmcmethods.html new file mode 100644 index 0000000..d007c2d --- /dev/null +++ b/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fmcmethods.html @@ -0,0 +1,146 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Chapter 5: Monte Carlo Methods

+

Monte Carlo methods do not assume complete knowledge of the environment. They require only experience which is a sample sequence of states, actions, and rewards from actual or simulated interaction with an environment.

+

Monte Carlo methods are ways of solving the reinforcement learning problem based on averaging sample returns. To ensure that well-defined returns are available, we define Monte Carlo methods only for episodic tasks. Only on the completion of an episode are value estimates and policies changed.

+

Monte Carlo methods sample and average returns for each state-action pair is much like the bandit methods explored earlier. The main difference is that there are now multiple states, each acting like a different bandit problems and the problems are interrelated. Due to all the action selections undergoing learning, the problem becomes nonstationary from the point of view of the earlier state.

+

Monte Carlo Prediction

+

Recall that the value of a state is the expected return -- expected cumulative future discounted reward - starting from that state. One way to do it is to estimate it from experience by averaging the returns observed after visits to that state.

+

Each occurrence of state $s$ in an episode is called a visit to $s$. The first-visit MC method estimates $v_\pi(s)$ as the average of the returns following first visits to $s$, whereas the every-visit MC method averages the returns following all visits to $s$. These two Monte Carlo methods are very similar but have slightly different theoretical properties.

+

First-visit MC prediction

+
Initialize:
+  π ← policy to be evaluated
+  V ← an arbitrary state-value function
+  Returns(s) ← an empty list, for all s ∈ S
+
+Repeat forever:
+  Generate an episode using π 
+  For each state s appearing in the episode:
+    G ← the return that follows the first occurrence of
+s
+    Append G to Returns(s)
+    V(s) ← average(Returns(s))
+

Monte Carlo Estimation of Action Values

+

If a model is not available then it is particularly useful to estimate action values rather than state values. With a model, state values alone are sufficient to define a policy. Without a model, however, state values alone are not sufficient. One must explicitly estimate the value of each action in order for the values to be useful in suggesting a policy.

+

The only complication is that many state-action pairs may never be visited. If $\pi$ is a deterministic policy, then in following $\pi$ one will observe returns only for one of the actions from each state. With no returns to average, the Monte Carlo estimates of the other actions will not improve with experience. This is a serious problem because the purpose of learning action values is to help in choosing among the actions available in each state.

+

This is the general problem of maintaining exploration. For policy evaluation to work for action values, we must assure continual exploration. One way to do this is by specifying that the episodes start in a state-action pair, and that each pair has a nonzero probability of being selected as the start. We call this the assumption of exploring starts.

+

Monte Carlo Control

+

We made two unlikely assumptions above in order to easily obtain this guarantee of convergence for the Monte Carlo method. One was that the episodes have exploring starts, and the other was that policy evaluation could be done with an infinite number of episodes.

+

Monte Carlo Exploring Starts

+
Initialize, for all s ∈ S, a ∈ A(s):
+  Q(s,a) ← arbitrary
+  π(s) ← arbitrary
+  Returns(s,a) ← empty list
+
+Repeat forever:
+  Choose S_0 ∈ S and A_0 ∈ A(S_0) s.t. all pairs have probability > 0
+  Generate an episode starting from S_0,A_0, following
+π
+  For each pair s,a appearing in the episode:
+    G ← the return that follows the first occurrence of
+s,a
+    Append G to Returns(s,a)
+    Q(s,a) ← average(Returns(s,a))
+  For each s in the episode:
+    π(s) ← arg max_a Q(s,a)
+

Monte Carlo Control without Exploring Starts

+

The only general way to ensure that actions are selected infinitely often is for the agent to continue to select them. There are two approaches ensuring this, resulting in what we call on-policy methods and off-policy methods.

+

On-policy methods attempt to evaluate or improve the policy that is used to make decisions, whereas off-policy methods evaluate or improve a policy different from that used to generate the data.

+

In on-policy control methods the policy is generally soft, meaning that $\pi(a|s)$ for all $a \in \mathcal{A}(s)$. The on-policy methods in this section uses $\epsilon$-greedy policies, meaning that most of the time they choose an action that has maximal estimated action value, but with probability $\epsilon$ they instead select an action at random.

+

On-policy first-visit MC control (for $\epsilon$-soft policies)

+
+

Initialize, for all $s \in \mathcal{S}$, $a \in \mathcal{A}(s)$:

+

$Q(s, a)$ ← arbitrary

+

$Returns(s,a)$ ← empty list

+

$\pi(a|s)$ ← an arbitrary $\epsilon$-soft policy

+

Repeat forever:

+

(a) Generate an episode using $\pi$

+

(b) For each pair $s,a$ appearing in the episoe

+

​ $G$ ← the return that follows the first occurance of s, a

+

​ Append $G$ to $Returns(s,a)$

+

​ $Q(s, a)$ ← average($Returns(s,a)$)

+

(c) For each $s$ in the episode:

+

​ $A^*$ ← argmax$_a Q(s,a)$ (with ties broken arbitrarily)

+

​ For all $a \in \mathcal{A}(s)$:

+

​ $\pi(a|s)$ ← $\begin{cases} 1 - \epsilon + \epsilon / |\mathcal{A}(s)| & a = A^ \ \epsilon / | \mathcal{A}(s)| & a \neq A^ \end{cases}$

+
+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fmdp.html b/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fmdp.html new file mode 100644 index 0000000..2745ac3 --- /dev/null +++ b/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes%2Fmdp.html @@ -0,0 +1,274 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Chapter 3: Finite Markov Decision Processes

+

Markov Decision processes are a classical formalization of sequential decision making, where actions influence not just immediate rewards, but also subsequent situations, or states, and through those future rewards. Thus MDPs involve delayed reward and the need to trade-off immediate and delayed reward. Whereas in bandit problems we estimated the value of $q*(a)$ of each action $a$, in MDPs we estimate the value of $q*(s, a)$ of each action $a$ in state $s$.

+

MDPs are a mathematically idealized form of the reinforcement learning problem. As we will see in artificial intelligence, there is often a tension between breadth of applicability and mathematical tractability. This chapter will introduce this tension and discuss some of the trade-offs and challenges that it implies.

+

Agent-Environment Interface

+

The learner and decision maker is called the agent. The thing it interacts with is called the environment. These interact continually, the agent selecting actions and the environment responding to these actions and presenting new situations to the agent.

+

The environment also give rise to rewards, special numerical values that the agent seeks to maximize over time through its choice of actions.

+

![1536511147205](/home/rozek/Documents/Research/Reinforcement Learning/1536511147205.png)

+

To make the future paragraphs clearer, a Markov Decision Process is a discrete time stochastic control process. It provides a mathematical framework for modeling decision making in situations where outcomes are partly random and partly under the control of the decision maker.

+

In a finite MDP, the set of states, actions, and rewards all have a finite number of elements. In this case, the random variables R_t and St have a well defined discrete probability distribution dependent only on the preceding state and action. +$$ +p(s^\prime | s,a) = \sum{r \in \mathcal{R}}{p(s^\prime, r|s, a)} +$$ +Breaking down the above formula, it's just an instantiation of the law of total probability. If you partition the probabilistic space by the reward, if you sum up each partition you should get the overall space. This formula has a special name: the state-transition probability.

+

From this we can compute the expected rewards for each state-action pair by multiplying each reward with the probability of getting said reward and summing it all up. +$$ +r(s, a) = \sum{r \in \mathcal{R}}{r}\sum{s^\prime \in \mathcal{S}}{p(s^\prime, r|s,a)} +$$ +The expected reward for a state-action-next-state triple is +$$ +r(s, a, s^\prime) = \sum_{r \in \mathcal{R}}{r\frac{p(s^\prime, r|s,a)}{p(s^\prime|s,a)}} +$$ +I wasn't able to piece together this function in my head like the others. Currently I imagine it as if we took the formula before and turned the universe of discourse from the universal set to the state where $s^\prime$ occurred.

+

The MDP framework is abstract and flexible and can be applied to many different problems in many different ways. For example, the time steps need not refer to fixed intervals of real time; they can refer to arbitrary successive states of decision making and acting.

+

Agent-Environment Boundary

+

In particular, the boundary between agent and environment is typically not the same as the physical boundary of a robot's or animals' body. Usually, the boundary is drawn closer to the agent than that. For example, the motors and mechanical linkages of a robot and its sensing hardware should usually be considered parts of the environment rather than parts of the agent.

+

The general rule we follow is that anything that cannot be changed arbitrarily by the agent is considered to be outside of it and thus part of its environment. We do not assume that everything in the environment is unknown to the agent. For example, the agent often knows quite a bit about how its rewards are computed as a function of its actions and the states in which they are taken. But we always consider the reward computation to be external to the agent because it defines the task facing the agent and thus must be beyond its ability to change arbitrarily. The agent-environment boundary represents the limit of the agent's absolute control, not of its knowledge.

+

This framework breaks down whatever the agent is trying to achieve to three signals passing back and forth between an agent and its environment: one signal to represent the choices made by the agent, one signal to represent the basis on which the choices are made (the states), and one signal to define the agent's goal (the rewards).

+

Example 3.4: Recycling Robot MDP

+

Recall that the agent makes a decision at times determined by external events. At each such time the robot decides whether it should

+

(1) Actively search for a can

+

(2) Remain stationary and wait for someone to bring it a can

+

(3) Go back to home base to recharge its battery

+

Suppose the environment works as follows: the best way to find cans is to actively search for them, but this runs down the robot's battery, whereas waiting does not. Whenever the robot is searching the possibility exists that its battery will become depleted. In this case, the robot must shut down and wait to be rescued (producing a low reward.)

+

The agent makes its decisions solely as a function of the energy level of the battery, It can distinguish two levels, high and low, so that the state set is $\mathcal{S} = {high, low}$. Let us call the possible decisions -- the agent's actions -- wait, search, and recharge. When the energy level is high, recharging would always be foolish, so we do not include it in the action set for this state. The agent's action sets are +$$ +\begin{align} +\mathcal{A}(high) &= {search, wait} \ +\mathcal{A}(low) &= {search, wait, recharge} +\end{align} +$$ +If the energy level is high, then a period of active search can always be completed without a risk of depleting the battery. A period of searching that begins with a high energy level leaves the energy level high with a probability of $\alpha$ and reduces it to low with a probability of $(1 - \alpha)$. On the other hand, a period of searching undertaken when the energy level is low leaves it low with a probability of $\beta$ and depletes the battery with a probability of $(1 - \beta)$. In the latter case, the robot must be rescued, and the batter is then recharged back to high.

+

Each can collected by the robot counts as a unit reward, whereas a reward of $-3$ occurs whenever the robot has to be rescued. Let $r{search}$ and $r{wait}$ with $r{search } > r{wait}$, respectively denote the expected number of cans the robot will collect while searching and waiting. Finally, to keep things simple, suppose that no cans can be collected ruing a run home for recharging and that no cans can be collected on a step in which the battery is depleted.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
$s$$a$$s^\prime$$p(s^\primes, a)$$r(s
highsearchhigh$\alpha$$r_{search}$
highsearchlow$(1-\alpha)$$r_{search}$
lowsearchhigh$(1 - \beta)$-3
lowsearchlow$\beta$$r_{search}$
highwaithigh1$r_{wait}$
highwaitlow0$r_{wait}$
lowwaithigh0$r_{wait}$
lowwaitlow1$r_{wait}$
lowrechargehigh10
lowrechargelow00
+

A transition graph is a useful way to summarize the dynamics of a finite MDP. There are two kinds of nodes: state nodes and action nodes. There is a state node for each possible state and an action node for reach state-action pair. Starting in state $s$ and taking action $a$ moves you along the line from state node $s$ to action node $(s, a)$. The the environment responds with a transition ot the next states node via one of the arrows leaving action node $(s, a)$.

+

![1537031348278](/home/rozek/Documents/Research/Reinforcement Learning/1537031348278.png)

+

Goals and Rewards

+

The reward hypothesis is that all of what we mean by goals and purposes can be well thought of as the maximization of the expected value of the cumulative sum of a received scalar signal called the reward.

+

Although formulating goals in terms of reward signals might at first appear limiting, in practice it has proved to be flexible and widely applicable. The best way to see this is to consider the examples of how it has been, or could be used. For example:

+ +

It is critical that the rewards we set up truly indicate what we want accomplished. In particular, the reward signal is not the place to impart to the agent prior knowledge about how to achieve what we want it to do. For example, a chess playing agent should only be rewarded for actually winning, not for achieving subgoals such as taking its opponent's pieces. If achieving these sort of subgoals were rewarded, then the agent might find a way to achieve them without achieving the real goal. The reward signal is your way of communicating what you want it to achieve, not how you want it achieved.

+

Returns and Episodes

+

In general, we seek to maximize the expected return, where the return is defined as some specific function of the reward sequence. In the simplest case, the return is the sum of the rewards: +$$ +Gt = R{t + 1} + R{t + 2} + R{t + 3} + \dots + R_{T} +$$ +where $T$ is the final time step. This approach makes sense in applications in which there is a natural notion of a final time step. That is when the agent-environment interaction breaks naturally into subsequences or episodes, such as plays of a game, trips through a maze, or any sort of repeated interaction.

+

Episodic Tasks

+

Each episode ends in a special state called the terminal state, followed by a reset to the standard starting state or to a sample from a standard distribution of starting states. Even if you think of episodes as ending in different ways the next episode begins independently of how the previous one ended. Therefore, the episodes can all be considered to ending the same terminal states with different rewards for different outcomes.

+

Tasks with episodes of this kind are called episodic tasks. In episodic tasks we sometimes need to distinguish the set of all nonterminal states, denoted $\mathcal{S}$, from the set of all states plus the terminal state, denoted $\mathcal{S}^+$. The time of termination, $T$, is a random variable that normally varies from episode to episode.

+

Continuing Tasks

+

On the other hand, in many cases the agent-environment interaction goes on continually without limit. We call these continuing tasks. The return formulation above is problematic for continuing tasks because the final time step would be $T = \infty$, and the return which we are trying to maximize, could itself easily be infinite. The additional concept that we need is that of discounting. According to this approach, the agent tries to select actions so that the sum of the discounted rewards it receives over the future is maximized. In particular, it chooses $A_t$ to maximize the expected discounted return. +$$ +Gt= \sum{k = 0}^\infty{\gamma^kR_{t+k+1}} +$$ +where $\gamma$ that is a parameter between $0$ and $1$ is called the discount rate.

+

Discount Rate

+

The discount rate determines the present value of future rewards: a reward received $k$ time steps in the future is worth only $\gamma^{k - 1}$ time what it would be worth if it were received immediately. If $\gamma < 1$, the infinite sum has a finite value as long as the reward sequence is bounded.

+

If $\gamma = 0$, the agent is "myopic" in being concerned only with maximizing immediate rewards. But in general, acting to maximize immediate reward can reduce access to future rewards so that the return is reduced.

+

As $\gamma$ approaches 1, the return objective takes future rewards into account more strongly; the agent becomes more farsighted.

+

Example 3.5 Pole-Balancing

+

The objective in this task is to apply forces to a car moving along a track so as to keep a pole hinged to the cart from falling over.

+

A failure is said to occur if the pole falls past a given angle from the vertical or if the cart runs off the track.

+

![1537500975060](/home/rozek/Documents/Research/Reinforcement Learning/1537500975060.png)

+

Approach 1

+

The reward can be a $+1$ for every time step on which failure did not occur. In this case, successful balancing would mean a return of infinity.

+

Approach 2

+

The reward can be $-1$ on each failure and zero all other times. The return at each time would then be related to $-\gamma^k$ where $k$ is the number of steps before failure.

+

Either case the return is maximized by keeping the pole balanced for as long as possible.

+

Policies and Value Functions

+

Almost all reinforcement learning algorithms involve estimating value functions which estimate what future rewards can be expected. Of course the rewards that the agent can expect to receive is dependent on the actions it will take. Accordingly, value functions are defined with respect to particular ways of acting, called policies.

+

Formally, a policy is a mapping from states to probabilities of selecting each possible action. The value of a state s under a policy \pi, denoted $v{\pi}(s)$ is the expected return when starting in $s$ and following $\pi$ thereafter. For MDPs we can define $v{\pi}$ as

+

$$ +v{\pi}(s) = \mathbb{E}{\pi}[G_t | St = s] = \mathbb{E}{\pi}[\sum{k = 0}^\infty{\gamma^kR{t+k+1} | S_t = s}] +$$

+

We call this function the state-value function for policy $\pi$. Similarly, we define the value of taking action $a$ in state $s$ under a policy $\pi$, denoted as $q_\pi(s,a)$ as the expected return starting from $s$, taking the action $a$, and thereafter following the policy $\pi$. Succinctly, this is called the action-value function for policy $\pi$.

+

Optimality and Approximation

+

For some kinds of tasks we are interested in,optimal policies can be generated only with extreme computational cost. A critical aspect of the problemfacing the agent is always teh computational power available to it, in particular, the amount of computation it can perform in a single time step.

+

The memory available is also an important constraint. A large amount of memory is often required to build up approximations of value functions, policies, and models. In the case of large state sets, functions must be approximated using some sort of more compact parameterized function representation.

+

This presents us with unique oppurtunities for achieving useful approximations. For example, in approximating optimal behavior, there may be many states that the agent faces with such a low probability that selecting suboptimal actions for them has little impact on the amount of reward the agent receives.

+

The online nature of reinforcement learning which makes it possible to approximate optimal policies in ways that put more effort into learning to make good decisions for frequently encountered states at the expense of infrequent ones is the key property that distinguishes reinforcement learning from other approaches to approximately solve MDPs.

+

Summary

+

Let us summarize the elements of the reinforcement learning problem.

+

Reinforcement learning is about learning from interaction how to behave in order to achieve a goal. The reinforcement learning agent and its environment interact over a sequence of discrete time steps.

+

The actions are the choices made by the agent; the states are the basis for making the choice; and the rewards are the basis for evaluating the choices.

+

Everything inside the agent is completely known and controllable by the agent; everything outside is incompletely controllable but may or may not be completely known.

+

A policy is a stochastic rule by which the agent selects actions as a function of states.

+

When the reinforcement learning setup described above is formulated with well defined transition probabilities it constitutes a Markov Decision Process (MDP)

+

The return is the function of future rewards that the agent seeks to maximize. It has several different definitions depending on the nature of the task and whether one wishes to discount delayed reward.

+ +

A policy's value functions assign to each state, or state-action pair, the expected return from that state, or state-action pair, given that the agent uses the policy. The optimal value functions assign to each state, or state-action pair, the largest expected return achievable by any policy. A policy whose value unctions are optimal is an optimal policy.

+

Even if the agent has a complete and accurate environment model, the agent is typically unable to perform enough computation per time step to fully use it. The memory available is also an important constraint. Memory may be required to build up accurate approximations of value functions, policies, and models. In most cases of practical interest there are far more states that could possibly be entries in a table, and approximations must be made.

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes.html b/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes.html new file mode 100644 index 0000000..2d57431 --- /dev/null +++ b/static/~brozek/index.html?research%2FReinforcementLearning%2Fnotes.html @@ -0,0 +1,88 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Lecture Notes for Reinforcement Learning

+

Chapter 1: An Introduction

+

Chapter 2: Multi-armed Bandits

+

Chapter 3: Markov Decision Processes

+

Chapter 4: Dynamic Programming

+

Chapter 5: Monte Carlo Methods

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FReinforcementLearning%2Freadings.html b/static/~brozek/index.html?research%2FReinforcementLearning%2Freadings.html new file mode 100644 index 0000000..f5f595c --- /dev/null +++ b/static/~brozek/index.html?research%2FReinforcementLearning%2Freadings.html @@ -0,0 +1,94 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Readings for Lectures of Cluster Analysis

+

Lecture 1

+

Chapter 1: What is Reinforcement Learning?

+

Lecture 2

+

Chapter 2: Multi-armed Bandits

+

Lecture 3

+

Chpater 3: Finite Markov Decision Processes Part 1

+

Lecture 4

+

Chapter 3: Finite Markov Decision Processes Part 2

+

Lecture 5

+

[No Readings] Playing around with Multi-armed Bandits Code

+

Lost track of readings around this time period :(

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FReinforcementLearning%2Fsyllabus.html b/static/~brozek/index.html?research%2FReinforcementLearning%2Fsyllabus.html new file mode 100644 index 0000000..bbf11ee --- /dev/null +++ b/static/~brozek/index.html?research%2FReinforcementLearning%2Fsyllabus.html @@ -0,0 +1,144 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Reinforcement Learning

+

The goal of this independent study is to gain an introduction to the topic of Reinforcement Learning.

+

As such the majority of the semester will be following the textbook to gain an introduction to the topic, and the last part applying it to some problems.

+

Textbook

+

The majority of the content of this independent study will come from the textbook. This is meant to lessen the burden on the both us of as I already experimented with curating my own content.

+

The textbook also includes examples throughout the text to immediately apply what's learned.

+

Richard S. Sutton and Andrew G. Barto, "Reinforcement Learning: An Introduction" http://incompleteideas.net/book/bookdraft2017nov5.pdf

+

Discussions and Notes

+

Discussions and notes will be kept track of and published on my tilda space as time and energy permits. This is for easy reference and since it's nice to write down what you learn.

+

Topics to be Discussed

+

The Reinforcement Learning Problem (3 Sessions)

+

In this section we will get ourselves familiar with the topics that are commonly discussed in Reinforcement learning problems.

+

In this section we will learn the different vocab terms such as:

+ +

Markov Decision Processes (4 Sessions)

+

This is a type of reinforcement learning problem that is commonly studied and well documented. This helps form an environment for which the agent can operate within. Possible subtopics include:

+ +

Dynamic Programming (3 Sessions)

+

Dynamic Programming refers to a collection of algorithms that can be used to compute optimal policies given an environment. Subtopics that we are going over is:

+ +

Monte Carlo Methods (3 Sessions)

+

Now we move onto not having complete knowledge of the environment. This will go into estimating value functions and discovering optimal policies. Possible subtopics include:

+ +

Temporal-Difference Learning (4-5 Sessions)

+

Temporal-Difference learning is a combination of Monte Carlo ideas and Dynamic Programming. This can lead to methods learning directly from raw experience without knowledge of an environment. Subtopics will include:

+ +
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research%2FReinforcementLearning.html b/static/~brozek/index.html?research%2FReinforcementLearning.html new file mode 100644 index 0000000..8d831bd --- /dev/null +++ b/static/~brozek/index.html?research%2FReinforcementLearning.html @@ -0,0 +1,101 @@ + + + + + + + + Brandon Rozek + + + + + + +
+
+

Reinforcement Learning

+

Reinforcement learning is the art of analyzing situations and mapping them to actions in order to maximize a numerical reward signal.

+

In this independent study, I as well as Dr. Stephen Davies, will explore the Reinforcement Learning problem and its subproblems. We will go over the bandit problem, markov decision processes, and discover how best to translate a problem in order to make decisions.

+

I have provided a list of topics that I wish to explore in a syllabus

+

Readings

+

In order to spend more time learning, I decided to follow a textbook this time.

+

Reinforcement Learning: An Introduction

+

By Richard S. Sutton and Andrew G. Barto

+

Reading Schedule

+

Notes

+

The notes for this course, is going to be an extreemly summarized version of the textbook. There will also be notes on whatever side tangents Dr. Davies and I explore.

+

Notes page

+

I wrote a small little quirky/funny report describing the bandit problem. Great for learning about the common considerations for Reinforcement Learning problems.

+

The Bandit Report

+

Code

+

Code will occasionally be written to solidify the learning material and to act as aids for more exploration.

+

Github Link

+

Specifically, if you want to see agents I've created to solve some OpenAI environments, take a look at this specific folder in the Github Repository

+

Github Link

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?research.html b/static/~brozek/index.html?research.html new file mode 100644 index 0000000..f31dbdc --- /dev/null +++ b/static/~brozek/index.html?research.html @@ -0,0 +1,110 @@ + + + + + + + + + Research | Brandon Rozek + + + + + + +
+
+

Research

+

Computer Science / Data Science Research

+

Reinforcement Learning

+

Deep Reinforcement Learning: With Dr. Zacharski I focused more on a particular instance of Reinforcement Learning where deep neural networks are used. During this time, I built out a Reinforcement Learning library written in PyTorch. This library helps me have a test bed for trying out different algorithms and attempts to create my own.

+

Github Code

+

QEP Algorithm Slides

+

Reinforcement Learning: Currently studying the fundamentals of reinforcement learning with Dr. Davies. We went over the fundamentals such as value functions, policy functions, how we can describe our environment as a markov decision processes, etc.

+

Notes and Other Goodies

+

Github Code

+

Programming Languages

+

Programming Languages: Studying the design of programming languages. So far I made an implementation of the SLOTH programming language, experimenting with what I want my own programming language to be syntatically and paradigm wise.

+

SLOTH Code

+

Before this study, I worked though a book called "Build your own Lisp" and my implementation of a lisp like language is below.

+

Lispy Code

+

Other

+

Competitive Programming: Studying algorithms and data structures necessary for competitive programming. Attending ACM ICPC in November with a team of two other students.

+

Math/Statistics Research

+

Worked on an independent study on the topic of Cluster Analysis. This is where you try to group similar observations without knowing what the labels are. +I am studying under the guidance of Dr. Melody Denhere, the link below gives you more of a description of the project along with my course notes.

+

Cluster Analysis Spring 2018

+

Physics Research

+

For the two projects below, I worked on Quantum Research in a physics lab with a fellow student Hannah Killian and an advisor Dr. Hai Nguyen. I mostly assisted with the software support for the project and assisted in the mathematics in whatever way I can.

+

Modeling Population Dynamics of Incoherent and Coherent Excitation

+

Coherent Control of Atomic Population Using the Genetic Algorithm

+

In order to circumvent the frustrations I had with simulation code taking a while, I applied and received funding to build out a Beowulf cluster for the Physics department. Dr. Maia Magrakvilidze was the advisor for this project.

+

High Performance Cluster for Research and Education Report (nicknamed LUNA-C)

+

LUNA-C Poster

+
+
+ + + + + + + + + + diff --git a/static/~brozek/index.html?transcript.html b/static/~brozek/index.html?transcript.html new file mode 100644 index 0000000..4b01b3e --- /dev/null +++ b/static/~brozek/index.html?transcript.html @@ -0,0 +1,146 @@ + + + + + + + + + Transcript | Brandon Rozek + + + + + + +
+
+

Transcript

+

Below is a list of courses I've taken in the past for credit.

+

Spring 2019

+

Deep Reinforcement Learning (CPSC 491)

+

Real Analysis I (MATH 471)

+

Abstract Algebra I (MATH 431)

+

Operating Systems (CPSC 405)

+

Digital Storytelling (CPSC 106)

+

Fall 2018

+

Reinforcement Learning (CPSC 491)

+

Programming Languages (CPSC 491)

+

Competitive Programming (CPSC 491)

+

Multivariate Statistics (STAT 461)

+

Foundations of Advance Mathematics (MATH 330)

+

Applications of Databases (CPSC 350)

+

Spring 2018

+

Foundations for Data Science (Data 219)

+

Theory of Computation (CPSC 326)

+

Data Structures and Algorithms (CPSC 340)

+

Differential Equations (MATH 312)

+

Cluster Analysis (STAT 491)

+

Fall 2017

+

Computer Systems and Architecture (CPSC 305)

+

Introduction to Data Science (DATA 101)

+

Linear Algebra (MATH 300)

+

Methods in Mathematical Physics (PHYS 317)

+

Probability & Statistical Inference I (STAT 381)

+

Undergraduate Research in Physics (URES 197J)

+

Fall 2017

+

Computer Systems and Architecture (CPSC 305)

+

Introduction to Data Science (DATA 101)

+

Linear Algebra (MATH 300)

+

Methods in Mathematical Physics (PHYS 317)

+

Probability & Statistical Inference I (STAT 381)

+

Undergraduate Research in Physics (URES 197J)

+

Fall 2017

+

Computer Systems and Architecture (CPSC 305)

+

Introduction to Data Science (DATA 101)

+

Linear Algebra (MATH 300)

+

Methods in Mathematical Physics (PHYS 317)

+

Probability & Statistical Inference I (STAT 381)

+

Undergraduate Research in Physics (URES 197J)

+

Spring 2017

+

Intro to Discrete Mathematics (CPSC 125A)

+

Object-Oriented Analysis & Design (CPSC 240)

+

Statistical Methods (MATH 280)

+

University Physics II, with Lab (PHYS 106)

+

Undergraduate Research in Physics (URES 197J)

+

Fall 2016

+

Software Development Tools (CPSC 225)

+

Numbers Rule Your World (FSEM 100M1)

+

Intro to Statistics (MATH 200)

+

American Music (MUHL 156)

+

University Physics I, with Lab (PHYS 105)

+

Advance Placement

+

Computer Programming and Problem Solving (CPSC 220)

+

Intro to Human Geography (GEOG 102)

+

American History to 1865 (HIST 131)

+

American History since 1865 (HIST 132)

+

Calculus I (MATH 121)

+

Calculus II (MATH 122)

+

Calculus III (MATH 223)

+

General Psychology (PSYCH 100)

+
+
+ + + + + + + + + + diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-It.eot b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-It.eot new file mode 100644 index 0000000..bb3a732 Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-It.eot differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-It.eot? b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-It.eot? new file mode 100644 index 0000000..bb3a732 Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-It.eot? differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-It.otf.woff b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-It.otf.woff new file mode 100644 index 0000000..9cae9b4 Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-It.otf.woff differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-It.ttf b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-It.ttf new file mode 100644 index 0000000..c689cd2 Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-It.ttf differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Regular.eot b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Regular.eot new file mode 100644 index 0000000..1c20988 Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Regular.eot differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Regular.eot? b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Regular.eot? new file mode 100644 index 0000000..1c20988 Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Regular.eot? differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Regular.otf.woff b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Regular.otf.woff new file mode 100644 index 0000000..6bc912b Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Regular.otf.woff differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Regular.ttf b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Regular.ttf new file mode 100644 index 0000000..a011dff Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Regular.ttf differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Semibold.eot b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Semibold.eot new file mode 100644 index 0000000..7f7cd0e Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Semibold.eot differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Semibold.eot? b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Semibold.eot? new file mode 100644 index 0000000..7f7cd0e Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Semibold.eot? differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Semibold.otf.woff b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Semibold.otf.woff new file mode 100644 index 0000000..475c499 Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Semibold.otf.woff differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Semibold.ttf b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Semibold.ttf new file mode 100644 index 0000000..dbf946a Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-Semibold.ttf differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-SemiboldIt.eot b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-SemiboldIt.eot new file mode 100644 index 0000000..c7efea1 Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-SemiboldIt.eot differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-SemiboldIt.eot? b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-SemiboldIt.eot? new file mode 100644 index 0000000..c7efea1 Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-SemiboldIt.eot? differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-SemiboldIt.otf.woff b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-SemiboldIt.otf.woff new file mode 100644 index 0000000..62c2997 Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-SemiboldIt.otf.woff differ diff --git a/static/~brozek/themes/bitsandpieces/font/SourceSansPro-SemiboldIt.ttf b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-SemiboldIt.ttf new file mode 100644 index 0000000..d1bc7f0 Binary files /dev/null and b/static/~brozek/themes/bitsandpieces/font/SourceSansPro-SemiboldIt.ttf differ diff --git a/static/~brozek/themes/bitsandpieces/scripts/highlight.js b/static/~brozek/themes/bitsandpieces/scripts/highlight.js new file mode 100644 index 0000000..022f9d9 --- /dev/null +++ b/static/~brozek/themes/bitsandpieces/scripts/highlight.js @@ -0,0 +1 @@ +!function(e){"undefined"!=typeof exports?e(exports):(window.hljs=e({}),"function"==typeof define&&define.amd&&define("hljs",[],function(){return window.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&").replace(//gm,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){return/^(no-?highlight|plain|text)$/i.test(e)}function i(e){var n,t,r,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=/\blang(?:uage)?-([\w-]+)\b/i.exec(i))return w(t[1])?t[1]:"no-highlight";for(i=i.split(/\s+/),n=0,r=i.length;r>n;n++)if(w(i[n])||a(i[n]))return i[n]}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset"}function u(e){l+=""}function c(e){("start"==e.event?o:u)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g==e&&g.length&&g[0].offset==s);f.reverse().forEach(o)}else"start"==g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):Object.keys(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\b\w+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function l(e,t,a,i){function o(e,n){for(var t=0;t";return i+=e+'">',i+n+o}function p(){if(!L.k)return n(M);var e="",t=0;L.lR.lastIndex=0;for(var r=L.lR.exec(M);r;){e+=n(M.substr(t,r.index-t));var a=g(L,r);a?(B+=a[1],e+=h(a[0],n(r[0]))):e+=n(r[0]),t=L.lR.lastIndex,r=L.lR.exec(M)}return e+n(M.substr(t))}function d(){var e="string"==typeof L.sL;if(e&&!x[L.sL])return n(M);var t=e?l(L.sL,M,!0,y[L.sL]):f(M,L.sL.length?L.sL:void 0);return L.r>0&&(B+=t.r),e&&(y[L.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){return void 0!==L.sL?d():p()}function v(e,t){var r=e.cN?h(e.cN,"",!0):"";e.rB?(k+=r,M=""):e.eB?(k+=n(t)+r,M=""):(k+=r,M=t),L=Object.create(e,{parent:{value:L}})}function m(e,t){if(M+=e,void 0===t)return k+=b(),0;var r=o(t,L);if(r)return k+=b(),v(r,t),r.rB?0:t.length;var a=u(L,t);if(a){var i=L;i.rE||i.eE||(M+=t),k+=b();do L.cN&&(k+=""),B+=L.r,L=L.parent;while(L!=a.parent);return i.eE&&(k+=n(t)),M="",a.starts&&v(a.starts,""),i.rE?0:t.length}if(c(t,L))throw new Error('Illegal lexeme "'+t+'" for mode "'+(L.cN||"")+'"');return M+=t,t.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,L=i||N,y={},k="";for(R=L;R!=N;R=R.parent)R.cN&&(k=h(R.cN,"",!0)+k);var M="",B=0;try{for(var C,j,I=0;;){if(L.t.lastIndex=I,C=L.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}for(m(t.substr(I)),R=L;R.parent;R=R.parent)R.cN&&(k+="");return{r:B,value:k,language:e,top:L}}catch(O){if(-1!=O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function f(e,t){t=t||E.languages||Object.keys(x);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(w(n)){var t=l(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function g(e){return E.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,E.tabReplace)})),E.useBR&&(e=e.replace(/\n/g,"
")),e}function h(e,n,t){var r=n?R[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function p(e){var n=i(e);if(!a(n)){var t;E.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):t=e;var r=t.textContent,o=n?l(n,r,!0):f(r),s=u(t);if(s.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=o.value,o.value=c(s,u(p),r)}o.value=g(o.value),e.innerHTML=o.value,e.className=h(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){E=o(E,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=x[n]=t(e);r.aliases&&r.aliases.forEach(function(e){R[e]=n})}function N(){return Object.keys(x)}function w(e){return e=(e||"").toLowerCase(),x[e]||x[R[e]]}var E={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},x={},R={};return e.highlight=l,e.highlightAuto=f,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e});hljs.registerLanguage("nginx",function(e){var r={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},b={eW:!0,l:"[a-z/_]+",k:{built_in:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,r],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{cN:"url",b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[r]},{cN:"regexp",c:[e.BE,r],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},r]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"title",b:e.UIR,starts:b}],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("cs",function(e){var r="abstract as base bool break byte case catch char checked const continue decimal dynamic default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long null when object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async protected public private internal ascending descending from get group into join let orderby partial select set value var where yield",t=e.IR+"(<"+e.IR+">)?";return{aliases:["csharp"],k:r,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"xmlDocTag",v:[{b:"///",r:0},{b:""},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line region endregion pragma checksum"},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},e.ASM,e.QSM,e.CNM,{bK:"class interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[{cN:"title",b:"[a-zA-Z](\\.?\\w)*",r:0},e.CLCM,e.CBCM]},{bK:"new return throw await",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"chunk",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"header",v:[{b:/Index: /,e:/$/},{b:/=====/,e:/=====$/},{b:/^\-\-\-/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+\+\+/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,e.NM,s,a,t]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"header",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{cN:"horizontal_rule",b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"link_label",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link_url",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"link_reference",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:"^\\[.+\\]:",rB:!0,c:[{cN:"link_reference",b:"\\[",e:"\\]:",eB:!0,eE:!0,starts:{cN:"link_url",e:"$"}}]}]}});hljs.registerLanguage("javascript",function(e){return{aliases:["js"],k:{keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},c:[{cN:"pi",r:10,b:/^\s*['"]use (strict|asm)['"]/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b:/\s*[);\]]/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[e.CLCM,e.CBCM]}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{bK:"import",e:"[;$]",k:"import from as",c:[e.ASM,e.QSM]},{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]}],i:/#/}});hljs.registerLanguage("ini",function(e){var c={cN:"string",c:[e.BE],v:[{b:"'''",e:"'''",r:10},{b:'"""',e:'"""',r:10},{b:'"',e:'"'},{b:"'",e:"'"}]};return{aliases:["toml"],cI:!0,i:/\S/,c:[e.C(";","$"),e.HCM,{cN:"title",b:/^\s*\[+/,e:/\]+/},{cN:"setting",b:/^[a-z0-9\[\]_-]+\s*=\s*/,e:"$",c:[{cN:"value",eW:!0,k:"on off true false yes no",c:[{cN:"variable",v:[{b:/\$[\w\d"][\w\d_]*/},{b:/\$\{(.*?)}/}]},c,{cN:"number",b:/([\+\-]+)?[\d]+_[\d_]+/},e.NM],r:0}]}]}});hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"tag",b:""},{cN:"keyword",b:/\w+/,r:0,k:{common:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"sqbracket",b:"\\s\\[",e:"\\]$"},{cN:"cbracket",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}});hljs.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*]/,c:[{cN:"operator",bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke",e:/;/,eW:!0,k:{keyword:"abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes c cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle d data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration e each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract f failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function g general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http i id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists k keep keep_duplicates key keys kill l language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim m main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex n name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding p package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime t table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}});hljs.registerLanguage("twig",function(e){var t={cN:"params",b:"\\(",e:"\\)"},a="attribute block constant cycle date dump include max min parent random range source template_from_string",r={cN:"function",bK:a,r:0,c:[t]},c={cN:"filter",b:/\|[A-Za-z_]+:?/,k:"abs batch capitalize convert_encoding date date_modify default escape first format join json_encode keys last length lower merge nl2br number_format raw replace reverse round slice sort split striptags title trim upper url_encode",c:[r]},n="autoescape block do embed extends filter flush for if import include macro sandbox set spaceless use verbatim";return n=n+" "+n.split(" ").map(function(e){return"end"+e}).join(" "),{aliases:["craftcms"],cI:!0,sL:"xml",c:[e.C(/\{#/,/#}/),{cN:"template_tag",b:/\{%/,e:/%}/,k:n,c:[c,r]},{cN:"variable",b:/\{\{/,e:/}}/,c:[c,r]}]}});hljs.registerLanguage("makefile",function(e){var a={cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]};return{aliases:["mk","mak"],c:[e.HCM,{b:/^\w+\s*\W*=/,rB:!0,r:0,starts:{cN:"constant",e:/\s*\W*=/,eE:!0,starts:{e:/$/,r:0,c:[a]}}},{cN:"title",b:/^[\w]+:\s*$/},{cN:"phony",b:/^\.PHONY:/,e:/$/,k:".PHONY",l:/[\.\w]+/},{b:/^\t+/,e:/$/,r:0,c:[e.QSM,a]}]}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",a={cN:"function",b:c+"\\(",rB:!0,eE:!0,e:"\\("},r={cN:"rule",b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{cN:"value",eW:!0,eE:!0,c:[a,e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"id",b:/\#[A-Za-z0-9_-]+/},{cN:"class",b:/\.[A-Za-z0-9_-]+/},{cN:"attr_selector",b:/\[/,e:/\]/,i:"$"},{cN:"pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"']+/},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[a,e.ASM,e.QSM,e.CSSNM]}]},{cN:"tag",b:c,r:0},{cN:"rules",b:"{",e:"}",i:/\S/,c:[e.CBCM,r]}]}});hljs.registerLanguage("applescript",function(e){var t=e.inherit(e.QSM,{i:""}),r={cN:"params",b:"\\(",e:"\\)",c:["self",e.CNM,t]},o=e.C("--","$"),n=e.C("\\(\\*","\\*\\)",{c:["self",o]}),a=[o,n,e.HCM];return{aliases:["osascript"],k:{keyword:"about above after against and around as at back before beginning behind below beneath beside between but by considering contain contains continue copy div does eighth else end equal equals error every exit fifth first for fourth from front get given global if ignoring in into is it its last local me middle mod my ninth not of on onto or over prop property put ref reference repeat returning script second set seventh since sixth some tell tenth that the|0 then third through thru timeout times to transaction try until where while whose with without",constant:"AppleScript false linefeed return pi quote result space tab true",type:"alias application boolean class constant date file integer list number real record string text",command:"activate beep count delay launch log offset read round run say summarize write",property:"character characters contents day frontmost id item length month name paragraph paragraphs rest reverse running time version weekday word words year"},c:[t,e.CNM,{cN:"type",b:"\\bPOSIX file\\b"},{cN:"command",b:"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{cN:"constant",b:"\\b(text item delimiters|current application|missing value)\\b"},{cN:"keyword",b:"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference))\\b"},{cN:"property",b:"\\b(POSIX path|(date|time) string|quoted form)\\b"},{cN:"function_start",bK:"on",i:"[${=;\\n]",c:[e.UTM,r]}].concat(a),i:"//|->|=>|\\[\\["}});hljs.registerLanguage("xml",function(t){var s="[A-Za-z0-9\\._:-]+",c={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php"},e={eW:!0,i:/]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"doctype",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},t.C("",{r:10}),{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"|$)",e:">",k:{title:"style"},c:[e],starts:{e:"",rE:!0,sL:"css"}},{cN:"tag",b:"|$)",e:">",k:{title:"script"},c:[e],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars"]}},c,{cN:"pi",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"",c:[{cN:"title",b:/[^ \/><\n\t]+/,r:0},e]}]}});hljs.registerLanguage("ruby",function(e){var c="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r="and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",b={cN:"doctag",b:"@[A-Za-z]+"},a={cN:"value",b:"#<",e:">"},n=[e.C("#","$",{c:[b]}),e.C("^\\=begin","^\\=end",{c:[b],r:10}),e.C("^__END__","\\n$")],s={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,s],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/}]},i={cN:"params",b:"\\(",e:"\\)",k:r},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(n)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:c}),i].concat(n)},{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":",c:[t,{b:c}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:[a,{cN:"regexp",c:[e.BE,s],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(n),r:0}].concat(n);s.c=d,i.c=d;var o="[>?]>",l="[\\w#]+\\(\\w+\\):\\d+:\\d+>",u="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",N=[{b:/^\s*=>/,cN:"status",starts:{e:"$",c:d}},{cN:"prompt",b:"^("+o+"|"+l+"|"+u+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,i:/\/\*/,c:n.concat(N).concat(d)}});hljs.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"(AV|CA|CF|CG|CI|MK|MP|NS|UI)\\w+"},i={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},o=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:i,l:o,i:""}]}]},{cN:"class",b:"("+n.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:n,l:o,c:[e.UTM]},{cN:"variable",b:"\\."+e.UIR,r:0}]}});hljs.registerLanguage("python",function(e){var r={cN:"prompt",b:/^(>>>|\.\.\.) /},b={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[r],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[r],r:10},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},e.ASM,e.QSM]},a={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},l={cN:"params",b:/\(/,e:/\)/,c:["self",r,a,b]};return{aliases:["py","gyp"],k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:[r,a,b,e.HCM,{v:[{cN:"function",bK:"def",r:10},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,l]},{cN:"decorator",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("swift",function(e){var i={keyword:"__COLUMN__ __FILE__ __FUNCTION__ __LINE__ as as! as? associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip"},t={cN:"type",b:"\\b[A-Z][\\w']*",r:0},n=e.C("/\\*","\\*/",{c:["self"]}),r={cN:"subst",b:/\\\(/,e:"\\)",k:i,c:[]},a={cN:"number",b:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",r:0},o=e.inherit(e.QSM,{c:[r,e.BE]});return r.c=[a],{k:i,c:[o,e.CLCM,n,t,a,{cN:"func",bK:"func",e:"{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/,i:/\(/}),{cN:"generics",b://,i:/>/},{cN:"params",b:/\(/,e:/\)/,endsParent:!0,k:i,c:["self",a,o,e.CBCM,{b:":"}],i:/["']/}],i:/\[|%/},{cN:"class",bK:"struct protocol class extension enum",k:i,e:"\\{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/})]},{cN:"preprocessor",b:"(@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain)"},{bK:"import",e:/$/,c:[e.CLCM,n]}]}});hljs.registerLanguage("coffeescript",function(e){var c={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",r={cN:"subst",b:/#\{/,e:/}/,k:c},t=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,r]},{b:/"/,e:/"/,c:[e.BE,r]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[r,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{cN:"property",b:"@"+n},{b:"`",e:"`",eB:!0,eE:!0,sL:"javascript"}];r.c=t;var s=e.inherit(e.TM,{b:n}),i="(\\(.*\\))?\\s*\\B[-=]>",o={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:c,c:["self"].concat(t)}]};return{aliases:["coffee","cson","iced"],k:c,i:/\/\*/,c:t.concat([e.C("###","###"),e.HCM,{cN:"function",b:"^\\s*"+n+"\\s*=\\s*"+i,e:"[-=]>",rB:!0,c:[s,o]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:i,e:"[-=]>",rB:!0,c:[o]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[s]},s]},{cN:"attribute",b:n+":",e:":",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage("perl",function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",r={cN:"subst",b:"[$@]\\{",e:"\\}",k:t},s={b:"->{",e:"}"},n={cN:"variable",v:[{b:/\$\d/},{b:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{b:/[\$%@][^\s\w{]/,r:0}]},o=[e.BE,r,n],i=[n,e.HCM,e.C("^\\=\\w","\\=cut",{eW:!0}),s,{cN:"string",c:o,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"sub",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",r:5},{cN:"operator",b:"-\\w\\b",r:0},{b:"^__DATA__$",e:"^__END__$",sL:"mojolicious",c:[{b:"^@@.*",e:"$",cN:"comment"}]}];return r.c=i,s.c=i,{aliases:["pl"],k:t,c:i}});hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},r={cN:"string",v:[t.inherit(t.QSM,{b:'((u8?|U)|L)?"'}),{b:'(u8?|U)?R"',e:'"',c:[t.BE]},{b:"'\\\\?.",e:"'",i:"."}]},s={cN:"number",v:[{b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},{b:t.CNR}]},i={cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line pragma ifdef ifndef",c:[{b:/\\\n/,r:0},{bK:"include",e:"$",c:[r,{cN:"string",b:"<",e:">",i:"\\n"}]},r,s,t.CLCM,t.CBCM]},a=t.IR+"\\s*\\(",c={keyword:"int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf",literal:"true false nullptr NULL"};return{aliases:["c","cc","h","c++","h++","hpp"],k:c,i:"",k:c,c:["self",e]},{b:t.IR+"::",k:c},{bK:"new throw return else",r:0},{cN:"function",b:"("+t.IR+"[\\*&\\s]+)+"+a,rB:!0,e:/[{;=]/,eE:!0,k:c,i:/[^\w\s\*&]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,s]},t.CLCM,t.CBCM,i]}]}});hljs.registerLanguage("http",function(t){return{aliases:["https"],i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("json",function(e){var t={literal:"true false null"},i=[e.QSM,e.CNM],l={cN:"value",e:",",eW:!0,eE:!0,c:i,k:t},c={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:l}],i:"\\S"},n={b:"\\[",e:"\\]",c:[e.inherit(l,{cN:null})],i:"\\S"};return i.splice(i.length,0,c,n),{c:i,k:t,i:"\\S"}});hljs.registerLanguage("scss",function(e){var t="[a-zA-Z-][a-zA-Z0-9_-]*",i={cN:"variable",b:"(\\$"+t+")\\b"},r={cN:"function",b:t+"\\(",rB:!0,eE:!0,e:"\\("},o={cN:"hexcolor",b:"#[0-9A-Fa-f]+"};({cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:!0,i:"[^\\s]",starts:{cN:"value",eW:!0,eE:!0,c:[r,o,e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"important",b:"!important"}]}});return{cI:!0,i:"[=/|']",c:[e.CLCM,e.CBCM,r,{cN:"id",b:"\\#[A-Za-z0-9_-]+",r:0},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"tag",b:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",r:0},{cN:"pseudo",b:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{cN:"pseudo",b:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},i,{cN:"attribute",b:"\\b(z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background-blend-mode|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",i:"[^\\s]"},{cN:"value",b:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{cN:"value",b:":",e:";",c:[r,i,o,e.CSSNM,e.QSM,e.ASM,{cN:"important",b:"!important"}]},{cN:"at_rule",b:"@",e:"[{;]",k:"mixin include extend for if else each while charset import debug media page content font-face namespace warn",c:[r,i,e.QSM,e.ASM,o,e.CSSNM,{cN:"preprocessor",b:"\\s[A-Za-z0-9_.-]+",r:0}]}]}});hljs.registerLanguage("java",function(e){var a=e.UIR+"(<"+e.UIR+">)?",t="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private",c="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",r={cN:"number",b:c,r:0};return{aliases:["jsp"],k:t,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+a+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:t,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},r,{cN:"annotation",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("php",function(e){var c={cN:"variable",b:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},a={cN:"preprocessor",b:/<\?(php)?|\?>/},i={cN:"string",c:[e.BE,a],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},t={v:[e.BNM,e.CNM]};return{aliases:["php3","php4","php5","php6"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.CLCM,e.HCM,e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"},a]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:/<<<['"]?\w+['"]?$/,e:/^\w+;?$/,c:[e.BE,{cN:"subst",v:[{b:/\$\w+/},{b:/\{\$/,e:/\}/}]}]},a,c,{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",c,e.CBCM,i,t]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},i,t]}}); \ No newline at end of file diff --git a/static/~brozek/themes/bitsandpieces/scripts/mousetrap.min.js b/static/~brozek/themes/bitsandpieces/scripts/mousetrap.min.js new file mode 100644 index 0000000..0128950 --- /dev/null +++ b/static/~brozek/themes/bitsandpieces/scripts/mousetrap.min.js @@ -0,0 +1,11 @@ +/* mousetrap v1.6.0 craig.is/killing/mice */ +(function(r,t,g){function u(a,b,h){a.addEventListener?a.addEventListener(b,h,!1):a.attachEvent("on"+b,h)}function y(a){if("keypress"==a.type){var b=String.fromCharCode(a.which);a.shiftKey||(b=b.toLowerCase());return b}return k[a.which]?k[a.which]:p[a.which]?p[a.which]:String.fromCharCode(a.which).toLowerCase()}function D(a){var b=[];a.shiftKey&&b.push("shift");a.altKey&&b.push("alt");a.ctrlKey&&b.push("ctrl");a.metaKey&&b.push("meta");return b}function v(a){return"shift"==a||"ctrl"==a||"alt"==a|| +"meta"==a}function z(a,b){var h,c,e,g=[];h=a;"+"===h?h=["+"]:(h=h.replace(/\+{2}/g,"+plus"),h=h.split("+"));for(e=0;el||k.hasOwnProperty(l)&&(n[k[l]]=l)}e=n[h]?"keydown":"keypress"}"keypress"==e&&g.length&&(e="keydown");return{key:c,modifiers:g,action:e}}function C(a,b){return null===a||a===t?!1:a===b?!0:C(a.parentNode,b)}function c(a){function b(a){a= +a||{};var b=!1,m;for(m in n)a[m]?b=!0:n[m]=0;b||(w=!1)}function h(a,b,m,f,c,h){var g,e,k=[],l=m.type;if(!d._callbacks[a])return[];"keyup"==l&&v(a)&&(b=[a]);for(g=0;g":".","?":"/","|":"\\"},A={option:"alt",command:"meta","return":"enter", +escape:"esc",plus:"+",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?"meta":"ctrl"},n;for(g=1;20>g;++g)k[111+g]="f"+g;for(g=0;9>=g;++g)k[g+96]=g;c.prototype.bind=function(a,b,c){a=a instanceof Array?a:[a];this._bindMultiple.call(this,a,b,c);return this};c.prototype.unbind=function(a,b){return this.bind.call(this,a,function(){},b)};c.prototype.trigger=function(a,b){if(this._directMap[a+":"+b])this._directMap[a+":"+b]({},a);return this};c.prototype.reset=function(){this._callbacks={};this._directMap= +{};return this};c.prototype.stopCallback=function(a,b){return-1<(" "+b.className+" ").indexOf(" mousetrap ")||C(b,this.target)?!1:"INPUT"==b.tagName||"SELECT"==b.tagName||"TEXTAREA"==b.tagName||b.isContentEditable};c.prototype.handleKey=function(){return this._handleKey.apply(this,arguments)};c.addKeycodes=function(a){for(var b in a)a.hasOwnProperty(b)&&(k[b]=a[b]);n=null};c.init=function(){var a=c(t),b;for(b in a)"_"!==b.charAt(0)&&(c[b]=function(b){return function(){return a[b].apply(a,arguments)}}(b))}; +c.init();r.Mousetrap=c;"undefined"!==typeof module&&module.exports&&(module.exports=c);"function"===typeof define&&define.amd&&define(function(){return c})}})("undefined"!==typeof window?window:null,"undefined"!==typeof window?document:null); diff --git a/static/~brozek/themes/bitsandpieces/styles/highlightjs-github.css b/static/~brozek/themes/bitsandpieces/styles/highlightjs-github.css new file mode 100644 index 0000000..772419a --- /dev/null +++ b/static/~brozek/themes/bitsandpieces/styles/highlightjs-github.css @@ -0,0 +1,121 @@ +/* + +github.com style (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + -webkit-text-size-adjust: none; + /*border-radius: 5px;*/ +} + +.hljs-comment, +.diff .hljs-header { + color: #95a5a6; /* concrete */ + font-style: italic; +} + +.hljs-keyword, +.css .rule .hljs-keyword, +.hljs-winutils, +.nginx .hljs-title, +.hljs-subst, +.hljs-request, +.hljs-status { + color: #4d5757; /* text */ + font-weight: bold; +} + +.hljs-number, +.hljs-hexcolor, +.ruby .hljs-constant { + color: #27ae60; /* dark green */ +} + +.hljs-string, +.hljs-tag .hljs-value, +.hljs-doctag, +.tex .hljs-formula { + color: #c0392b; /* dark fire */ +} + +.hljs-title, +.hljs-id, +.scss .hljs-preprocessor { + color: #c0392b; /* dark fire */ + font-weight: bold; +} + +.hljs-list .hljs-keyword, +.hljs-subst { + font-weight: normal; +} + +.hljs-class .hljs-title, +.hljs-type, +.vhdl .hljs-literal, +.tex .hljs-command { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-tag .hljs-title, +.hljs-rule .hljs-property, +.django .hljs-tag .hljs-keyword { + color: #2980B9; /* dark blue */ + font-weight: normal; +} + +.hljs-attribute, +.hljs-variable, +.lisp .hljs-body, +.hljs-name { + color: #27ae60; /* dark green */ +} + +.hljs-regexp { + color: #009926; +} + +.hljs-symbol, +.ruby .hljs-symbol .hljs-string, +.lisp .hljs-keyword, +.clojure .hljs-keyword, +.scheme .hljs-keyword, +.tex .hljs-special, +.hljs-prompt { + color: #990073; +} + +.hljs-built_in { + color: #0086b3; +} + +.hljs-preprocessor, +.hljs-pragma, +.hljs-pi, +.hljs-doctype, +.hljs-shebang, +.hljs-cdata { + color: #95a5a6; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.diff .hljs-change { + background: #0086b3; +} + +.hljs-chunk { + color: #aaa; +} diff --git a/static/~brozek/themes/bitsandpieces/styles/main.css b/static/~brozek/themes/bitsandpieces/styles/main.css new file mode 100644 index 0000000..75d533f --- /dev/null +++ b/static/~brozek/themes/bitsandpieces/styles/main.css @@ -0,0 +1,377 @@ +/** + * Main.css for Bits and Pieces theme for Pico + * Authored by Fredrik Danielsson, Lost&Keys (http://lostkeys.se) + * Licensed under MIT (https://github.com/lostkeys/Bits-and-Pieces-Theme-for-Pico/blob/master/LICENSE) + * + * Dev note: This stylesheet is using a mobile first approach + */ + + + +/* + * Variables, resets and setup + */ + +:root { + --color-white: #ffffff; + --color-asphalt:#4d5757; + --color-concrete: #c1cacc; + --color-smoke: #e1e7e8; + --color-cloud: #fafafa; + --color-ocean: #2980B9; + --color-grass: #27ae60; + + --accent-color: var(--color-concrete); + --border-color: var(--color-smoke); + --code-bg-color: var(--color-cloud); + --text-color: var(--color-asphalt); + --link-color: var(--color-ocean); + + --vertical-padding: 40px; + --document-horizontal-margin: 80px; + --main-content-max-width: 800px; + --main-content-margin: 0 auto; + --nav-width: 180px; +} + + + +/* + * Font-face + */ + +@font-face { + font-weight: 400; + font-style: normal; + font-family: 'source-sans-pro'; + src: url('../font/SourceSansPro-Regular.eot'); /* IE9 Compat Modes */ + src: url('../font/SourceSansPro-Regular.eot%3F') format('embedded-opentype'), /* IE6-IE8 */ + url('../font/SourceSansPro-Regular.otf.woff') format('woff'), /* Pretty Modern Browsers */ + url('../font/SourceSansPro-Regular.ttf') format('truetype'); /* Safari, Android, iOS */ +} + +@font-face { + font-weight: 400; + font-style: italic; + font-family: 'source-sans-pro'; + src: url('../font/SourceSansPro-It.eot'); /* IE9 Compat Modes */ + src: url('../font/SourceSansPro-It.eot%3F') format('embedded-opentype'), /* IE6-IE8 */ + url('../font/SourceSansPro-It.otf.woff') format('woff'), /* Pretty Modern Browsers */ + url('../font/SourceSansPro-It.ttf') format('truetype'); /* Safari, Android, iOS */ +} + +@font-face { + font-weight: 700; + font-style: normal; + font-family: 'source-sans-pro'; + src: url('../font/SourceSansPro-Semibold.eot'); /* IE9 Compat Modes */ + src: url('../font/SourceSansPro-Semibold.eot%3F') format('embedded-opentype'), /* IE6-IE8 */ + url('../font/SourceSansPro-Semibold.otf.woff') format('woff'), /* Pretty Modern Browsers */ + url('../font/SourceSansPro-Semibold.ttf') format('truetype'); /* Safari, Android, iOS */ +} + +@font-face { + font-weight: 700; + font-style: italic; + font-family: 'source-sans-pro'; + src: url('../font/SourceSansPro-SemiboldIt.eot'); + /* IE9 Compat Modes */ + src: url('../font/SourceSansPro-SemiboldIt.eot%3F') format('embedded-opentype'), /* IE6-IE8 */ + url('../font/SourceSansPro-SemiboldIt.otf.woff') format('woff'), /* Pretty Modern Browsers */ + url('../font/SourceSansPro-SemiboldIt.ttf') format('truetype'); /* Safari, Android, iOS */ +} + + + +/* + * Mediaqueries + */ + +@media (max-width: 1200px) { + :root { + --main-content-margin: 0 0 0 var(--nav-width); + } +} + + + +/* + * Block styling + */ + +html { + font-size: 16px; + font-family: "source-sans-pro", "Helvetica Neue", Helvetica, Arial, sans-serif; + line-height: 1.4; +} + +body { + margin: 0; + background-color: #fff; + color: var(--text-color); +} + + + +/* + * Structure + */ + +.main-content { + margin: var(--main-content-margin); + max-width: var(--main-content-max-width); +} + +.main-content .article { + margin-top: var(--document-horizontal-margin); + margin-bottom: var(--document-horizontal-margin); + margin-left: var(--vertical-padding); + margin-right: var(--vertical-padding); +} + + + +/* + * Basic styling + */ + +a, +a:link, +a:visited { + color: var(--link-color); + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +a:active, +a:focus { + text-decoration: underline; +} + +hr { + margin: 1rem 0; + border-width: 1px 0 0 0; + border-style: solid; + border-color: #ecf0f1; +} + +h1 { + margin-top: 6rem; + margin-bottom: 3rem; + font-weight: normal; + font-size: 2.5rem; + letter-spacing: -0.025rem; +} + +h2 { + margin-top: 1.5rem; + margin-bottom: 1.5rem; + padding-top: 1.5rem; + padding-bottom: 1.5rem; + font-weight: bold; + font-size: 1.5rem; + border-bottom: 1px solid var(--border-color); + position: -webkit-sticky; + top:0; + background-color: #fff; +} + +h3 { + margin-top: 3rem; + margin-bottom: 1rem; + font-size: 1.25rem; + font-weight: bold; +} + +h4, +h5, +h6 { + font-size: 1rem; + margin: 1rem 0; +} + +h2::before, +h3::before +{ + font-weight: 400; + font-size: 1.25rem; + text-align: right; + width: 1.5rem; + content: '#'; + padding-right: .5rem; + margin-left: -2rem; + color: var(--accent-color); + display: inline-block; + -webkit-font-smoothing: antialiased; +} + +.main-content h1:first-of-type { + margin-top: 0; +} + + +h2 + h3 { + margin-top: 1.5rem; +} + + +table { + width: 100%; + border-collapse: collapse; + margin: 1rem 0; +} + +table td, +table th { + text-align: left; + padding: .3rem 0; + border-style: solid; + border-color: var(--border-color); + border-width: 1px 0; +} + +/* Avoid border-on-border together with bordered H2 */ +h2 + table tr:first-child th, +h2 + table tr:first-child td { + border-top-width: 0; +} + +code { + font-size: .875rem; + display: inline-block; + padding: 0 3px; + border: 1px solid var(--border-color); + border-radius: 1px; + background-color: var(--code-bg-color); + color: var(--text-color); +} + +pre code { + display: block; + padding: 5px 10px; +} + + + +/* + * Main navigation + */ + +.main-nav { + box-sizing: border-box; + position: fixed; + top: 0; + left: 0; + padding-left: var(--vertical-padding); + overflow-x: hidden; + overflow-y: scroll; + width: var(--nav-width); + height: 100vh; +} + +.main-nav::-webkit-scrollbar { + display: none; +} + +.main-nav a { + color: var(--text-color); + font-size: 0.9rem; + overflow: hidden; + padding-top: 5px; + padding-bottom: 0; + text-overflow: ellipsis; + white-space: nowrap; + display: flex; +} + +.main-nav a:hover { + text-decoration: none; +} + +.main-nav a .shortcut { + align-self: center; + color: var(--color-concrete); + display: inline-block; + font-size: .6875rem; + font-weight: normal; + margin-left: auto; + text-align: right; +} + +.main-nav nav { + padding: var(--document-horizontal-margin) 0; +} + +.main-nav nav ul { + margin: 0; + padding-left: 0; + list-style: none; +} + +.main-nav nav li { + margin-left: 0px; +} + +.main-nav nav > ul > li { + padding-left: 0px; +} + +.main-nav nav li.active { + +} + +.main-nav nav li.active > a { + font-weight: bold; +} + +/* Main nav Tree (not implemented...yet */ + +.main-nav nav li.directory > a::before { + content: '▸ '; +} + +.main-nav nav li.directory a.folder-open::before { + content: '▾ '; +} + +.main-nav nav li.directory > ul { + margin-top: 0; + margin-left: 20px; + display: none; + margin-bottom: 10px; +} + +.main-nav nav li.directory.open > ul { + display: block; +} + +/* same-page navigation (Not implemented...yet) */ + +.page-nav:not(:empty) { + padding-top: 5px; +} + +.page-nav a { + padding-top: 0px; + padding-bottom: 0px; + font-size: 0.8em; +} + +.page-nav a:before { + content: '# '; +} +@media (max-width: 800px) { + .main-nav { + display: block; + height: initial; + width: initial; + position: initial; + } + .main-content { + max-width: 100%; + margin: 0; + } +} \ No newline at end of file