Miscellany / AI concepts and tools
Exploring the Tsetlin Machine! A Cutting-Edge Classification Algorithm
Contents
- Introduction to Tsetlin Machines
- Core Concepts of Tsetlin Machines
- Clause Formation
- Voting Mechanism
- Training Process
- Interpretability
- Binarization of Input Features
- Handling Multi-class Problems
- Hyperparameter Tuning
- Real-life Example: Image Classification
- Real-life Example: Text Classification
- Comparison with Other Algorithms
- Future Directions and Ongoing Research
- Additional Resources
Introduction to Tsetlin Machines
The Tsetlin Machine is a novel machine learning algorithm that uses propositional logic to create interpretable models. It combines concepts from finite state automata, reinforcement learning, and Boolean algebra to tackle classification problems efficiently.
import numpy as np
class TsetlinMachine:
def __init__(self, num_clauses, num_features):
self.num_clauses = num_clauses
self.num_features = num_features
self.ta_state = np.ones((num_clauses, num_features, 2), dtype=int)
Core Concepts of Tsetlin Machines
Tsetlin Machines operate on binary input features and use a collection of Tsetlin Automata (TAs) to learn patterns. Each TA decides whether to include or exclude a specific feature in a clause, forming the building blocks of the machine's decision-making process.
def update_ta_state(self, clause, feature, action, reward):
if action == 1: # Include
if reward == 1:
self.ta_state[clause, feature, 0] = min(self.ta_state[clause, feature, 0] + 1, 100)
else:
self.ta_state[clause, feature, 0] = max(self.ta_state[clause, feature, 0] - 1, 1)
else: # Exclude
if reward == 1:
self.ta_state[clause, feature, 1] = min(self.ta_state[clause, feature, 1] + 1, 100)
else:
self.ta_state[clause, feature, 1] = max(self.ta_state[clause, feature, 1] - 1, 1)
Clause Formation
Clauses in Tsetlin Machines are conjunctions of literals (features or their negations). They act as pattern detectors, activating when specific feature combinations are present in the input.
def compute_clause_output(self, X):
clause_output = np.ones((self.num_clauses, X.shape[0]), dtype=bool)
for j in range(self.num_features):
clause_output *= (self.ta_state[:, j, 0] > self.ta_state[:, j, 1]).reshape(-1, 1) == X[:, j]
return clause_output
Voting Mechanism
The Tsetlin Machine uses a voting mechanism where clauses vote for or against a particular class. The final classification is determined by summing these votes and comparing them to a threshold.
def predict(self, X):
clause_output = self.compute_clause_output(X)
class_sum = np.sum(clause_output[:self.num_clauses//2], axis=0) - np.sum(clause_output[self.num_clauses//2:], axis=0)
return (class_sum >= 0).astype(int)
Training Process
Training a Tsetlin Machine involves updating the states of TAs based on the clause outputs and the true label. This process reinforces correct decisions and penalizes incorrect ones.
def fit(self, X, y, epochs=100):
for _ in range(epochs):
for i in range(X.shape[0]):
clause_output = self.compute_clause_output(X[i:i+1])
for j in range(self.num_clauses):
if (j < self.num_clauses // 2) == y[i]:
if clause_output[j]:
for k in range(self.num_features):
self.update_ta_state(j, k, 1 if X[i, k] else 0, 1)
else:
if not clause_output[j]:
for k in range(self.num_features):
action = 1 if self.ta_state[j, k, 0] > self.ta_state[j, k, 1] else 0
self.update_ta_state(j, k, action, 1)
Interpretability
One of the key advantages of Tsetlin Machines is their interpretability. The learned clauses can be easily translated into human-readable logical expressions.
def interpret_clause(self, clause_index):
clause = []
for feature in range(self.num_features):
if self.ta_state[clause_index, feature, 0] > self.ta_state[clause_index, feature, 1]:
clause.append(f"x{feature}")
elif self.ta_state[clause_index, feature, 1] > self.ta_state[clause_index, feature, 0]:
clause.append(f"¬x{feature}")
return " ∧ ".join(clause)
# Example usage
tm = TsetlinMachine(10, 5)
print(tm.interpret_clause(0))
# Output might be something like: x0 ∧ ¬x2 ∧ x4
Binarization of Input Features
Tsetlin Machines work with binary inputs. For continuous features, we need to implement a binarization process.
def binarize(X, threshold=0.5):
return (X > threshold).astype(int)
# Example
X_continuous = np.array([[0.1, 0.6, 0.3],
[0.7, 0.2, 0.8],
[0.4, 0.9, 0.5]])
X_binary = binarize(X_continuous)
print(X_binary)
# Output:
# [[0 1 0]
# [1 0 1]
# [0 1 0]]
Handling Multi-class Problems
While the basic Tsetlin Machine is designed for binary classification, it can be extended to handle multi-class problems using a one-vs-rest approach.
class MultiClassTsetlinMachine:
def __init__(self, num_classes, num_clauses_per_class, num_features):
self.num_classes = num_classes
self.tsetlin_machines = [TsetlinMachine(num_clauses_per_class, num_features) for _ in range(num_classes)]
def fit(self, X, y, epochs=100):
for i in range(self.num_classes):
binary_y = (y == i).astype(int)
self.tsetlin_machines[i].fit(X, binary_y, epochs)
def predict(self, X):
votes = np.array([tm.predict(X) for tm in self.tsetlin_machines])
return np.argmax(votes, axis=0)
Hyperparameter Tuning
Tsetlin Machines have several hyperparameters that can be tuned to optimize performance. These include the number of clauses, the threshold T, and the specificity s.
import optuna
def objective(trial):
num_clauses = trial.suggest_int('num_clauses', 10, 100)
threshold = trial.suggest_int('threshold', 1, 10)
s = trial.suggest_float('s', 1.0, 10.0)
tm = TsetlinMachine(num_clauses, num_features, threshold, s)
tm.fit(X_train, y_train)
return accuracy_score(y_test, tm.predict(X_test))
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)
print('Best trial:')
trial = study.best_trial
print(f' Value: {trial.value}')
print(' Params: ')
for key, value in trial.params.items():
print(f' {key}: {value}')
Real-life Example: Image Classification
Tsetlin Machines can be applied to image classification tasks. Here's an example using the MNIST dataset:
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
# Load MNIST dataset
X, y = fetch_openml('mnist_784', version=1, return_X_y=True, as_frame=False)
X = binarize(X / 255.0) # Normalize and binarize
y = y.astype(int)
# Split the data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Train MultiClassTsetlinMachine
mctm = MultiClassTsetlinMachine(10, 2000, 784)
mctm.fit(X_train, y_train, epochs=50)
# Evaluate
accuracy = np.mean(mctm.predict(X_test) == y_test)
print(f"Accuracy: {accuracy:.4f}")
Real-life Example: Text Classification
Tsetlin Machines can also be applied to text classification tasks. Here's an example using a simple sentiment analysis dataset:
from sklearn.feature_extraction.text import CountVectorizer
# Sample dataset
texts = ["I love this movie", "This film is terrible", "Great acting and plot", "Boring and predictable"]
labels = [1, 0, 1, 0] # 1 for positive, 0 for negative
# Vectorize the text
vectorizer = CountVectorizer(binary=True)
X = vectorizer.fit_transform(texts).toarray()
# Train TsetlinMachine
tm = TsetlinMachine(num_clauses=10, num_features=X.shape[1])
tm.fit(X, labels, epochs=100)
# Test
new_text = ["This movie is amazing"]
X_new = vectorizer.transform(new_text).toarray()
prediction = tm.predict(X_new)
print(f"Sentiment: {'Positive' if prediction[0] == 1 else 'Negative'}")
Comparison with Other Algorithms
Tsetlin Machines offer unique advantages over traditional machine learning algorithms. Let's compare their performance with a decision tree on a simple dataset:
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# Generate a random dataset
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, random_state=42)
X = binarize(X)
# Split the data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Train and evaluate Tsetlin Machine
tm = TsetlinMachine(num_clauses=100, num_features=20)
tm.fit(X_train, y_train, epochs=100)
tm_accuracy = accuracy_score(y_test, tm.predict(X_test))
# Train and evaluate Decision Tree
dt = DecisionTreeClassifier(random_state=42)
dt.fit(X_train, y_train)
dt_accuracy = accuracy_score(y_test, dt.predict(X_test))
print(f"Tsetlin Machine Accuracy: {tm_accuracy:.4f}")
print(f"Decision Tree Accuracy: {dt_accuracy:.4f}")
Future Directions and Ongoing Research
Tsetlin Machines are an active area of research with ongoing developments in areas such as:
- Convolutional Tsetlin Machines for image processing
- Regression Tsetlin Machines for continuous output prediction
- Tsetlin Machine ensembles for improved performance
- Hardware implementations for faster inference
Researchers are also exploring ways to incorporate fuzzy logic and handle missing data more effectively in Tsetlin Machines.
# Pseudocode for a Convolutional Tsetlin Machine
class ConvolutionalTsetlinMachine:
def __init__(self, num_filters, filter_size, stride):
self.num_filters = num_filters
self.filter_size = filter_size
self.stride = stride
self.filters = [TsetlinMachine(...) for _ in range(num_filters)]
def convolve(self, input_image):
# Apply each filter to the input image
feature_maps = []
for filter in self.filters:
feature_map = np.zeros_like(input_image)
for i in range(0, input_image.shape[0] - self.filter_size + 1, self.stride):
for j in range(0, input_image.shape[1] - self.filter_size + 1, self.stride):
patch = input_image[i:i+self.filter_size, j:j+self.filter_size]
feature_map[i, j] = filter.predict(patch.flatten())
feature_maps.append(feature_map)
return feature_maps
Additional Resources
For those interested in delving deeper into Tsetlin Machines, here are some valuable resources:
- Original Paper: "The Tsetlin Machine - A Game Theoretic Bandit Driven Approach to Optimal Pattern Recognition with Propositional Logic" by Ole-Christoffer Granmo (arXiv:1804.01508)
- GitHub Repository: https://github.com/cair/pyTsetlinMachine
- Survey Paper: "A Survey of the Tsetlin Machine and Its Variants" by K. Darshana Abeyrathna et al. (arXiv:2104.14545)
- Tsetlin Machine Project Website: https://tsetlinmachine.org/
These resources provide in-depth explanations, implementations, and the latest research developments in Tsetlin Machines.