Skip to content

Interpreting a model

A trained Tsetlin machine is a list of rules. torchtsetlin.interpret helps you read them, rank them and explain single predictions.

Rules

model.feature_names = ["four_wheels", "transports_people", "wings", "yellow", "blue"]
model.class_names = ["plane", "car"]
for rule in model.rules(polarity=1):           # only clauses voting *for* their class
    print(rule)
# IF four_wheels AND transports_people AND NOT wings THEN car
model.clause_info(3)                            # dict: class, polarity, weight, n_literals, expression
model.clause_literals(3)                        # {'positive': [0, 1], 'negated': [2]}

Coalesced models list every output a clause votes on with its weight; regression models show the contribution of each clause.

Which clauses matter?

act = tt.interpret.clause_activity(model, x, y)          # (K, C): firing rate per class
cp = tt.interpret.clause_precision(model, x, y)          # support and precision per clause
top = cp["precision"].argsort(descending=True)[:10]

Feature importance (closed form)

Blakely & Granmo (2020) define literal importance directly from the clauses, without perturbation:

  • global: the weighted fraction of positive clauses of a class that include a literal, tt.interpret.global_feature_importance(model) → (K, 2F);
  • local: the weight of the matching clauses of the predicted class that rely on each literal for a specific input, tt.interpret.local_feature_importance(model, x) → (B, 2F).

For thermometer-encoded data, sum the bits of each original feature:

imp = tt.interpret.global_feature_importance(model, class_index=1)
groups = [i // 8 for i in range(n_columns * 8)]           # 8 bits per column
per_feature = tt.interpret.aggregate_literal_importance(imp, groups)
tt.viz.plot_feature_importance(per_feature, column_names)

Explaining one prediction

print(tt.interpret.explain(model, x_test[0], feature_names=model.feature_names))
# prediction: 1  votes: [-10.0, 7.0]
#   [+1 -> output 1] clause 50: IF a>=0.12 AND NOT b>=0.41
#   ...

Inspecting the memory itself

model.ta_state is the raw (C, 2F) state matrix; model.included_mask() the Boolean include matrix; model.literal_frequency() counts how many clauses use each literal; model.state_summary() gives quick statistics. See Visualisation for plots of all of these.