Skip to main content

Sentiment Analysis with LatticaAI Demo Tutorial

Private text is encoded and encrypted on the client, processed by the protected sentiment model, then decrypted on the client as a sentiment result.
Client side
Private textPlaintext stays here
Encrypt input
Server side
Sentiment analysisEncrypted computation
Decrypt result
Client side
SentimentReadable only here

Overview of the Model​

Our Sentiment Analysis model is trained on the Sentiment140 Kaggle dataset. This dataset is a collection of 1.6 million tweets that have been labeled with sentiment polarity- positive or negative, and is commonly used for sentiment analysis and natural language processing tasks.

We trained a logistic regression sentiment classifier using the Term Frequency-Inverse Document Frequency (TF-IDF) approach:

TF-IDF is a numerical representation of text useful for transforming text into a numerical format suitable for machine learning. It measures how important a word is within a document relative to the entire corpus. It consists of:

  • Term Frequency (TF): The number of times a word appears in a document.
  • Inverse Document Frequency (IDF): A measure that reduces the weight of commonly occurring words and increases the weight of rare words.

Here is a sample code for inferring sentiment from text using the trained model:

sentiment_tfidf.json

dictionary containing the vocabulary and the IDF scores

coef.npyintercept.npy
import re
import numpy as np
import json
import torch

def preprocess_text(text: str) -> str:
# Remove links, special characters, and digits
text = re.sub(r'http\S+|www\S+|https\S+', '', text, flags=re.MULTILINE) # Remove URLs
text = re.sub(r'[^a-zA-Z\s]', '', text) # Remove non-alphabetic characters
text = text.lower() # Convert to lowercase
text = text.strip() # Remove leading/trailing whitespaces
return text

def txt2tfidf(s: str, vocab: dict[str, int], idf: list[float]) -> torch.Tensor:
s_clean = preprocess_text(s)
all_words = s_clean.split()
relevant_words = set(s_clean.split()).intersection(vocab.keys())

res = np.zeros(len(vocab))
for w in relevant_words:
w_idx = vocab[w]
w_cnt = all_words.count(w)
w_idf = idf[w_idx]
w_tfidf = w_cnt * w_idf
res[w_idx] = w_tfidf

return torch.tensor(res / np.linalg.norm(res))

# load tfidf data
with open('sentiment_tfidf.json', 'r') as f:
tfidf_data = json.load(f)

# load the coef matrix and intercept vector of the trained logistic regression model
W = np.load('coef.npy') # shape (1,5000)
b = np.load('intercept.npy') # shape (1,)

txt = 'this is the best day of my life'

# transform text to numerical representation
pt = txt2tfidf(txt, tfidf_data['vocabulary'], tfidf_data['idf']) # shape (5000,)

# calculate the logistic regression prediction
res = pt @ W.T + b

# the predicted sentiment is the sign of the logit
sentiment = "POSITIVE" if res > 0 else "NEGATIVE"
print(f"Predicted sentiment: {sentiment}")

Achieving Full Privacy with LatticaAI​

First install our client package

import os

from lattica_query import QueryClient, QueryToken

# Set LATTICA_QUERY_TOKEN to a query token scoped to this demo model.
token = QueryToken(os.environ["LATTICA_QUERY_TOKEN"])
with QueryClient(token) as client:
key = client.keys.ensure()
# `pt` and `res` are torch.Tensor objects, as in the plain example above.
res = client.query.encrypted(pt, key=key)

See our step-by-step guide for a detailed explanation of each step in this flow.
To use the sentiment analysis model, use the sentimentAnalysis model ID.