Skip to content
academia.sh

Lesson 07 / 24

Content Inventory and Grouping

Deriving structure from content; the inventory's columns, building a similarity matrix from card-sorting data, threshold-based grouping, and detecting cards without consensus.

Contents

The problem is defined and the solution space is clear. The first question is not the screens themselves but the structure between them. The catalog interface carries thousands of records, dozens of subjects, and a set of operations; which headings these fall under is not a matter of style. A wrong grouping leads the user to search for what they want in the wrong place, a loss no search box can rescue.

Information architecture is the grouping and naming of content and the establishment of the relationships between its pieces. This lesson shows where the structure is derived from: first an inventory that counts what exists, then a study that measures how users group these items.

What the Inventory Counts

Content inventory is the list of every item the interface carries. Grouping is impossible without the list; what is being grouped is unknown otherwise. The inventory has five columns.

  • Item. The name of the content. Not the screen name, but the content itself: “borrowing terms” is an item, “help page” is a container.
  • Type. Is it a record, an explanatory text, an operation, or an external link. Type determines not how the item is displayed, but how it can be grouped.
  • Task link. Which task the item serves. It connects to the task inventory built in the third lesson. An item that cannot be linked to any task stays in the inventory as a question mark.
  • Owner. Who updates the content. Content without an owner grows stale, and stale content is wrong information.
  • Last updated. How long the item has gone unchanged.

The last two columns do not directly affect the grouping decision, but they are the inventory’s most useful part: content that should be deleted before the structure is built shows up here. In the catalog interface, an item that cannot be linked to any task and has not been updated in two years is not an item to group but one to remove.

User Grouping Is Measured

Having the design team do the grouping results in the organization copying its own structure onto the interface. In the library’s internal organization, the “circulation unit” and the “reference unit” may be separate; the user does not know this distinction and does not search for the “interlibrary loan” item by which unit runs it.

Card sorting is giving participants the inventory’s items as cards and asking them to group them their own way. If the participant assigns the group names, it is open sorting; if the names are given in advance, it is closed sorting. Open sorting measures structure and naming together; closed sorting serves to test an existing structure.

The result is a stack of patterns and cannot be read one by one. Ten participants’ ten separate sortings are reduced to how often the cards were grouped together.

// card-sorting.mjs — similarity matrix and grouping from card-sorting data

// The 15 content items in the inventory and each item's expected cluster (a hypothesis to verify)
const CARDS = [
  ["search tips", "discover"], ["subject headings", "discover"], ["new arrivals", "discover"],
  ["databases", "discover"], ["borrowing terms", "borrow"], ["late fees", "borrow"],
  ["renewal", "borrow"], ["reservation", "borrow"], ["interlibrary loan", "borrow"],
  ["shelf plan", "on-site"], ["study rooms", "on-site"], ["opening hours", "on-site"],
  ["membership signup", "account"], ["password reset", "account"], ["contact", "unclear"],
];
const CATEGORIES = ["discover", "borrow", "on-site", "account"];

