jester6136
commited on
Commit
•
3edacb2
1
Parent(s):
9c80216
Update README.md
Browse files
README.md
CHANGED
@@ -110,35 +110,86 @@ This [Model2Vec](https://github.com/MinishLab/model2vec) model is a distilled ve
|
|
110 |
|
111 |
## Installation
|
112 |
|
113 |
-
Install
|
114 |
```
|
115 |
-
pip install model2vec
|
116 |
```
|
117 |
|
118 |
## Usage
|
119 |
-
Load this model using the `from_pretrained` method:
|
120 |
-
```python
|
121 |
-
from model2vec import StaticModel
|
122 |
-
|
123 |
-
# Load a pretrained Model2Vec model
|
124 |
-
model = StaticModel.from_pretrained("jester6136/multilingual-e5-large-m2v")
|
125 |
-
|
126 |
-
# Compute text embeddings
|
127 |
-
embeddings = model.encode(["Example sentence"])
|
128 |
```
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
from
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
#
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
```
|
143 |
|
144 |
## How it works
|
|
|
110 |
|
111 |
## Installation
|
112 |
|
113 |
+
Install using pip:
|
114 |
```
|
115 |
+
pip install model2vec reach tqdm numpy
|
116 |
```
|
117 |
|
118 |
## Usage
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
```
|
120 |
+
import numpy as np
|
121 |
+
from model2vec import StaticModel
|
122 |
+
from reach import Reach
|
123 |
+
from tqdm import tqdm
|
124 |
+
import time
|
125 |
+
|
126 |
+
class TextDeduplicator:
|
127 |
+
def __init__(self, model_path: str):
|
128 |
+
# Load the pre-trained model
|
129 |
+
self.model = StaticModel.from_pretrained(model_path)
|
130 |
+
|
131 |
+
def encode_texts(self, texts: list[str]) -> np.ndarray:
|
132 |
+
# Prepare the texts and encode them into embeddings
|
133 |
+
texts = [f"query: {text}" for text in texts]
|
134 |
+
embedding_matrix = self.model.encode(texts, show_progressbar=True)
|
135 |
+
return embedding_matrix
|
136 |
+
|
137 |
+
def deduplicate(self, embedding_matrix: np.ndarray, threshold: float, batch_size: int = 1024
|
138 |
+
) -> tuple[np.ndarray, dict[int, list[int]]]:
|
139 |
+
# Deduplicate the texts based on their embeddings
|
140 |
+
reach = Reach(vectors=embedding_matrix, items=[str(i) for i in range(len(embedding_matrix))])
|
141 |
+
results = reach.nearest_neighbor_threshold(
|
142 |
+
embedding_matrix, threshold=threshold, batch_size=batch_size, show_progressbar=True
|
143 |
+
)
|
144 |
+
|
145 |
+
deduplicated_indices = set(range(len(embedding_matrix)))
|
146 |
+
duplicate_groups = {}
|
147 |
+
|
148 |
+
for i, similar_items in enumerate(tqdm(results)):
|
149 |
+
if i not in deduplicated_indices:
|
150 |
+
continue
|
151 |
+
|
152 |
+
similar_indices = [int(item[0]) for item in similar_items if int(item[0]) != i]
|
153 |
+
for sim_idx in similar_indices:
|
154 |
+
if sim_idx in deduplicated_indices:
|
155 |
+
deduplicated_indices.remove(sim_idx)
|
156 |
+
if i not in duplicate_groups:
|
157 |
+
duplicate_groups[i] = []
|
158 |
+
duplicate_groups[i].append(sim_idx)
|
159 |
+
|
160 |
+
return np.array(list(deduplicated_indices)), duplicate_groups
|
161 |
+
|
162 |
+
def deduplicate_texts(self, texts: list[str], threshold: float) -> tuple[np.ndarray, dict[int, list[int]]]:
|
163 |
+
# End-to-end deduplication process
|
164 |
+
embedding_matrix = self.encode_texts(texts)
|
165 |
+
return self.deduplicate(embedding_matrix, threshold)
|
166 |
+
|
167 |
+
|
168 |
+
if __name__ == "__main__":
|
169 |
+
# Example usage
|
170 |
+
texts = [
|
171 |
+
"Anh yêu em.",
|
172 |
+
"Mọi thứ ở công ty mới đều lạ lẫm, nhưng tôi cảm thấy rất sẵn sàng để bắt đầu hành trình mới.",
|
173 |
+
"Trận đấu bóng đá tối qua rất căng thẳng, hai đội liên tục tấn công và phòng thủ.",
|
174 |
+
"Một quan chức Fed muốn giảm bớt tốc độ hạ lãi suất",
|
175 |
+
"Ngày đầu tiên tại công ty mới đầy ấn tượng, tôi hy vọng sẽ nhanh chóng hòa nhập với môi trường làm việc.",
|
176 |
+
"Mùa hè này, cả gia đình sẽ có một chuyến đi đến Đà Nẵng, nơi mà chúng tôi đã mong chờ từ rất lâu.",
|
177 |
+
"Gia đình tôi đã lên kế hoạch cho kỳ nghỉ tại Đà Nẵng vào mùa hè này, một chuyến đi mà mọi người đều háo hức.",
|
178 |
+
"Fed có bước tiến mới để hạ lãi suất",
|
179 |
+
"Chúng tôi đã dự định từ lâu sẽ đi Đà Nẵng vào mùa hè này, và cả nhà đều rất trông đợi chuyến du lịch.",
|
180 |
+
"Ngày đầu đi làm thật là thú vị, tuy có chút hồi hộp nhưng tôi mong chờ những điều mới mẻ.",
|
181 |
+
"Mùa hè năm nay, gia đình tôi sẽ du lịch Đà Nẵng, chuyến đi mà ai cũng mong đợi từ trước."
|
182 |
+
]
|
183 |
+
|
184 |
+
deduplicator = TextDeduplicator("jester6136/multilingual-e5-large-m2v")
|
185 |
+
|
186 |
+
start_time = time.time()
|
187 |
+
deduplicated_indices, duplicate_groups = deduplicator.deduplicate_texts(texts, threshold=0.85)
|
188 |
+
end_time = time.time()
|
189 |
+
|
190 |
+
print(f"Deduplication completed in {end_time - start_time:.2f} seconds")
|
191 |
+
print(f"Deduped output: {deduplicated_indices}")
|
192 |
+
print(f"Group dup: {duplicate_groups}")
|
193 |
```
|
194 |
|
195 |
## How it works
|