@@ -312,7 +312,7 @@ def __init__(self, sentences=None, corpus_file=None, sg=0, hs=0, vector_size=100
312
312
max_vocab_size = None , word_ngrams = 1 , sample = 1e-3 , seed = 1 , workers = 3 , min_alpha = 0.0001 ,
313
313
negative = 5 , ns_exponent = 0.75 , cbow_mean = 1 , hashfxn = hash , epochs = 5 , null_word = 0 , min_n = 3 , max_n = 6 ,
314
314
sorted_vocab = 1 , bucket = 2000000 , trim_rule = None , batch_words = MAX_WORDS_IN_BATCH , callbacks = (),
315
- max_final_vocab = None ):
315
+ max_final_vocab = None , position_dependent_weights = 0 ):
316
316
"""Train, use and evaluate word representations learned using the method
317
317
described in `Enriching Word Vectors with Subword Information <https://arxiv.org/abs/1607.04606>`_,
318
318
aka FastText.
@@ -421,6 +421,14 @@ def __init__(self, sentences=None, corpus_file=None, sg=0, hs=0, vector_size=100
421
421
``min_count```. If the specified ``min_count`` is more than the
422
422
automatically calculated ``min_count``, the former will be used.
423
423
Set to ``None`` if not required.
424
+ position_dependent_weights : {1,0}, optional
425
+ If position vectors should be computed beside word and n-gram vectors, and used to weight the
426
+ context words during the training (1), or if all context words should be uniformly weighted (0).
427
+
428
+ Notes
429
+ -----
430
+ Positional vectors are only implemented for CBOW with negative sampling, not SG or hierarchical softmax.
431
+ Locking positional vectors is not supported. BLAS primitives are not used by the implementation.
424
432
425
433
Examples
426
434
--------
@@ -451,6 +459,10 @@ def __init__(self, sentences=None, corpus_file=None, sg=0, hs=0, vector_size=100
451
459
self .callbacks = callbacks
452
460
if word_ngrams != 1 :
453
461
raise NotImplementedError ("Gensim's FastText implementation does not yet support word_ngrams != 1." )
462
+ if position_dependent_weights and (sg or hs ):
463
+ raise NotImplementedError ("Gensim's FastText implementation does not yet support position-dependent "
464
+ "weighting with SG or hierarchical softmax" )
465
+ self .position_dependent_weights = position_dependent_weights
454
466
self .word_ngrams = word_ngrams
455
467
if max_n < min_n :
456
468
# with no eligible char-ngram lengths, no buckets need be allocated
@@ -468,7 +480,8 @@ def __init__(self, sentences=None, corpus_file=None, sg=0, hs=0, vector_size=100
468
480
seed = seed , hs = hs , negative = negative , cbow_mean = cbow_mean , min_alpha = min_alpha )
469
481
470
482
def prepare_weights (self , update = False ):
471
- """In addition to superclass allocations, compute ngrams of all words present in vocabulary.
483
+ """In addition to superclass allocations, compute ngrams of all words present in vocabulary
484
+ and initialize positional vectors.
472
485
473
486
Parameters
474
487
----------
@@ -479,6 +492,8 @@ def prepare_weights(self, update=False):
479
492
super (FastText , self ).prepare_weights (update = update )
480
493
if not update :
481
494
self .wv .init_ngrams_weights (self .seed )
495
+ if self .position_dependent_weights :
496
+ self .wv .init_positional_weights (self .seed , self .window )
482
497
# EXPERIMENTAL lockf feature; create minimal no-op lockf arrays (1 element of 1.0)
483
498
# advanced users should directly resize/adjust as necessary
484
499
self .wv .vectors_vocab_lockf = ones (1 , dtype = REAL )
@@ -570,6 +585,8 @@ def build_vocab(self, corpus_iterable=None, corpus_file=None, update=False, prog
570
585
"""
571
586
if not update :
572
587
self .wv .init_ngrams_weights (self .seed )
588
+ if self .position_dependent_weights :
589
+ self .wv .init_positional_weights (self .seed , self .window )
573
590
elif not len (self .wv ):
574
591
raise RuntimeError (
575
592
"You cannot do an online vocabulary-update of a model which has no prior vocabulary. "
@@ -1190,6 +1207,7 @@ def __init__(self, vector_size, min_n, max_n, bucket):
1190
1207
self .vectors_vocab = None # fka syn0_vocab
1191
1208
self .vectors_ngrams = None # fka syn0_ngrams
1192
1209
self .buckets_word = None
1210
+ self .vectors_positions = None
1193
1211
self .min_n = min_n
1194
1212
self .max_n = max_n
1195
1213
self .bucket = bucket # count of buckets, fka num_ngram_vectors
@@ -1329,7 +1347,6 @@ def init_ngrams_weights(self, seed):
1329
1347
vocab_shape = (len (self ), self .vector_size )
1330
1348
ngrams_shape = (self .bucket , self .vector_size )
1331
1349
self .vectors_vocab = rand_obj .uniform (lo , hi , vocab_shape ).astype (REAL )
1332
-
1333
1350
#
1334
1351
# We could have initialized vectors_ngrams at construction time, but we
1335
1352
# do it here for two reasons:
@@ -1341,6 +1358,25 @@ def init_ngrams_weights(self, seed):
1341
1358
#
1342
1359
self .vectors_ngrams = rand_obj .uniform (lo , hi , ngrams_shape ).astype (REAL )
1343
1360
1361
+ def init_positional_weights (self , seed , window ):
1362
+ """Initialize the positional weights prior to training.
1363
+
1364
+ Creates the weight matrix and initializes it with uniform random values.
1365
+
1366
+ Parameters
1367
+ ----------
1368
+ seed : float
1369
+ The seed for the PRNG.
1370
+ window : int
1371
+ The size of the window used during the training.
1372
+
1373
+ """
1374
+ rand_obj = np .random .default_rng (seed = seed ) # use new instance of numpy's recommended generator/algorithm
1375
+
1376
+ lo , hi = - 1.0 / self .vector_size , 1.0 / self .vector_size
1377
+ positional_shape = (2 * window , self .vector_size )
1378
+ self .vectors_positions = rand_obj .uniform (lo , hi , positional_shape ).astype (REAL )
1379
+
1344
1380
def update_ngrams_weights (self , seed , old_vocab_len ):
1345
1381
"""Update the vocabulary weights for training continuation.
1346
1382
0 commit comments