initial code and data
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- code/fasttext_embeddings.py +172 -0
- code/prepare_corpus.py +109 -0
- code/word2vec_embeddings.py +84 -0
- data/kananda_kasturi_kasthruriapril190000unse.txt +0 -0
- data/kananda_kasturi_kasthruriapril190000unse_z9j1.txt +0 -0
- data/kananda_kasturi_kasthuriapr19910000ksha.txt +0 -0
- data/kananda_kasturi_kasthuriapril1970000unse.txt +0 -0
- data/kananda_kasturi_kasthuriaug19910000ksha.txt +0 -0
- data/kananda_kasturi_kasthuriaug19920000ksha.txt +0 -0
- data/kananda_kasturi_kasthuriaugust190000unse.txt +0 -0
- data/kananda_kasturi_kasthuriaugust190000unse_l2t1.txt +0 -0
- data/kananda_kasturi_kasthuriaugust190000unse_v2e9.txt +0 -0
- data/kananda_kasturi_kasthuridec19860000unse.txt +0 -0
- data/kananda_kasturi_kasthuridec19870000unse.txt +0 -0
- data/kananda_kasturi_kasthuridec19880000unse.txt +0 -0
- data/kananda_kasturi_kasthuridec19910000ksha.txt +0 -0
- data/kananda_kasturi_kasthuridecember0000unse.txt +0 -0
- data/kananda_kasturi_kasthuridecember0000unse_j1v3.txt +0 -0
- data/kananda_kasturi_kasthurifeb19770000unse.txt +0 -0
- data/kananda_kasturi_kasthurifeb19870000unse.txt +0 -0
- data/kananda_kasturi_kasthurifebrury10000unse.txt +0 -0
- data/kananda_kasturi_kasthurifebrury10000unse_v7l3.txt +0 -0
- data/kananda_kasturi_kasthurijan19870000unse.txt +0 -0
- data/kananda_kasturi_kasthurijan19910000ksha.txt +0 -0
- data/kananda_kasturi_kasthurijuly19580000unse.txt +0 -0
- data/kananda_kasturi_kasthurijuly19610000unse.txt +0 -0
- data/kananda_kasturi_kasthurijuly19620000unse.txt +0 -0
- data/kananda_kasturi_kasthurijune19610000unse.txt +0 -0
- data/kananda_kasturi_kasthurijune19620000unse.txt +0 -0
- data/kananda_kasturi_kasthurijune19770000unse.txt +0 -0
- data/kananda_kasturi_kasthurijune19910000ksha.txt +0 -0
- data/kananda_kasturi_kasthurimarch1960000unse.txt +0 -0
- data/kananda_kasturi_kasthurimarch1960000unse_e2x6.txt +0 -0
- data/kananda_kasturi_kasthurimarch1960000unse_r5s9.txt +0 -0
- data/kananda_kasturi_kasthurimarch1970000unse.txt +0 -0
- data/kananda_kasturi_kasthurimarch1990000ksha.txt +0 -0
- data/kananda_kasturi_kasthurimay19610000unse.txt +0 -0
- data/kananda_kasturi_kasthurimay19620000unse.txt +0 -0
- data/kananda_kasturi_kasthurimay19770000unse.txt +0 -0
- data/kananda_kasturi_kasthurimay19910000ksha.txt +0 -0
- data/kananda_kasturi_kasthurimay19920000ksha.txt +0 -0
- data/kananda_kasturi_kasthurinov19780000unse.txt +0 -0
- data/kananda_kasturi_kasthurinov19860000unse.txt +0 -0
- data/kananda_kasturi_kasthurinov19880000unse.txt +0 -0
- data/kananda_kasturi_kasthurinov19900000ksha.txt +0 -0
- data/kananda_kasturi_kasthurinovember0000unse.txt +0 -0
- data/kananda_kasturi_kasthurinovember0000unse_g4q6.txt +0 -0
- data/kananda_kasturi_kasthurioct19880000unse.txt +0 -0
- data/kananda_kasturi_kasthurioctober10000ksha_n8d0.txt +0 -0
- data/kananda_kasturi_kasthurioctober10000ksha_q4i6.txt +0 -0
code/fasttext_embeddings.py
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env -S uv run
|
| 2 |
+
# /// script
|
| 3 |
+
# dependencies = ["fasttext", "matplotlib","numpy"]
|
| 4 |
+
# ///
|
| 5 |
+
|
| 6 |
+
# uv run fasttext_embeddings.py train ./corpus.txt --recursive --out ../models/kasturi_fasttext_v4
|
| 7 |
+
# uv run fasttext_embeddings.py test ../models/kasturi_fasttext_v4.bin --word ಕನ್ನಡ
|
| 8 |
+
# uv run fasttext_embeddings.py test ../models/kasturi_fasttext_v4.bin --word ರಾಜಧಾನಿ
|
| 9 |
+
# uv run fasttext_embeddings.py test ../models/kasturi_fasttext_v4.bin --sentence "ಬೆಂಗಳೂರು ಕರ್ನಾಟಕದ ರಾಜಧಾನಿ"
|
| 10 |
+
# uv run fasttext_embeddings.py compare ../models/kasturi_fasttext_v4.bin
|
| 11 |
+
|
| 12 |
+
import argparse
|
| 13 |
+
from pathlib import Path
|
| 14 |
+
|
| 15 |
+
import fasttext
|
| 16 |
+
import matplotlib.pyplot as plt
|
| 17 |
+
import numpy as np
|
| 18 |
+
from matplotlib import font_manager
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def setup_kannada_font():
|
| 22 |
+
candidates = [
|
| 23 |
+
"Noto Sans Kannada",
|
| 24 |
+
"Noto Serif Kannada",
|
| 25 |
+
"Lohit Kannada",
|
| 26 |
+
]
|
| 27 |
+
|
| 28 |
+
available = {f.name for f in font_manager.fontManager.ttflist}
|
| 29 |
+
|
| 30 |
+
for font in candidates:
|
| 31 |
+
if font in available:
|
| 32 |
+
plt.rcParams["font.family"] = font
|
| 33 |
+
return
|
| 34 |
+
|
| 35 |
+
print("Warning: Kannada font not found. Install fonts-noto-core.")
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def cosine_similarity(v1, v2):
|
| 39 |
+
denom = np.linalg.norm(v1) * np.linalg.norm(v2)
|
| 40 |
+
if denom == 0:
|
| 41 |
+
return 0.0
|
| 42 |
+
return float(np.dot(v1, v2) / denom)
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def compare_words_command(args):
|
| 46 |
+
setup_kannada_font()
|
| 47 |
+
|
| 48 |
+
model = fasttext.load_model(args.model)
|
| 49 |
+
|
| 50 |
+
words = args.words or [
|
| 51 |
+
"ಹಲಸು",
|
| 52 |
+
"ಹಣ್ಣು",
|
| 53 |
+
"ರೈತ",
|
| 54 |
+
"ನದಿ",
|
| 55 |
+
"ಮಳೆ",
|
| 56 |
+
"ತೆರಿಗೆ",
|
| 57 |
+
"ಅರಸ",
|
| 58 |
+
"ಅರಸಿ",
|
| 59 |
+
"ಹೆಣ್ಣು",
|
| 60 |
+
"ಮಾನವ",
|
| 61 |
+
]
|
| 62 |
+
|
| 63 |
+
matrix = []
|
| 64 |
+
for w1 in words:
|
| 65 |
+
row = []
|
| 66 |
+
for w2 in words:
|
| 67 |
+
row.append(
|
| 68 |
+
cosine_similarity(
|
| 69 |
+
model.get_word_vector(w1),
|
| 70 |
+
model.get_word_vector(w2),
|
| 71 |
+
)
|
| 72 |
+
)
|
| 73 |
+
matrix.append(row)
|
| 74 |
+
|
| 75 |
+
matrix = np.array(matrix)
|
| 76 |
+
|
| 77 |
+
fig, ax = plt.subplots(figsize=(12, 8))
|
| 78 |
+
im = ax.imshow(matrix, vmin=0, vmax=1)
|
| 79 |
+
|
| 80 |
+
ax.set_xticks(np.arange(len(words)))
|
| 81 |
+
ax.set_yticks(np.arange(len(words)))
|
| 82 |
+
ax.set_xticklabels(words, fontsize=12)
|
| 83 |
+
ax.set_yticklabels(words, fontsize=12)
|
| 84 |
+
|
| 85 |
+
plt.setp(ax.get_xticklabels(), rotation=45, ha="right", rotation_mode="anchor")
|
| 86 |
+
|
| 87 |
+
for i in range(len(words)):
|
| 88 |
+
for j in range(len(words)):
|
| 89 |
+
ax.text(j, i, f"{matrix[i, j]:.3f}", ha="center", va="center", fontsize=9)
|
| 90 |
+
|
| 91 |
+
ax.set_title("Kannada Word Similarity Matrix", fontsize=14)
|
| 92 |
+
fig.colorbar(im, ax=ax)
|
| 93 |
+
fig.tight_layout()
|
| 94 |
+
|
| 95 |
+
plt.savefig(args.output, dpi=180, bbox_inches="tight")
|
| 96 |
+
print(f"Saved matrix graph to {args.output}")
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
def train_command(args):
|
| 100 |
+
corpus_path = Path(args.corpus)
|
| 101 |
+
|
| 102 |
+
try:
|
| 103 |
+
model = fasttext.train_unsupervised(
|
| 104 |
+
input=str(corpus_path),
|
| 105 |
+
model="skipgram",
|
| 106 |
+
dim=args.dim,
|
| 107 |
+
epoch=args.epoch,
|
| 108 |
+
minCount=args.min_count,
|
| 109 |
+
wordNgrams=args.word_ngrams,
|
| 110 |
+
minn=args.minn,
|
| 111 |
+
maxn=args.maxn,
|
| 112 |
+
thread=args.threads,
|
| 113 |
+
)
|
| 114 |
+
print("training complete")
|
| 115 |
+
model.save_model(f"{args.out}.bin")
|
| 116 |
+
print(f"Saved {args.out}.bin")
|
| 117 |
+
except Exception as e:
|
| 118 |
+
print(f"Exception: {e}")
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
def test_command(args):
|
| 122 |
+
model = fasttext.load_model(args.model)
|
| 123 |
+
|
| 124 |
+
if args.word:
|
| 125 |
+
for score, word in model.get_nearest_neighbors(args.word, k=args.topk):
|
| 126 |
+
print(f"{word:<30} {score:.4f}")
|
| 127 |
+
|
| 128 |
+
if args.sentence:
|
| 129 |
+
vec = model.get_sentence_vector(args.sentence)
|
| 130 |
+
print(f"Embedding dimensions: {len(vec)}")
|
| 131 |
+
print(vec[:20])
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
def main():
|
| 135 |
+
parser = argparse.ArgumentParser()
|
| 136 |
+
sub = parser.add_subparsers(dest="command", required=True)
|
| 137 |
+
|
| 138 |
+
t = sub.add_parser("train")
|
| 139 |
+
t.add_argument("corpus", default="./corpus.txt")
|
| 140 |
+
t.add_argument("--recursive", action="store_true")
|
| 141 |
+
t.add_argument("--out", default="../models/kannada_fasttext")
|
| 142 |
+
t.add_argument("--dim", type=int, default=300)
|
| 143 |
+
t.add_argument("--epoch", type=int, default=20)
|
| 144 |
+
t.add_argument("--min-count", type=int, default=3)
|
| 145 |
+
t.add_argument("--word-ngrams", type=int, default=2)
|
| 146 |
+
t.add_argument("--minn", type=int, default=3)
|
| 147 |
+
t.add_argument("--maxn", type=int, default=8)
|
| 148 |
+
t.add_argument("--threads", type=int, default=16)
|
| 149 |
+
|
| 150 |
+
x = sub.add_parser("test")
|
| 151 |
+
x.add_argument("model")
|
| 152 |
+
x.add_argument("--word")
|
| 153 |
+
x.add_argument("--sentence")
|
| 154 |
+
x.add_argument("--topk", type=int, default=10)
|
| 155 |
+
|
| 156 |
+
c = sub.add_parser("compare")
|
| 157 |
+
c.add_argument("model")
|
| 158 |
+
c.add_argument("--output", default="../models/compare_matrix.png")
|
| 159 |
+
c.add_argument("--words", nargs="+")
|
| 160 |
+
|
| 161 |
+
args = parser.parse_args()
|
| 162 |
+
|
| 163 |
+
if args.command == "train":
|
| 164 |
+
train_command(args)
|
| 165 |
+
elif args.command == "test":
|
| 166 |
+
test_command(args)
|
| 167 |
+
elif args.command == "compare":
|
| 168 |
+
compare_words_command(args)
|
| 169 |
+
|
| 170 |
+
|
| 171 |
+
if __name__ == "__main__":
|
| 172 |
+
main()
|
code/prepare_corpus.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env -S uv run
|
| 2 |
+
# /// script
|
| 3 |
+
# dependencies = []
|
| 4 |
+
# ///
|
| 5 |
+
#
|
| 6 |
+
|
| 7 |
+
# uv run prepare_corpus.py prepare ../data ./corpus.txt --recursive
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
import argparse
|
| 11 |
+
import re
|
| 12 |
+
import unicodedata
|
| 13 |
+
from pathlib import Path
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def clean_text(text: str) -> str:
|
| 17 |
+
# Unicode normalization
|
| 18 |
+
text = unicodedata.normalize("NFC", text)
|
| 19 |
+
|
| 20 |
+
# Remove control characters except newline/tab
|
| 21 |
+
text = "".join(
|
| 22 |
+
ch for ch in text if unicodedata.category(ch)[0] != "C" or ch in "\n\t"
|
| 23 |
+
)
|
| 24 |
+
|
| 25 |
+
# Normalize line endings
|
| 26 |
+
text = text.replace("\r\n", "\n").replace("\r", "\n")
|
| 27 |
+
|
| 28 |
+
# Remove zero-width characters (common OCR artifacts)
|
| 29 |
+
text = re.sub(r"[\u200B-\u200D\uFEFF]", "", text)
|
| 30 |
+
|
| 31 |
+
# Normalize spaces
|
| 32 |
+
text = re.sub(r"[ \t]+", " ", text)
|
| 33 |
+
|
| 34 |
+
# Remove common OCR symbols
|
| 35 |
+
text = re.sub(r"[■□▪▫◆◇★☆◦•●]+", " ", text)
|
| 36 |
+
text = re.sub(r"[_=~`]+", " ", text)
|
| 37 |
+
|
| 38 |
+
# Remove separator lines
|
| 39 |
+
text = re.sub(r"(?m)^[-=*_]{3,}\s*$", "", text)
|
| 40 |
+
|
| 41 |
+
# Remove standalone page numbers
|
| 42 |
+
text = re.sub(r"(?m)^\s*\d+\s*$", "", text)
|
| 43 |
+
|
| 44 |
+
# Remove lines containing only Roman numerals (optional)
|
| 45 |
+
text = re.sub(r"(?m)^\s*[IVXLCDM]+\s*$", "", text)
|
| 46 |
+
|
| 47 |
+
# Trim spaces around newlines
|
| 48 |
+
text = re.sub(r" *\n *", "\n", text)
|
| 49 |
+
|
| 50 |
+
# Collapse multiple blank lines
|
| 51 |
+
text = re.sub(r"\n{3,}", "\n\n", text)
|
| 52 |
+
|
| 53 |
+
return text.strip()
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def collect_text_files(folder: Path, recursive: bool):
|
| 57 |
+
pattern = "**/*.txt" if recursive else "*.txt"
|
| 58 |
+
return sorted(folder.glob(pattern))
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
def build_corpus(files, output_file: Path):
|
| 62 |
+
print(f"output_file {output_file}")
|
| 63 |
+
|
| 64 |
+
with output_file.open("w", encoding="utf-8") as out:
|
| 65 |
+
for file in files:
|
| 66 |
+
print(file)
|
| 67 |
+
|
| 68 |
+
try:
|
| 69 |
+
text = file.read_text(
|
| 70 |
+
encoding="utf-8",
|
| 71 |
+
errors="ignore",
|
| 72 |
+
)
|
| 73 |
+
|
| 74 |
+
text = clean_text(text)
|
| 75 |
+
|
| 76 |
+
out.write(text)
|
| 77 |
+
out.write("\n")
|
| 78 |
+
|
| 79 |
+
except Exception as e:
|
| 80 |
+
print(f"Skipping {file}: {e}")
|
| 81 |
+
|
| 82 |
+
print("DONE build_corpus")
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
def prepare_command(args):
|
| 86 |
+
files = collect_text_files(Path(args.folder), args.recursive)
|
| 87 |
+
if not files:
|
| 88 |
+
raise SystemExit("No .txt files found")
|
| 89 |
+
build_corpus(files, Path(args.output))
|
| 90 |
+
print(f"Corpus written to {args.output}")
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
def main():
|
| 94 |
+
parser = argparse.ArgumentParser()
|
| 95 |
+
sub = parser.add_subparsers(dest="command", required=True)
|
| 96 |
+
|
| 97 |
+
p = sub.add_parser("prepare")
|
| 98 |
+
p.add_argument("folder", default="../data/")
|
| 99 |
+
p.add_argument("output", default="./corpus.txt")
|
| 100 |
+
p.add_argument("--recursive", action="store_true")
|
| 101 |
+
|
| 102 |
+
args = parser.parse_args()
|
| 103 |
+
|
| 104 |
+
if args.command == "prepare":
|
| 105 |
+
prepare_command(args)
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
if __name__ == "__main__":
|
| 109 |
+
main()
|
code/word2vec_embeddings.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env -S uv run
|
| 2 |
+
# /// script
|
| 3 |
+
# dependencies = ["gensim"]
|
| 4 |
+
# ///
|
| 5 |
+
|
| 6 |
+
# uv run word2vec_embeddings.py train ./corpus.txt --out ../models/kannada_kasturi_word2vec.model --model skipgram
|
| 7 |
+
# uv run word2vec_embeddings.py test ../models/kannada_kasturi_word2vec.model --word ಕನ್ನಡ
|
| 8 |
+
# uv run word2vec_embeddings.py test ../models/kannada_kasturi_word2vec.model --word ರಾಜಧಾನಿ
|
| 9 |
+
|
| 10 |
+
import argparse
|
| 11 |
+
from pathlib import Path
|
| 12 |
+
|
| 13 |
+
from gensim.models import Word2Vec
|
| 14 |
+
from gensim.utils import simple_preprocess
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def read_sentences(corpus_path: Path):
|
| 18 |
+
with corpus_path.open("r", encoding="utf-8") as f:
|
| 19 |
+
for line in f:
|
| 20 |
+
line = line.strip()
|
| 21 |
+
if line:
|
| 22 |
+
# For Kannada, whitespace tokenization is often better than simple_preprocess
|
| 23 |
+
yield line.split()
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def train_word2vec(args):
|
| 27 |
+
sentences = list(read_sentences(Path(args.input)))
|
| 28 |
+
|
| 29 |
+
model = Word2Vec(
|
| 30 |
+
sentences=sentences,
|
| 31 |
+
vector_size=args.dim,
|
| 32 |
+
window=args.window,
|
| 33 |
+
min_count=args.min_count,
|
| 34 |
+
workers=args.threads,
|
| 35 |
+
epochs=args.epoch,
|
| 36 |
+
sg=1 if args.model == "skipgram" else 0,
|
| 37 |
+
)
|
| 38 |
+
|
| 39 |
+
model.save(args.out)
|
| 40 |
+
model.wv.save_word2vec_format(args.out + ".vec")
|
| 41 |
+
|
| 42 |
+
print(f"Saved model: {args.out}")
|
| 43 |
+
print(f"Saved vectors: {args.out}.vec")
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def test_word(args):
|
| 47 |
+
model = Word2Vec.load(args.model_path)
|
| 48 |
+
|
| 49 |
+
print(model.wv[args.word])
|
| 50 |
+
|
| 51 |
+
print("\nNearest:")
|
| 52 |
+
for word, score in model.wv.most_similar(args.word, topn=10):
|
| 53 |
+
print(word, score)
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def main():
|
| 57 |
+
parser = argparse.ArgumentParser()
|
| 58 |
+
|
| 59 |
+
sub = parser.add_subparsers(dest="cmd", required=True)
|
| 60 |
+
|
| 61 |
+
train = sub.add_parser("train")
|
| 62 |
+
train.add_argument("input", default="./corpus.txt")
|
| 63 |
+
train.add_argument("--out", default="../models/kannada_kasturi_word2vec.model")
|
| 64 |
+
train.add_argument("--model", choices=["skipgram", "cbow"], default="skipgram")
|
| 65 |
+
train.add_argument("--dim", type=int, default=300)
|
| 66 |
+
train.add_argument("--window", type=int, default=5)
|
| 67 |
+
train.add_argument("--epoch", type=int, default=20)
|
| 68 |
+
train.add_argument("--min-count", type=int, default=2)
|
| 69 |
+
train.add_argument("--threads", type=int, default=16)
|
| 70 |
+
|
| 71 |
+
test = sub.add_parser("test")
|
| 72 |
+
test.add_argument("model_path")
|
| 73 |
+
test.add_argument("--word", required=True)
|
| 74 |
+
|
| 75 |
+
args = parser.parse_args()
|
| 76 |
+
|
| 77 |
+
if args.cmd == "train":
|
| 78 |
+
train_word2vec(args)
|
| 79 |
+
elif args.cmd == "test":
|
| 80 |
+
test_word(args)
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
if __name__ == "__main__":
|
| 84 |
+
main()
|
data/kananda_kasturi_kasthruriapril190000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthruriapril190000unse_z9j1.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthuriapr19910000ksha.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthuriapril1970000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthuriaug19910000ksha.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthuriaug19920000ksha.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthuriaugust190000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthuriaugust190000unse_l2t1.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthuriaugust190000unse_v2e9.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthuridec19860000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthuridec19870000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthuridec19880000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthuridec19910000ksha.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthuridecember0000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthuridecember0000unse_j1v3.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurifeb19770000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurifeb19870000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurifebrury10000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurifebrury10000unse_v7l3.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurijan19870000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurijan19910000ksha.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurijuly19580000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurijuly19610000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurijuly19620000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurijune19610000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurijune19620000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurijune19770000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurijune19910000ksha.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurimarch1960000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurimarch1960000unse_e2x6.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurimarch1960000unse_r5s9.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurimarch1970000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurimarch1990000ksha.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurimay19610000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurimay19620000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurimay19770000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurimay19910000ksha.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurimay19920000ksha.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurinov19780000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurinov19860000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurinov19880000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurinov19900000ksha.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurinovember0000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurinovember0000unse_g4q6.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurioct19880000unse.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurioctober10000ksha_n8d0.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/kananda_kasturi_kasthurioctober10000ksha_q4i6.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|