// Deterministic pseudo-random generator (mulberry32)
function makeRng(seed) {
  let a = seed >>> 0;
  return () => {
    a = (a + 0x6d2b79f5) >>> 0;
    let t = Math.imul(a ^ (a >>> 15), 1 | a);
    t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}
const rng = makeRng(20260101);

// How the 10 participants group the cards: 80% match to the expected category, the "unclear" card is free
const PARTICIPANTS = 10;
const sorts = [];
for (let k = 0; k < PARTICIPANTS; k++) {
  sorts.push(
    CARDS.map(([, expected]) =>
      expected === "unclear" || rng() > 0.8
        ? CATEGORIES[Math.floor(rng() * CATEGORIES.length)]
        : expected
    )
  );
}

// Similarity matrix: how many participants put i and j in the same group
const n = CARDS.length;
const M = Array.from({ length: n }, () => new Array(n).fill(0));
for (const s of sorts)
  for (let i = 0; i < n; i++)
    for (let j = 0; j < n; j++) if (i !== j && s[i] === s[j]) M[i][j]++;

console.log("similarity matrix (how many of the 10 participants grouped them together)");
console.log(" ".repeat(24) + CARDS.map((_, i) => String(i + 1).padStart(3)).join(""));
CARDS.forEach(([name], i) => {
  console.log(
    `${String(i + 1).padStart(2)} ${name.padEnd(21)}` +
      M[i].map((v, j) => (i === j ? "  ." : String(v).padStart(3))).join("")
  );
});

// Distance = 1 - similarity; merge with average linkage, stop at threshold 0.5
const dist = (i, j) => 1 - M[i][j] / PARTICIPANTS;
let groups = CARDS.map((_, i) => [i]);
const linkageDistance = (a, b) => {
  let t = 0;
  for (const i of a) for (const j of b) t += dist(i, j);
  return t / (a.length * b.length);
};
const THRESHOLD = 0.5;
while (groups.length > 1) {
  let best = Infinity, pair = null;
  for (let i = 0; i < groups.length; i++)
    for (let j = i + 1; j < groups.length; j++) {
      const d = linkageDistance(groups[i], groups[j]);
      if (d < best) { best = d; pair = [i, j]; }
    }
  if (best > THRESHOLD) break;
  const [i, j] = pair;
  groups = groups.filter((_, x) => x !== i && x !== j).concat([groups[i].concat(groups[j])]);
}
groups = groups.map((g) => g.sort((a, b) => a - b)).sort((a, b) => a[0] - b[0]);

console.log(`\ngroups formed at threshold ${THRESHOLD} (${groups.length} groups)`);
for (const g of groups) console.log(`  ${g.map((i) => CARDS[i][0]).join(", ")}`);

// Each card's affinity gap between its own group and the nearest second group
console.log("\ncard                 own group  nearest other  gap");
const avgSimilarity = (i, g) => {
  const d = g.filter((x) => x !== i);
  return d.length ? d.reduce((t, j) => t + M[i][j], 0) / d.length / PARTICIPANTS : 0;
};
for (let i = 0; i < n; i++) {
  const own = groups.find((g) => g.includes(i));
  const a = avgSimilarity(i, own);
  const others = groups.filter((g) => g !== own).map((g) => avgSimilarity(i, g));
  const b = others.length ? Math.max(...others) : 0;
  console.log(
    `${CARDS[i][0].padEnd(20)} ${a.toFixed(2).padStart(9)}  ${b.toFixed(2).padStart(13)}  ${(a - b).toFixed(2)}${a - b < 0.2 ? "  UNCLEAR" : ""}`
  );
}
similarity matrix (how many of the 10 participants grouped them together)
                          1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
 1 search tips            .  9  8 10  1  1  0  0  1  0  1  1  2  0  2
 2 subject headings       9  .  7  9  1  1  0  0  1  0  2  2  2  0  2
 3 new arrivals           8  7  .  8  0  2  1  1  2  0  0  1  2  1  3
 4 databases             10  9  8  .  1  1  0  0  1  0  1  1  2  0  2
 5 borrowing terms        1  1  0  1  .  8  8  9  7  0  1  0  1  0  2
 6 late fees              1  1  2  1  8  .  8  9  7  0  0  1  0  0  3
 7 renewal                0  0  1  0  8  8  .  9  7  0  1  0  1  1  3
 8 reservation            0  0  1  0  9  9  9  .  8  0  1  0  0  0  3
 9 interlibrary loan      1  1  2  1  7  7  7  8  .  0  1  0  1  1  3
10 shelf plan             0  0  0  0  0  0  0  0  0  .  6  8  2  1  5
11 study rooms            1  2  0  1  1  0  1  1  1  6  .  7  0  1  3
12 opening hours          1  2  1  1  0  1  0  0  0  8  7  .  1  0  3
13 membership signup      2  2  2  2  1  0  1  0  1  2  0  1  .  7  2
14 password reset         0  0  1  0  0  0  1  0  1  1  1  0  7  .  1
15 contact                2  2  3  2  2  3  3  3  3  5  3  3  2  1  .

groups formed at threshold 0.5 (5 groups)
  search tips, subject headings, new arrivals, databases
  borrowing terms, late fees, renewal, reservation, interlibrary loan
  shelf plan, study rooms, opening hours
  membership signup, password reset
  contact

card                 own group  nearest other  gap
search tips               0.90           0.20  0.70
subject headings          0.83           0.20  0.63
new arrivals              0.77           0.30  0.47
databases                 0.90           0.20  0.70
borrowing terms           0.80           0.20  0.60
late fees                 0.80           0.30  0.50
renewal                   0.80           0.30  0.50
reservation               0.88           0.30  0.57
interlibrary loan         0.72           0.30  0.42
shelf plan                0.70           0.50  0.20  UNCLEAR
study rooms               0.65           0.30  0.35
opening hours             0.75           0.30  0.45
membership signup         0.70           0.20  0.50
password reset            0.70           0.10  0.60
contact                   0.00           0.37  -0.37  UNCLEAR

Reading the Matrix

The matrix shows a structure that cannot be extracted from the individual sortings. The first and fourth cards — search tips and databases — were placed in the same group by ten of the ten participants. The fifth and eighth cards were together for nine participants. These values are a measure of agreement: a high count shows that users regard the two items as part of the same task.

The threshold was set at 0.5; that is, two items enter the same group if they were grouped together by at least half the participants. The threshold is not a law of nature but an auditable decision. Raising it produces more, smaller groups; lowering it merges groups. What matters is that the threshold is written down: the sentence “these should stay together” is debatable, while “co-grouping rate 0.7, threshold 0.5” is auditable.

Five groups emerged, and four of them are internally consistent. The fifth “group” carries a single card.

The Card Without Consensus Is the Structure’s Most Important Finding

The affinity gap in the last table is the difference between each card’s average affinity to its own group and its affinity to the nearest second group. A large gap means the card has found its place; a small gap means the participants did not reach consensus.

The contact card did not stay inside any group. Its highest affinity is 0.37, to the on-site group; it does not clear any threshold. This is not a data flaw but a finding: users do not agree on where to look for contact information. Three options exist for such a card, and the choice is made from the data.

  • It is shown in multiple places. If the information is cheap and short, repeating it is harmless; contact information can appear in both the on-site group and the account group.
  • It is taken out of the structure. Some items belong not to groups but to an area reachable from every screen. The footer exists for this.
  • It is split. “Contact” may not be a single item: asking a question about a shelf and reporting a membership problem are separate tasks and go to separate groups. The lack of consensus can be a sign that the item itself splits in two.

The shelf plan card was also flagged: its affinity to its own group is 0.70, but its co-grouping rate with the contact card is 0.50. Half the participants treat asking where a shelf is and looking at the shelf plan as the same task. This is the information-architecture side trace of the “book cannot be found on the shelf” problem measured in the fourth lesson: the user does not know where to look for shelf information.

Naming the Groups

The groups now exist but have no names. In the open form of card sorting, the name is derived from the names the participants gave themselves; among the twelve phrases naming the same group, the most frequently used word is chosen. The organization’s internal vocabulary must not intrude here: if users do not say “circulation services,” the heading does not become “circulation services.”

Two criteria apply to naming. The name must cover the group’s entirety; the heading “renewal” names only one of the five items in the borrowing group. The name must be distinct from a neighboring group; when the headings “library information” and “general information” stand side by side, the user cannot choose which to enter and, unable to choose, tries both.

The Ethical Framework of Card Sorting

Card sorting is a research session, and the rules from the previous lesson apply here as well: the participant gives consent knowing what the sorting is for, the session record is kept under a code name, and the raw recording is deleted within the retention limit after analysis. No single participant’s sorting appears in the matrix above; only the co-grouping counts do.

Two more rules apply to the inventory itself. Content carrying personal data is flagged in the inventory: borrowing history, membership information, and search history are tied to a person, and their grouping decision is made together with the access decision. Every personal-data item in the inventory has its retention period written down; an item without a written period is being stored for an unspecified duration before it is even placed anywhere in the interface.

Summary

  • The content inventory carries item, type, task-link, owner, and last-updated columns; an item that cannot be linked to any task and is not updated is one to remove, not to group.
  • Card sorting ensures that structure is derived from the user’s mental grouping rather than the organization’s internal structure; the open form measures structure and naming together.
  • Individual sortings cannot be read; the data is reduced to a similarity matrix giving the co-grouping count for each pair of cards and grouped by a written threshold.
  • A card with a low affinity gap is a finding, not a flaw; in the sample data, one card could not be attached to any group, and the solution is repetition, moving it outside the structure, or splitting the item.
  • Group names are chosen from the participants’ own words; the name must cover the group’s entirety and be distinct from a neighboring group.
  • Content carrying personal data is flagged in the inventory and written down together with its retention period.

Next Step

Five groups and group names have been obtained, but this is not yet a navigation. How many of the groups are shown at once, how many levels the sub-breakdowns descend, and how many clicks a user needs to reach an item are separate decisions. The next lesson compares hierarchical, flat, and matrix navigation models, computes the trade-off between menu width and depth, and finds the width that minimizes total scanning cost.

To keep your progress and take notes, Log in

My notes

Log in to take notes.

Start typing to search.

↑↓ Esc navigate · open · close