cogentrl 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cogentrl/__init__.py +0 -0
- cogentrl/decision/__init__.py +6 -0
- cogentrl/decision/agent.py +14 -0
- cogentrl/decision/environment.py +8 -0
- cogentrl/decision/strategy.py +225 -0
- cogentrl/nlp/__init__.py +3 -0
- cogentrl/nlp/embedding.py +174 -0
- cogentrl/nlp/preprocessing.py +185 -0
- cogentrl/nlp/sentiment.py +8 -0
- cogentrl/nlp/tokenizer.py +8 -0
- cogentrl/nlp/vectorizer.py +224 -0
- cogentrl/utils/__init__.py +4 -0
- cogentrl/utils/helpers.py +11 -0
- cogentrl-0.2.0.dist-info/METADATA +75 -0
- cogentrl-0.2.0.dist-info/RECORD +18 -0
- cogentrl-0.2.0.dist-info/WHEEL +5 -0
- cogentrl-0.2.0.dist-info/licenses/LICENSE.txt +19 -0
- cogentrl-0.2.0.dist-info/top_level.txt +1 -0
cogentrl/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class DecisionAgent:
|
|
5
|
+
def __init__(self, strategy="random"):
|
|
6
|
+
self.strategy = strategy
|
|
7
|
+
|
|
8
|
+
def decide(self, opponent_action=None):
|
|
9
|
+
if self.strategy == "random":
|
|
10
|
+
return "cooperate" if np.random.rand() > 0.5 else "defect"
|
|
11
|
+
elif self.strategy == "tit_for_tat":
|
|
12
|
+
return opponent_action if opponent_action else "cooperate"
|
|
13
|
+
else:
|
|
14
|
+
raise ValueError("Unknown strategy!")
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import torch.nn as nn
|
|
3
|
+
import torch.optim as optim
|
|
4
|
+
import numpy as np
|
|
5
|
+
from collections import deque
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class StrategyBase(nn.Module):
|
|
9
|
+
"""
|
|
10
|
+
Base class for strategies using PyTorch.
|
|
11
|
+
|
|
12
|
+
This serves as a foundation for building various strategies, including neural networks
|
|
13
|
+
and reinforcement learning-based strategies.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, input_dim, hidden_dim, output_dim):
|
|
17
|
+
super(StrategyBase, self).__init__()
|
|
18
|
+
self.fc1 = nn.Linear(input_dim, hidden_dim)
|
|
19
|
+
self.fc2 = nn.Linear(hidden_dim, output_dim)
|
|
20
|
+
|
|
21
|
+
def forward(self, x):
|
|
22
|
+
"""
|
|
23
|
+
Forward pass through the network.
|
|
24
|
+
|
|
25
|
+
Parameters
|
|
26
|
+
----------
|
|
27
|
+
x : torch.Tensor
|
|
28
|
+
Input tensor.
|
|
29
|
+
|
|
30
|
+
Returns
|
|
31
|
+
-------
|
|
32
|
+
torch.Tensor
|
|
33
|
+
Output logits.
|
|
34
|
+
"""
|
|
35
|
+
x = torch.relu(self.fc1(x))
|
|
36
|
+
return self.fc2(x)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class RandomStrategy:
|
|
40
|
+
"""
|
|
41
|
+
Random strategy that selects actions based on a fixed probability distribution.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
def __init__(self, cooperation_prob=0.5):
|
|
45
|
+
self.cooperation_prob = cooperation_prob
|
|
46
|
+
|
|
47
|
+
def decide(self):
|
|
48
|
+
"""
|
|
49
|
+
Decide an action based on a fixed probability distribution.
|
|
50
|
+
|
|
51
|
+
Returns
|
|
52
|
+
-------
|
|
53
|
+
str
|
|
54
|
+
"cooperate" or "defect".
|
|
55
|
+
"""
|
|
56
|
+
return "cooperate" if np.random.rand() < self.cooperation_prob else "defect"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class TitForTatStrategy:
|
|
60
|
+
"""
|
|
61
|
+
Tit-for-tat strategy that mimics the opponent's previous action.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def decide(self, opponent_action=None):
|
|
65
|
+
"""
|
|
66
|
+
Decide an action based on the opponent's previous action.
|
|
67
|
+
|
|
68
|
+
Parameters
|
|
69
|
+
----------
|
|
70
|
+
opponent_action : str, optional
|
|
71
|
+
The opponent's last action.
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
-------
|
|
75
|
+
str
|
|
76
|
+
"cooperate" or "defect".
|
|
77
|
+
"""
|
|
78
|
+
return opponent_action if opponent_action else "cooperate"
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class PolicyGradientStrategy(nn.Module):
|
|
82
|
+
"""
|
|
83
|
+
Policy Gradient strategy implemented using PyTorch.
|
|
84
|
+
|
|
85
|
+
This strategy learns a policy for choosing actions based on a reward signal.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
def __init__(self, input_dim, hidden_dim, action_space):
|
|
89
|
+
super(PolicyGradientStrategy, self).__init__()
|
|
90
|
+
self.fc1 = nn.Linear(input_dim, hidden_dim)
|
|
91
|
+
self.fc2 = nn.Linear(hidden_dim, action_space)
|
|
92
|
+
self.softmax = nn.Softmax(dim=-1)
|
|
93
|
+
|
|
94
|
+
# Reinforcement learning memory
|
|
95
|
+
self.memory = []
|
|
96
|
+
|
|
97
|
+
def forward(self, x):
|
|
98
|
+
"""
|
|
99
|
+
Forward pass through the policy network.
|
|
100
|
+
|
|
101
|
+
Parameters
|
|
102
|
+
----------
|
|
103
|
+
x : torch.Tensor
|
|
104
|
+
Input tensor.
|
|
105
|
+
|
|
106
|
+
Returns
|
|
107
|
+
-------
|
|
108
|
+
torch.Tensor
|
|
109
|
+
Probability distribution over actions.
|
|
110
|
+
"""
|
|
111
|
+
x = torch.relu(self.fc1(x))
|
|
112
|
+
x = self.softmax(self.fc2(x))
|
|
113
|
+
return x
|
|
114
|
+
|
|
115
|
+
def store_transition(self, state, action, reward):
|
|
116
|
+
"""
|
|
117
|
+
Store a transition in memory for policy gradient updates.
|
|
118
|
+
|
|
119
|
+
Parameters
|
|
120
|
+
----------
|
|
121
|
+
state : torch.Tensor
|
|
122
|
+
The state vector.
|
|
123
|
+
action : int
|
|
124
|
+
The action index taken.
|
|
125
|
+
reward : float
|
|
126
|
+
The reward received.
|
|
127
|
+
"""
|
|
128
|
+
self.memory.append((state, action, reward))
|
|
129
|
+
|
|
130
|
+
def compute_returns(self, gamma=0.99):
|
|
131
|
+
"""
|
|
132
|
+
Compute discounted rewards for the stored transitions.
|
|
133
|
+
|
|
134
|
+
Parameters
|
|
135
|
+
----------
|
|
136
|
+
gamma : float
|
|
137
|
+
Discount factor for future rewards.
|
|
138
|
+
|
|
139
|
+
Returns
|
|
140
|
+
-------
|
|
141
|
+
list
|
|
142
|
+
List of discounted rewards.
|
|
143
|
+
"""
|
|
144
|
+
discounted_rewards = []
|
|
145
|
+
cumulative = 0
|
|
146
|
+
for _, _, reward in reversed(self.memory):
|
|
147
|
+
cumulative = reward + gamma * cumulative
|
|
148
|
+
discounted_rewards.insert(0, cumulative)
|
|
149
|
+
return discounted_rewards
|
|
150
|
+
|
|
151
|
+
def train_policy(self, optimizer, gamma=0.99):
|
|
152
|
+
"""
|
|
153
|
+
Train the policy using stored transitions and policy gradient.
|
|
154
|
+
|
|
155
|
+
Parameters
|
|
156
|
+
----------
|
|
157
|
+
optimizer : torch.optim.Optimizer
|
|
158
|
+
Optimizer for updating the policy network.
|
|
159
|
+
gamma : float
|
|
160
|
+
Discount factor for future rewards.
|
|
161
|
+
"""
|
|
162
|
+
if not self.memory:
|
|
163
|
+
return
|
|
164
|
+
|
|
165
|
+
states, actions, rewards = zip(*self.memory)
|
|
166
|
+
states = torch.stack(states)
|
|
167
|
+
actions = torch.tensor(actions)
|
|
168
|
+
returns = torch.tensor(self.compute_returns(gamma))
|
|
169
|
+
|
|
170
|
+
# Normalize returns for better gradient stability
|
|
171
|
+
returns = (returns - returns.mean()) / (returns.std() + 1e-5)
|
|
172
|
+
|
|
173
|
+
optimizer.zero_grad()
|
|
174
|
+
probs = self.forward(states)
|
|
175
|
+
action_probs = probs.gather(1, actions.unsqueeze(1)).squeeze()
|
|
176
|
+
loss = -torch.sum(torch.log(action_probs) * returns)
|
|
177
|
+
loss.backward()
|
|
178
|
+
optimizer.step()
|
|
179
|
+
|
|
180
|
+
# Clear memory
|
|
181
|
+
self.memory = []
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
class AdaptiveStrategy:
|
|
185
|
+
"""
|
|
186
|
+
Adaptive strategy that adjusts its decision logic based on performance.
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
def __init__(self, cooperation_threshold=0.7):
|
|
190
|
+
self.cooperation_threshold = cooperation_threshold
|
|
191
|
+
self.history = deque(maxlen=10)
|
|
192
|
+
|
|
193
|
+
def decide(self, opponent_action=None):
|
|
194
|
+
"""
|
|
195
|
+
Decide an action based on historical performance.
|
|
196
|
+
|
|
197
|
+
Parameters
|
|
198
|
+
----------
|
|
199
|
+
opponent_action : str, optional
|
|
200
|
+
The opponent's last action.
|
|
201
|
+
|
|
202
|
+
Returns
|
|
203
|
+
-------
|
|
204
|
+
str
|
|
205
|
+
"cooperate" or "defect".
|
|
206
|
+
"""
|
|
207
|
+
if len(self.history) < self.history.maxlen:
|
|
208
|
+
return "cooperate" # Default to cooperation initially
|
|
209
|
+
|
|
210
|
+
# Calculate cooperation ratio
|
|
211
|
+
cooperation_ratio = sum(1 for _, op_action in self.history if op_action == "cooperate") / len(self.history)
|
|
212
|
+
return "cooperate" if cooperation_ratio >= self.cooperation_threshold else "defect"
|
|
213
|
+
|
|
214
|
+
def update_history(self, action, opponent_action):
|
|
215
|
+
"""
|
|
216
|
+
Update the history with the latest action pair.
|
|
217
|
+
|
|
218
|
+
Parameters
|
|
219
|
+
----------
|
|
220
|
+
action : str
|
|
221
|
+
The agent's action.
|
|
222
|
+
opponent_action : str
|
|
223
|
+
The opponent's action.
|
|
224
|
+
"""
|
|
225
|
+
self.history.append((action, opponent_action))
|
cogentrl/nlp/__init__.py
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import torch.nn as nn
|
|
3
|
+
from transformers import AutoTokenizer, AutoModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class StaticEmbedding:
|
|
7
|
+
"""
|
|
8
|
+
Handles static embeddings like GloVe or FastText.
|
|
9
|
+
|
|
10
|
+
Parameters
|
|
11
|
+
----------
|
|
12
|
+
embedding_file : str
|
|
13
|
+
Path to the pre-trained embedding file.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, embedding_file):
|
|
17
|
+
self.embedding_file = embedding_file
|
|
18
|
+
self.word_to_index = {}
|
|
19
|
+
self.index_to_vector = []
|
|
20
|
+
|
|
21
|
+
self._load_embeddings()
|
|
22
|
+
|
|
23
|
+
def _load_embeddings(self):
|
|
24
|
+
"""
|
|
25
|
+
Load static embeddings from a file.
|
|
26
|
+
"""
|
|
27
|
+
print(f"Loading embeddings from {self.embedding_file}...")
|
|
28
|
+
with open(self.embedding_file, "r", encoding="utf-8") as f:
|
|
29
|
+
for line in f:
|
|
30
|
+
values = line.split()
|
|
31
|
+
word = values[0]
|
|
32
|
+
vector = torch.tensor([float(x) for x in values[1:]], dtype=torch.float32)
|
|
33
|
+
self.word_to_index[word] = len(self.index_to_vector)
|
|
34
|
+
self.index_to_vector.append(vector)
|
|
35
|
+
self.index_to_vector = torch.stack(self.index_to_vector)
|
|
36
|
+
print(f"Loaded {len(self.word_to_index)} embeddings.")
|
|
37
|
+
|
|
38
|
+
def get_embedding(self, word):
|
|
39
|
+
"""
|
|
40
|
+
Get the embedding for a given word.
|
|
41
|
+
|
|
42
|
+
Parameters
|
|
43
|
+
----------
|
|
44
|
+
word : str
|
|
45
|
+
The word to retrieve the embedding for.
|
|
46
|
+
|
|
47
|
+
Returns
|
|
48
|
+
-------
|
|
49
|
+
torch.Tensor
|
|
50
|
+
The embedding vector.
|
|
51
|
+
"""
|
|
52
|
+
index = self.word_to_index.get(word, None)
|
|
53
|
+
if index is None:
|
|
54
|
+
raise ValueError(f"Word '{word}' not found in the embedding vocabulary.")
|
|
55
|
+
return self.index_to_vector[index]
|
|
56
|
+
|
|
57
|
+
def similarity(self, word1, word2):
|
|
58
|
+
"""
|
|
59
|
+
Compute cosine similarity between two word embeddings.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
word1 : str
|
|
64
|
+
The first word.
|
|
65
|
+
word2 : str
|
|
66
|
+
The second word.
|
|
67
|
+
|
|
68
|
+
Returns
|
|
69
|
+
-------
|
|
70
|
+
float
|
|
71
|
+
Cosine similarity score.
|
|
72
|
+
"""
|
|
73
|
+
embedding1 = self.get_embedding(word1)
|
|
74
|
+
embedding2 = self.get_embedding(word2)
|
|
75
|
+
return torch.nn.functional.cosine_similarity(embedding1.unsqueeze(0), embedding2.unsqueeze(0)).item()
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class ContextualEmbedding:
|
|
79
|
+
"""
|
|
80
|
+
Handles contextual embeddings using transformer models like BERT.
|
|
81
|
+
|
|
82
|
+
Parameters
|
|
83
|
+
----------
|
|
84
|
+
model_name : str
|
|
85
|
+
Name of the transformer model to use.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
def __init__(self, model_name="bert-base-uncased"):
|
|
89
|
+
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
|
|
90
|
+
self.model = AutoModel.from_pretrained(model_name)
|
|
91
|
+
|
|
92
|
+
def get_embedding(self, sentence):
|
|
93
|
+
"""
|
|
94
|
+
Get contextual embeddings for a given sentence.
|
|
95
|
+
|
|
96
|
+
Parameters
|
|
97
|
+
----------
|
|
98
|
+
sentence : str
|
|
99
|
+
The input sentence.
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
torch.Tensor
|
|
104
|
+
The embedding for the sentence.
|
|
105
|
+
"""
|
|
106
|
+
inputs = self.tokenizer(sentence, return_tensors="pt", padding=True, truncation=True)
|
|
107
|
+
outputs = self.model(**inputs)
|
|
108
|
+
# Return the CLS token's embedding
|
|
109
|
+
return outputs.last_hidden_state[:, 0, :]
|
|
110
|
+
|
|
111
|
+
def sentence_similarity(self, sentence1, sentence2):
|
|
112
|
+
"""
|
|
113
|
+
Compute cosine similarity between two sentence embeddings.
|
|
114
|
+
|
|
115
|
+
Parameters
|
|
116
|
+
----------
|
|
117
|
+
sentence1 : str
|
|
118
|
+
The first sentence.
|
|
119
|
+
sentence2 : str
|
|
120
|
+
The second sentence.
|
|
121
|
+
|
|
122
|
+
Returns
|
|
123
|
+
-------
|
|
124
|
+
float
|
|
125
|
+
Cosine similarity score.
|
|
126
|
+
"""
|
|
127
|
+
embedding1 = self.get_embedding(sentence1)
|
|
128
|
+
embedding2 = self.get_embedding(sentence2)
|
|
129
|
+
return torch.nn.functional.cosine_similarity(embedding1, embedding2).item()
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class CustomEmbedding(nn.Module):
|
|
133
|
+
"""
|
|
134
|
+
Custom embedding layer for specific NLP tasks.
|
|
135
|
+
|
|
136
|
+
Parameters
|
|
137
|
+
----------
|
|
138
|
+
vocab_size : int
|
|
139
|
+
Size of the vocabulary.
|
|
140
|
+
embedding_dim : int
|
|
141
|
+
Dimension of the embeddings.
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
def __init__(self, vocab_size, embedding_dim):
|
|
145
|
+
super(CustomEmbedding, self).__init__()
|
|
146
|
+
self.embedding = nn.Embedding(vocab_size, embedding_dim)
|
|
147
|
+
|
|
148
|
+
def forward(self, input_ids):
|
|
149
|
+
"""
|
|
150
|
+
Forward pass to retrieve embeddings for input IDs.
|
|
151
|
+
|
|
152
|
+
Parameters
|
|
153
|
+
----------
|
|
154
|
+
input_ids : torch.Tensor
|
|
155
|
+
Tensor of input token IDs.
|
|
156
|
+
|
|
157
|
+
Returns
|
|
158
|
+
-------
|
|
159
|
+
torch.Tensor
|
|
160
|
+
Embedding vectors.
|
|
161
|
+
"""
|
|
162
|
+
return self.embedding(input_ids)
|
|
163
|
+
|
|
164
|
+
def freeze_embeddings(self):
|
|
165
|
+
"""
|
|
166
|
+
Freeze the embedding weights (useful for fine-tuning).
|
|
167
|
+
"""
|
|
168
|
+
self.embedding.weight.requires_grad = False
|
|
169
|
+
|
|
170
|
+
def unfreeze_embeddings(self):
|
|
171
|
+
"""
|
|
172
|
+
Unfreeze the embedding weights.
|
|
173
|
+
"""
|
|
174
|
+
self.embedding.weight.requires_grad = True
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
from transformers import AutoTokenizer
|
|
3
|
+
from sklearn.model_selection import train_test_split
|
|
4
|
+
import re
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TextPreprocessor:
|
|
9
|
+
"""
|
|
10
|
+
Handles text preprocessing tasks, including cleaning, tokenization, and batching.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, model_name="bert-base-uncased", max_length=128):
|
|
14
|
+
"""
|
|
15
|
+
Initialize the TextPreprocessor with a tokenizer and max sequence length.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
model_name : str
|
|
20
|
+
Name of the transformer model tokenizer.
|
|
21
|
+
max_length : int
|
|
22
|
+
Maximum sequence length for tokenization.
|
|
23
|
+
"""
|
|
24
|
+
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
|
|
25
|
+
self.max_length = max_length
|
|
26
|
+
|
|
27
|
+
def clean_text(self, text):
|
|
28
|
+
"""
|
|
29
|
+
Cleans the input text by removing special characters and extra spaces.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
text : str
|
|
34
|
+
The input text.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
str
|
|
39
|
+
The cleaned text.
|
|
40
|
+
"""
|
|
41
|
+
text = text.lower()
|
|
42
|
+
text = re.sub(r"[^a-zA-Z0-9\s]", "", text)
|
|
43
|
+
text = re.sub(r"\s+", " ", text).strip()
|
|
44
|
+
return text
|
|
45
|
+
|
|
46
|
+
def tokenize(self, texts):
|
|
47
|
+
"""
|
|
48
|
+
Tokenize and encode a list of texts using the tokenizer.
|
|
49
|
+
|
|
50
|
+
Parameters
|
|
51
|
+
----------
|
|
52
|
+
texts : list of str
|
|
53
|
+
List of input texts.
|
|
54
|
+
|
|
55
|
+
Returns
|
|
56
|
+
-------
|
|
57
|
+
dict
|
|
58
|
+
Tokenized output with input IDs and attention masks.
|
|
59
|
+
"""
|
|
60
|
+
return self.tokenizer(
|
|
61
|
+
texts,
|
|
62
|
+
max_length=self.max_length,
|
|
63
|
+
padding="max_length",
|
|
64
|
+
truncation=True,
|
|
65
|
+
return_tensors="pt"
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
def preprocess(self, texts):
|
|
69
|
+
"""
|
|
70
|
+
Clean and tokenize input texts.
|
|
71
|
+
|
|
72
|
+
Parameters
|
|
73
|
+
----------
|
|
74
|
+
texts : list of str
|
|
75
|
+
List of input texts.
|
|
76
|
+
|
|
77
|
+
Returns
|
|
78
|
+
-------
|
|
79
|
+
dict
|
|
80
|
+
Preprocessed data with input IDs and attention masks.
|
|
81
|
+
"""
|
|
82
|
+
cleaned_texts = [self.clean_text(text) for text in texts]
|
|
83
|
+
return self.tokenize(cleaned_texts)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class DataBatcher:
|
|
87
|
+
"""
|
|
88
|
+
Handles batching and preparing data for deep learning models.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
def __init__(self, batch_size=32):
|
|
92
|
+
"""
|
|
93
|
+
Initialize the DataBatcher with a specified batch size.
|
|
94
|
+
|
|
95
|
+
Parameters
|
|
96
|
+
----------
|
|
97
|
+
batch_size : int
|
|
98
|
+
Number of samples per batch.
|
|
99
|
+
"""
|
|
100
|
+
self.batch_size = batch_size
|
|
101
|
+
|
|
102
|
+
def create_batches(self, input_ids, attention_masks, labels=None):
|
|
103
|
+
"""
|
|
104
|
+
Create batches from tokenized input data and labels.
|
|
105
|
+
|
|
106
|
+
Parameters
|
|
107
|
+
----------
|
|
108
|
+
input_ids : torch.Tensor
|
|
109
|
+
Tokenized input IDs.
|
|
110
|
+
attention_masks : torch.Tensor
|
|
111
|
+
Attention masks corresponding to the input IDs.
|
|
112
|
+
labels : torch.Tensor, optional
|
|
113
|
+
Labels for the input data.
|
|
114
|
+
|
|
115
|
+
Returns
|
|
116
|
+
-------
|
|
117
|
+
list of dict
|
|
118
|
+
List of batches containing input IDs, attention masks, and labels.
|
|
119
|
+
"""
|
|
120
|
+
dataset = []
|
|
121
|
+
for i in range(0, len(input_ids), self.batch_size):
|
|
122
|
+
batch = {
|
|
123
|
+
"input_ids": input_ids[i:i + self.batch_size],
|
|
124
|
+
"attention_masks": attention_masks[i:i + self.batch_size],
|
|
125
|
+
}
|
|
126
|
+
if labels is not None:
|
|
127
|
+
batch["labels"] = labels[i:i + self.batch_size]
|
|
128
|
+
dataset.append(batch)
|
|
129
|
+
return dataset
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def split_data(input_texts, labels, test_size=0.2):
|
|
133
|
+
"""
|
|
134
|
+
Split data into training and testing sets.
|
|
135
|
+
|
|
136
|
+
Parameters
|
|
137
|
+
----------
|
|
138
|
+
input_texts : list of str
|
|
139
|
+
List of input texts.
|
|
140
|
+
labels : list
|
|
141
|
+
List of labels corresponding to the input texts.
|
|
142
|
+
test_size : float
|
|
143
|
+
Fraction of data to be used for testing.
|
|
144
|
+
|
|
145
|
+
Returns
|
|
146
|
+
-------
|
|
147
|
+
tuple
|
|
148
|
+
Training and testing sets (texts and labels).
|
|
149
|
+
"""
|
|
150
|
+
return train_test_split(input_texts, labels, test_size=test_size, random_state=42)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class EmbeddingGenerator:
|
|
154
|
+
"""
|
|
155
|
+
Generates embeddings for input texts using a transformer model.
|
|
156
|
+
|
|
157
|
+
Parameters
|
|
158
|
+
----------
|
|
159
|
+
model_name : str
|
|
160
|
+
Name of the transformer model to use.
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
def __init__(self, model_name="bert-base-uncased"):
|
|
164
|
+
from transformers import AutoModel
|
|
165
|
+
self.model = AutoModel.from_pretrained(model_name)
|
|
166
|
+
|
|
167
|
+
def generate_embeddings(self, input_ids, attention_masks):
|
|
168
|
+
"""
|
|
169
|
+
Generate embeddings for input texts.
|
|
170
|
+
|
|
171
|
+
Parameters
|
|
172
|
+
----------
|
|
173
|
+
input_ids : torch.Tensor
|
|
174
|
+
Tokenized input IDs.
|
|
175
|
+
attention_masks : torch.Tensor
|
|
176
|
+
Attention masks corresponding to the input IDs.
|
|
177
|
+
|
|
178
|
+
Returns
|
|
179
|
+
-------
|
|
180
|
+
torch.Tensor
|
|
181
|
+
Generated embeddings.
|
|
182
|
+
"""
|
|
183
|
+
with torch.no_grad():
|
|
184
|
+
outputs = self.model(input_ids=input_ids, attention_mask=attention_masks)
|
|
185
|
+
return outputs.last_hidden_state[:, 0, :] # CLS token embeddings
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import torch.nn as nn
|
|
3
|
+
from transformers import AutoTokenizer, AutoModel
|
|
4
|
+
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BagOfWordsVectorizer:
|
|
9
|
+
"""
|
|
10
|
+
Bag of Words (BoW) vectorizer for text data.
|
|
11
|
+
|
|
12
|
+
Parameters
|
|
13
|
+
----------
|
|
14
|
+
max_features : int, optional
|
|
15
|
+
Maximum number of features to consider. Default is 5000.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, max_features=5000):
|
|
19
|
+
self.vectorizer = CountVectorizer(max_features=max_features)
|
|
20
|
+
|
|
21
|
+
def fit_transform(self, texts):
|
|
22
|
+
"""
|
|
23
|
+
Fits the vectorizer on texts and transforms them into feature vectors.
|
|
24
|
+
|
|
25
|
+
Parameters
|
|
26
|
+
----------
|
|
27
|
+
texts : list of str
|
|
28
|
+
List of input texts.
|
|
29
|
+
|
|
30
|
+
Returns
|
|
31
|
+
-------
|
|
32
|
+
np.ndarray
|
|
33
|
+
Bag of Words feature matrix.
|
|
34
|
+
"""
|
|
35
|
+
return self.vectorizer.fit_transform(texts).toarray()
|
|
36
|
+
|
|
37
|
+
def transform(self, texts):
|
|
38
|
+
"""
|
|
39
|
+
Transforms texts into feature vectors using a fitted vectorizer.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
texts : list of str
|
|
44
|
+
List of input texts.
|
|
45
|
+
|
|
46
|
+
Returns
|
|
47
|
+
-------
|
|
48
|
+
np.ndarray
|
|
49
|
+
Bag of Words feature matrix.
|
|
50
|
+
"""
|
|
51
|
+
return self.vectorizer.transform(texts).toarray()
|
|
52
|
+
|
|
53
|
+
def feature_names(self):
|
|
54
|
+
"""
|
|
55
|
+
Returns the feature names extracted by the vectorizer.
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
list of str
|
|
60
|
+
List of feature names.
|
|
61
|
+
"""
|
|
62
|
+
return self.vectorizer.get_feature_names_out()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class TfidfVectorizerWrapper:
|
|
66
|
+
"""
|
|
67
|
+
TF-IDF vectorizer for text data.
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
max_features : int, optional
|
|
72
|
+
Maximum number of features to consider. Default is 5000.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
def __init__(self, max_features=5000):
|
|
76
|
+
self.vectorizer = TfidfVectorizer(max_features=max_features)
|
|
77
|
+
|
|
78
|
+
def fit_transform(self, texts):
|
|
79
|
+
"""
|
|
80
|
+
Fits the vectorizer on texts and transforms them into TF-IDF vectors.
|
|
81
|
+
|
|
82
|
+
Parameters
|
|
83
|
+
----------
|
|
84
|
+
texts : list of str
|
|
85
|
+
List of input texts.
|
|
86
|
+
|
|
87
|
+
Returns
|
|
88
|
+
-------
|
|
89
|
+
np.ndarray
|
|
90
|
+
TF-IDF feature matrix.
|
|
91
|
+
"""
|
|
92
|
+
return self.vectorizer.fit_transform(texts).toarray()
|
|
93
|
+
|
|
94
|
+
def transform(self, texts):
|
|
95
|
+
"""
|
|
96
|
+
Transforms texts into TF-IDF vectors using a fitted vectorizer.
|
|
97
|
+
|
|
98
|
+
Parameters
|
|
99
|
+
----------
|
|
100
|
+
texts : list of str
|
|
101
|
+
List of input texts.
|
|
102
|
+
|
|
103
|
+
Returns
|
|
104
|
+
-------
|
|
105
|
+
np.ndarray
|
|
106
|
+
TF-IDF feature matrix.
|
|
107
|
+
"""
|
|
108
|
+
return self.vectorizer.transform(texts).toarray()
|
|
109
|
+
|
|
110
|
+
def feature_names(self):
|
|
111
|
+
"""
|
|
112
|
+
Returns the feature names extracted by the vectorizer.
|
|
113
|
+
|
|
114
|
+
Returns
|
|
115
|
+
-------
|
|
116
|
+
list of str
|
|
117
|
+
List of feature names.
|
|
118
|
+
"""
|
|
119
|
+
return self.vectorizer.get_feature_names_out()
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class EmbeddingVectorizer:
|
|
123
|
+
"""
|
|
124
|
+
Embedding-based vectorizer using pre-trained transformer models.
|
|
125
|
+
|
|
126
|
+
Parameters
|
|
127
|
+
----------
|
|
128
|
+
model_name : str
|
|
129
|
+
Name of the transformer model to use.
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
def __init__(self, model_name="bert-base-uncased"):
|
|
133
|
+
self.tokenizer = AutoTokenizer.from_pretrained(model_name)
|
|
134
|
+
self.model = AutoModel.from_pretrained(model_name)
|
|
135
|
+
|
|
136
|
+
def vectorize(self, texts):
|
|
137
|
+
"""
|
|
138
|
+
Generates embeddings for input texts.
|
|
139
|
+
|
|
140
|
+
Parameters
|
|
141
|
+
----------
|
|
142
|
+
texts : list of str
|
|
143
|
+
List of input texts.
|
|
144
|
+
|
|
145
|
+
Returns
|
|
146
|
+
-------
|
|
147
|
+
torch.Tensor
|
|
148
|
+
Embedding matrix for input texts.
|
|
149
|
+
"""
|
|
150
|
+
embeddings = []
|
|
151
|
+
for text in texts:
|
|
152
|
+
inputs = self.tokenizer(text, return_tensors="pt", padding=True, truncation=True)
|
|
153
|
+
with torch.no_grad():
|
|
154
|
+
outputs = self.model(**inputs)
|
|
155
|
+
embeddings.append(outputs.last_hidden_state[:, 0, :]) # CLS token
|
|
156
|
+
return torch.cat(embeddings, dim=0)
|
|
157
|
+
|
|
158
|
+
def batch_vectorize(self, texts, batch_size=8):
|
|
159
|
+
"""
|
|
160
|
+
Generates embeddings for input texts in batches.
|
|
161
|
+
|
|
162
|
+
Parameters
|
|
163
|
+
----------
|
|
164
|
+
texts : list of str
|
|
165
|
+
List of input texts.
|
|
166
|
+
batch_size : int
|
|
167
|
+
Size of each batch.
|
|
168
|
+
|
|
169
|
+
Returns
|
|
170
|
+
-------
|
|
171
|
+
torch.Tensor
|
|
172
|
+
Embedding matrix for input texts.
|
|
173
|
+
"""
|
|
174
|
+
embeddings = []
|
|
175
|
+
for i in range(0, len(texts), batch_size):
|
|
176
|
+
batch_texts = texts[i:i + batch_size]
|
|
177
|
+
inputs = self.tokenizer(batch_texts, return_tensors="pt", padding=True, truncation=True)
|
|
178
|
+
with torch.no_grad():
|
|
179
|
+
outputs = self.model(**inputs)
|
|
180
|
+
embeddings.append(outputs.last_hidden_state[:, 0, :])
|
|
181
|
+
return torch.cat(embeddings, dim=0)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
class CombinedVectorizer:
|
|
185
|
+
"""
|
|
186
|
+
Combines Bag of Words, TF-IDF, and Embedding vectorizers.
|
|
187
|
+
|
|
188
|
+
Parameters
|
|
189
|
+
----------
|
|
190
|
+
bow_max_features : int, optional
|
|
191
|
+
Maximum number of features for Bag of Words. Default is 5000.
|
|
192
|
+
tfidf_max_features : int, optional
|
|
193
|
+
Maximum number of features for TF-IDF. Default is 5000.
|
|
194
|
+
model_name : str, optional
|
|
195
|
+
Transformer model for embeddings. Default is "bert-base-uncased".
|
|
196
|
+
"""
|
|
197
|
+
|
|
198
|
+
def __init__(self, bow_max_features=5000, tfidf_max_features=5000, model_name="bert-base-uncased"):
|
|
199
|
+
self.bow_vectorizer = BagOfWordsVectorizer(max_features=bow_max_features)
|
|
200
|
+
self.tfidf_vectorizer = TfidfVectorizerWrapper(max_features=tfidf_max_features)
|
|
201
|
+
self.embedding_vectorizer = EmbeddingVectorizer(model_name=model_name)
|
|
202
|
+
|
|
203
|
+
def fit_transform(self, texts):
|
|
204
|
+
"""
|
|
205
|
+
Fits and transforms texts using all vectorizers.
|
|
206
|
+
|
|
207
|
+
Parameters
|
|
208
|
+
----------
|
|
209
|
+
texts : list of str
|
|
210
|
+
List of input texts.
|
|
211
|
+
|
|
212
|
+
Returns
|
|
213
|
+
-------
|
|
214
|
+
dict
|
|
215
|
+
Combined feature matrices from all vectorizers.
|
|
216
|
+
"""
|
|
217
|
+
bow_features = self.bow_vectorizer.fit_transform(texts)
|
|
218
|
+
tfidf_features = self.tfidf_vectorizer.fit_transform(texts)
|
|
219
|
+
embedding_features = self.embedding_vectorizer.vectorize(texts)
|
|
220
|
+
return {
|
|
221
|
+
"bow": bow_features,
|
|
222
|
+
"tfidf": tfidf_features,
|
|
223
|
+
"embeddings": embedding_features
|
|
224
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cogentrl
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: star AI: Tools for decision-making and NLP.
|
|
5
|
+
Author: Mathis Daviau
|
|
6
|
+
Classifier: Development Status :: 4 - Beta
|
|
7
|
+
Classifier: Intended Audience :: Developers
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Requires-Python: >=3.7
|
|
15
|
+
Description-Content-Type: text/x-rst
|
|
16
|
+
License-File: LICENSE.txt
|
|
17
|
+
Requires-Dist: numpy>=1.21.0
|
|
18
|
+
Requires-Dist: matplotlib>=3.4.0
|
|
19
|
+
Requires-Dist: torch>=1.9.0
|
|
20
|
+
Requires-Dist: transformers>=4.0.0
|
|
21
|
+
Requires-Dist: scikit-learn>=0.24.0
|
|
22
|
+
Requires-Dist: pyyaml>=5.4.0
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=6.2.0; extra == "dev"
|
|
25
|
+
Requires-Dist: flake8>=3.9.0; extra == "dev"
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
Dynamic: requires-python
|
|
28
|
+
|
|
29
|
+
star AI
|
|
30
|
+
=======
|
|
31
|
+
|
|
32
|
+
star AI is a Python package that bridges decision-making and natural language processing, inspired by intelligent behavior.
|
|
33
|
+
|
|
34
|
+
Features
|
|
35
|
+
--------
|
|
36
|
+
|
|
37
|
+
- **Decision-Making Models**
|
|
38
|
+
- Game-theoretic strategies (e.g., tit-for-tat).
|
|
39
|
+
- Multi-agent simulations.
|
|
40
|
+
- Reinforcement learning agents.
|
|
41
|
+
|
|
42
|
+
- **Natural Language Processing**
|
|
43
|
+
- Sentiment analysis.
|
|
44
|
+
- Tokenization and text similarity.
|
|
45
|
+
- Language evolution simulation.
|
|
46
|
+
|
|
47
|
+
Installation
|
|
48
|
+
------------
|
|
49
|
+
|
|
50
|
+
You can install the package via pip::
|
|
51
|
+
|
|
52
|
+
pip install star
|
|
53
|
+
|
|
54
|
+
Quick Start
|
|
55
|
+
-----------
|
|
56
|
+
|
|
57
|
+
Example usage:
|
|
58
|
+
|
|
59
|
+
.. code-block:: python
|
|
60
|
+
|
|
61
|
+
# Decision Agent
|
|
62
|
+
from star.decision.agent import DecisionAgent
|
|
63
|
+
agent = DecisionAgent(strategy="tit_for_tat")
|
|
64
|
+
decision = agent.decide(opponent_action="cooperate")
|
|
65
|
+
print(f"Agent decided to: {decision}")
|
|
66
|
+
|
|
67
|
+
# Sentiment Analysis
|
|
68
|
+
from star.nlp.sentiment import SentimentAnalyzer
|
|
69
|
+
analyzer = SentimentAnalyzer()
|
|
70
|
+
print(analyzer.analyze("I love bananas!")) # Output: "positive"
|
|
71
|
+
|
|
72
|
+
License
|
|
73
|
+
-------
|
|
74
|
+
|
|
75
|
+
This project is licensed under the MIT License.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
cogentrl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
cogentrl/decision/__init__.py,sha256=P4tJ0cO7GmknNvNA9z0s8ph-A0CI7meRCgxZT8w7O3o,222
|
|
3
|
+
cogentrl/decision/agent.py,sha256=VE8m6xpevWlNWZ_k7FPJauPSSM50pKQGyb6u-PUebO0,452
|
|
4
|
+
cogentrl/decision/environment.py,sha256=ch6-cufjGMyICMk6XfTkGChkBxY3mBZqZYpk6hr5dfo,254
|
|
5
|
+
cogentrl/decision/strategy.py,sha256=iwbeL4fKSGUIdA0We9ixe1-ec_Pvp3L4ZeatDq4__H0,6126
|
|
6
|
+
cogentrl/nlp/__init__.py,sha256=VIh1_NeSsFTJQD2YpsIyCEo97dpM6PLhCoh1WqUa3N0,134
|
|
7
|
+
cogentrl/nlp/embedding.py,sha256=__KiC72IKW8ORyeq8bZI1Vixh3a2pocJga8OgXPaeMU,4800
|
|
8
|
+
cogentrl/nlp/preprocessing.py,sha256=AwuW8wpMEy5A5fVFiGmZ2BwBf_fvKqIE0Yo6PQPl1_E,5007
|
|
9
|
+
cogentrl/nlp/sentiment.py,sha256=c-VeEgXFFMOzCEOXQEG0yfnwZNRdY4Oh1byXnuRkGBA,249
|
|
10
|
+
cogentrl/nlp/tokenizer.py,sha256=gAkGAyeM609JpkrgZXULUxSjgVFNVvxxS532ineEHXc,252
|
|
11
|
+
cogentrl/nlp/vectorizer.py,sha256=Om0U1vPDYtakIwpLljCLXGJmnaPhQ2HXKwh42FP4nCo,6242
|
|
12
|
+
cogentrl/utils/__init__.py,sha256=VXp_I7dSpQ21M-bZPFPC4kq2xoiRtwrILdxIYusWf4o,82
|
|
13
|
+
cogentrl/utils/helpers.py,sha256=24k8wTHUM-OAgcjUqjszIdPVhm5wSuJ0DZTVK7DkGqQ,267
|
|
14
|
+
cogentrl-0.2.0.dist-info/licenses/LICENSE.txt,sha256=UIp30ue1HZit7tMmSK0SS3swJBqOcLLnLJn5LY5YdNE,1036
|
|
15
|
+
cogentrl-0.2.0.dist-info/METADATA,sha256=TdNdORr5uvESLF5T_nvhGmuZXCim4IyCAxLVisSORhA,2005
|
|
16
|
+
cogentrl-0.2.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
17
|
+
cogentrl-0.2.0.dist-info/top_level.txt,sha256=zkWqXSvJx9OXzrfrFovTU4YLLlO4d0OSUumVuXpwzPo,9
|
|
18
|
+
cogentrl-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cogentrl
|