
```{R}
library(tidyverse)
library(HumanitiesDataAnalysis)
```

Choose a different collection of texts that you can divide into two
classes. Copying the democratic/republican code above, attempt to
predict the variable using textual features.

Choose two states, and create a dataframe from the `cities` datasets
we’ve been working with. Create some new columns which show population
*change* between different censuses. (Note–you will have the best
results if you make change be the *logarithm* of the change–e.g.,
`change_from_1950_to_1960 = log(\`1960\` / \`1950)\`\`.)

Use `glm` with a binomial model to predict what *state* a city is in
based on some of these population shifts. Then inspect the probabilities
to see which cities it’s especially wrong on. Can you tell why? (You’ll
probably have to look up the cities to tell what’s going on–it’s OK to
use `drop_na` to get rid of entries that prevent things were working
on.)

1.  Choose a different set of documents and compare them along some
    metadata facet by PMI, Dunning Log-Likelihood, and (if applicable)
    TF-IDF. Plot the results in some way, separately or together.

<div class="cell" run="false"
hash="classifying_cache/json/problem1_dea9bad4318780aa3922cbe35feedf8d">

</div>

(Hard, skippable.) Build a logistic classifier to predict the class of a
book based on its synopsis. You can use “Juvenile literature,” or find
another frequent category.

Calculate the classifiers accuracy (the percentage of predictions that
are correct). Look at the highest-likelihood misclassifications in both
directions to see why it might be getting it wrong.

<div class="cell"
hash="classifying_cache/json/unnamed-chunk-18_3ad95d444bceb63ea4d05eb2057ec5e1">

```{R}
titles = books |>
  mutate(.juvenile = subjects |> str_detect("Juvenile literature"))

# Turn titles into a term document matrix with just the class.

tdMatrix = titles |>
  select(.juvenile, lccn, summary) |>
  unnest_tokens(word, summary) |>
  group_by(word) |>
  filter(n() > 5000) |> 
  group_by(word, lccn, .juvenile) |> 
  summarize(count = n()) |>
  group_by(lccn) |>
  pivot_wider(names_from = word, values_from = count, values_fill = c(count = 0)) |>
  ungroup

# etc: fill it out from here using spread, filter, etc. Make sure to limit the
# population of words before you run "pivot_wider."


# Split into test and training data using the lccns.
# This will keep you honest. (Is it an unfair split?)
# The particular function here: `%%` tests if the number
# is divisible by nine. This means one in nine books
# will be in the test set.

train = tdMatrix |> filter(lccn %% 9 != 0)
test = tdMatrix |> filter(lccn %% 9 == 0)

model = glm(.juvenile ~ ., data = train |> select(-lccn), family = "binomial")

summary(model)

test |> mutate(prediction = predict(model, newdata = test)) |> arrange(-prediction) |>
  head(10) |>
  inner_join(books, by = c(".lccn" = "lccn"))
```


```{R}
titles = books |>
  mutate(.juvenile = subjects |> str_detect("Juvenile literature"))

# Turn titles into a term document matrix with just the class.

tdMatrix = titles |>
  select(.juvenile, lccn, summary) |>
  unnest_tokens(word, summary) |>
  group_by(word) |>
  filter(n() > 5000) |> 
  group_by(word, lccn, .juvenile) |> 
  summarize(count = n()) |>
  group_by(lccn) |>
  pivot_wider(names_from = word, values_from = count, values_fill = c(count = 0)) |>
  ungroup

# etc: fill it out from here using spread, filter, etc. Make sure to limit the
# population of words before you run "pivot_wider."


# Split into test and training data using the lccns.
# This will keep you honest. (Is it an unfair split?)
# The particular function here: `%%` tests if the number
# is divisible by nine. This means one in nine books
# will be in the test set.

train = tdMatrix |> filter(lccn %% 9 != 0)
test = tdMatrix |> filter(lccn %% 9 == 0)

model = glm(.juvenile ~ ., data = train |> select(-lccn), family = "binomial")

summary(model)

test |> mutate(prediction = predict(model, newdata = test)) |> arrange(-prediction) |>
  head(10) |>
  inner_join(books, by = c(".lccn" = "lccn"))
```

</div>

Free Exercise. Re-using your code from 3 as much as possible, train some
other classificatory model. It can use textual features or something
else.
