| 376 | |
| 377 | |
| 378 | def analogy(pos1, neg1, pos2, neg2, word2idx, idx2word, W): |
| 379 | V, D = W.shape |
| 380 | |
| 381 | # don't actually use pos2 in calculation, just print what's expected |
| 382 | print("testing: %s - %s = %s - %s" % (pos1, neg1, pos2, neg2)) |
| 383 | for w in (pos1, neg1, pos2, neg2): |
| 384 | if w not in word2idx: |
| 385 | print("Sorry, %s not in word2idx" % w) |
| 386 | return |
| 387 | |
| 388 | p1 = W[word2idx[pos1]] |
| 389 | n1 = W[word2idx[neg1]] |
| 390 | p2 = W[word2idx[pos2]] |
| 391 | n2 = W[word2idx[neg2]] |
| 392 | |
| 393 | vec = p1 - n1 + n2 |
| 394 | |
| 395 | distances = pairwise_distances(vec.reshape(1, D), W, metric='cosine').reshape(V) |
| 396 | idx = distances.argsort()[:10] |
| 397 | |
| 398 | # pick one that's not p1, n1, or n2 |
| 399 | best_idx = -1 |
| 400 | keep_out = [word2idx[w] for w in (pos1, neg1, neg2)] |
| 401 | for i in idx: |
| 402 | if i not in keep_out: |
| 403 | best_idx = i |
| 404 | break |
| 405 | |
| 406 | print("got: %s - %s = %s - %s" % (pos1, neg1, idx2word[idx[0]], neg2)) |
| 407 | print("closest 10:") |
| 408 | for i in idx: |
| 409 | print(idx2word[i], distances[i]) |
| 410 | |
| 411 | print("dist to %s:" % pos2, cos_dist(p2, vec)) |
| 412 | |
| 413 | |
| 414 | def test_model(word2idx, W, V): |