An NLI-Based Approach to Asset-Specific Stance Detection in Cryptocurrency Tweets
This model classifies the stance of tweets toward Bitcoin (BTC) and Ethereum (ETH) as Bullish, Bearish, or Neutral using a Natural Language Inference (NLI) approach.
Instead of standard 3-class classification, this model frames stance detection as an entailment task. For each tweet, three hypotheses are constructed (one per stance), and the model scores which hypothesis is most entailed by the tweet:
Stance
Hypothesis
Bullish
"The author's perspective on {target} in this tweet reflects a bullish sentiment."
Bearish
"The author's perspective on {target} in this tweet reflects a bearish sentiment."
Neutral
"The author's perspective on {target} in this tweet reflects a neutral sentiment."
The predicted stance is the one with the highest entailment score.
Usage
python
1from transformers import pipeline
23classifier = pipeline("zero-shot-classification", model="syahrezapratama/crypto-stance-nli")45tweet ="Bitcoin is going to the moon! $100k is just the beginning 🚀"67result = classifier(8 tweet,9 candidate_labels=["bullish","bearish","neutral"],10 hypothesis_template="The author's perspective on BTC in this tweet reflects a {} sentiment.",11)1213print(result["labels"][0])# "bullish"14print(result["scores"][0])# ~0.999
Manual inference (more control)
python
1from transformers import AutoTokenizer, AutoModelForSequenceClassification
2import torch
34model_name ="syahrezapratama/crypto-stance-nli"5tokenizer = AutoTokenizer.from_pretrained(model_name)6model = AutoModelForSequenceClassification.from_pretrained(model_name)7model.eval()89tweet ="I'm not sure where ETH is headed, could go either way"10stances =["bullish","bearish","neutral"]11template ="The author's perspective on ETH in this tweet reflects a {} sentiment."1213scores =[]14for stance in stances:15 hypothesis = template.format(stance)16 inputs = tokenizer(tweet, hypothesis, return_tensors="pt", truncation=True, max_length=128)17with torch.no_grad():18 logits = model(**inputs).logits
19# Entailment is index 0 for DeBERTa-MNLI20 entailment_score = torch.softmax(logits, dim=-1)[0,0].item()21 scores.append(entailment_score)2223predicted = stances[scores.index(max(scores))]24print(f"Predicted stance: {predicted}")# "neutral"
Performance
Evaluated on a held-out test set of 450 tweets (70/15/15 train/val/test split, seed=42).
Overall metrics
Metric
Value
Accuracy
80.67%
Macro F1
0.7606
Weighted F1
0.8009
Per-class metrics
Class
Precision
Recall
F1
Support
Bearish
0.8108
0.6383
0.7143
47
Neutral
0.8137
0.9154
0.8616
272
Bullish
0.7850
0.6412
0.7059
131
Comparison with baselines
Model
Paradigm
Accuracy
Macro F1
DeBERTa-MNLI
Zero-Shot (Baseline)
43.33%
0.4192
DeBERTa-MNLI
Zero-Shot (OPRO)
50.44%
0.4538
DeBERTa-NLI
Fine-Tuned
80.67%
0.7606
GPT-4o
Zero-Shot
76.67%
0.7275
Training details
Dataset
Source: 3,000 cryptocurrency tweets about BTC and ETH