| 325 | |
| 326 | |
| 327 | def analogy(pos1, neg1, pos2, neg2, word2idx, idx2word, W): |
| 328 | V, D = W.shape |
| 329 | |
| 330 | # don't actually use pos2 in calculation, just print what's expected |
| 331 | print("testing: %s - %s = %s - %s" % (pos1, neg1, pos2, neg2)) |
| 332 | for w in (pos1, neg1, pos2, neg2): |
| 333 | if w not in word2idx: |
| 334 | print("Sorry, %s not in word2idx" % w) |
| 335 | return |
| 336 | |
| 337 | p1 = W[word2idx[pos1]] |
| 338 | n1 = W[word2idx[neg1]] |
| 339 | p2 = W[word2idx[pos2]] |
| 340 | n2 = W[word2idx[neg2]] |
| 341 | |
| 342 | vec = p1 - n1 + n2 |
| 343 | |
| 344 | distances = pairwise_distances(vec.reshape(1, D), W, metric='cosine').reshape(V) |
| 345 | idx = distances.argsort()[:10] |
| 346 | |
| 347 | # pick one that's not p1, n1, or n2 |
| 348 | best_idx = -1 |
| 349 | keep_out = [word2idx[w] for w in (pos1, neg1, neg2)] |
| 350 | # print("keep_out:", keep_out) |
| 351 | for i in idx: |
| 352 | if i not in keep_out: |
| 353 | best_idx = i |
| 354 | break |
| 355 | # print("best_idx:", best_idx) |
| 356 | |
| 357 | print("got: %s - %s = %s - %s" % (pos1, neg1, idx2word[best_idx], neg2)) |
| 358 | print("closest 10:") |
| 359 | for i in idx: |
| 360 | print(idx2word[i], distances[i]) |
| 361 | |
| 362 | print("dist to %s:" % pos2, cos_dist(p2, vec)) |
| 363 | |
| 364 | |
| 365 | def test_model(word2idx, W, V): |