Получить ключ на основе значения в массиве из словаря - PullRequest
1 голос
/ 08 апреля 2020

Я просто создаю модель word2ve c и создаю словарь между словом (ключом) и значением (вектором).

dictionary = dict({})
for idx, key in enumerate(model.wv.vocab):
dictionary[key] = model.wv[key]

Словарь, подобный следующему:

{'petani': array([-1.5856586e-01, -3.7320998e-01,  5.2052790e-01,  4.2783752e-01,
         7.6572634e-02, -6.9080216e-01, -6.2848133e-01, -8.8271695e-01,
        -5.0581765e-01, -3.0301598e-01,  1.2088260e-01, -6.9143041e-03,
         4.4222975e-01, -3.6879349e-01,  5.5616591e-02, -1.1631098e-01,
        -4.1717857e-02, -1.0702840e-01, -3.8082123e-01, -3.2646924e-01,
        -6.2404245e-01,  1.5188067e-01,  4.4228908e-01, -1.2028643e-02,
        -1.1128881e-01, -1.2848943e-01, -2.2734607e-02, -4.8964986e-01,
         8.8901877e-01,  3.4160933e-01, -2.7001941e-01,  1.9693324e-01,
         2.0979826e-01,  2.9565904e-01, -1.2944296e-01,  7.1377866e-02,
        -2.3514537e-02, -8.9601561e-02,  2.5837755e-01,  2.4173041e-01,
         1.3690867e-01, -2.9203954e-01, -2.2040294e-01,  4.3522149e-01,
        -1.3773613e-01,  1.5158685e-01, -8.4017359e-02, -4.2125726e-01,
        -4.1426069e-01, -3.0153343e-01, -3.7908006e-01,  6.4364660e-01,
         4.3095109e-01,  7.0161112e-02,  2.5523776e-01,  1.0336957e-01,
         2.0642248e-01, -3.3600163e-01,  4.1162384e-01,  3.1530520e-01,
        -7.8101611e-01, -2.8255533e-02,  3.7680027e-01,  1.4239751e-01,
        -2.4524818e-01,  4.0836743e-01,  5.3868568e-01, -3.5229959e-02,
        -2.4528666e-03,  6.3001931e-01,  5.2766448e-01, -4.7586882e-01,
         3.9797042e-02,  6.7331716e-02,  9.5685691e-02, -1.2028452e-01,
        -4.5608345e-01,  2.8427744e-01, -2.9394981e-01, -1.2994224e-01,
         5.1969510e-01,  1.2906422e-01, -7.3352844e-02,  1.4258710e-01,
        -5.1817909e-02, -9.9871524e-02, -7.8935099e-01, -7.4661225e-02,
         7.3149313e-05, -5.7802260e-01,  9.4037224e-03, -3.1019258e-01,
        -1.2252379e-01, -2.6833829e-01,  6.4406760e-02,  2.1438387e-01,
        -4.6708840e-01,  4.6972111e-01,  6.5475023e-01,  2.5733718e-01],
       dtype=float32),
 'tewas': array([-0.5524042 ,  0.06416334,  0.43303823,  0.08412471, -0.26415887,
         0.81605107, -0.30849332, -0.31477442,  0.55429876, -0.34576067,
         0.20641974, -0.4408319 ,  0.6560267 , -0.27099684,  0.01890246,
         0.19507472,  1.0473057 , -0.4251338 ,  0.47794574, -0.87928706,
        -0.17208456,  0.42365453, -0.1005183 , -0.4278884 ,  0.5542767 ,
        -0.2686175 ,  0.08917291, -0.67033154, -0.5816741 ,  0.6316814 ,
         0.02794617, -0.36843893,  0.28338206, -0.20059416, -0.45663786,
        -0.01763846,  0.0384933 , -0.6548334 ,  0.30371612, -0.31790268,
        -0.2999138 , -0.44880405, -0.23181435, -0.4012081 , -0.39137393,
         0.40417886, -0.24790864, -0.4002588 ,  0.5552438 , -0.13635041,
        -0.2759215 ,  0.5185368 ,  1.1411811 ,  0.02402515, -0.22694567,
        -0.13629675,  0.00484379,  0.21743643, -0.09752762, -0.13332742,
        -0.5833612 ,  0.18499097,  0.16189235, -0.6939921 , -0.8281921 ,
         0.22095513,  0.390632  , -0.23755077, -0.36395508,  0.8814506 ,
         0.4552586 , -0.36801606,  0.06618993,  0.47150037,  0.3567098 ,
        -0.9401551 ,  0.53242975, -0.84471244, -0.8138361 ,  0.28408146,
         0.23675315, -0.28799447, -0.33678758,  0.57642925,  0.37340602,
        -0.12505923, -0.02738794, -0.6040789 , -0.17035136, -0.3264485 ,
         0.5719107 , -0.3058263 , -0.11770777, -0.73283607,  0.07872504,
        -0.3070875 , -0.3163887 , -0.2119802 , -0.11972545, -0.27509072],
    dtype=float32),
...}

Я могу получить значение на основе ключа с помощью:

dictionary.get('petani')

с результатом:

array([-1.5856586e-01, -3.7320998e-01,  5.2052790e-01,  4.2783752e-01,
        7.6572634e-02, -6.9080216e-01, -6.2848133e-01, -8.8271695e-01,
       -5.0581765e-01, -3.0301598e-01,  1.2088260e-01, -6.9143041e-03,
        4.4222975e-01, -3.6879349e-01,  5.5616591e-02, -1.1631098e-01,
       -4.1717857e-02, -1.0702840e-01, -3.8082123e-01, -3.2646924e-01,
       -6.2404245e-01,  1.5188067e-01,  4.4228908e-01, -1.2028643e-02,
       -1.1128881e-01, -1.2848943e-01, -2.2734607e-02, -4.8964986e-01,
        8.8901877e-01,  3.4160933e-01, -2.7001941e-01,  1.9693324e-01,
        2.0979826e-01,  2.9565904e-01, -1.2944296e-01,  7.1377866e-02,
       -2.3514537e-02, -8.9601561e-02,  2.5837755e-01,  2.4173041e-01,
        1.3690867e-01, -2.9203954e-01, -2.2040294e-01,  4.3522149e-01,
       -1.3773613e-01,  1.5158685e-01, -8.4017359e-02, -4.2125726e-01,
       -4.1426069e-01, -3.0153343e-01, -3.7908006e-01,  6.4364660e-01,
        4.3095109e-01,  7.0161112e-02,  2.5523776e-01,  1.0336957e-01,
        2.0642248e-01, -3.3600163e-01,  4.1162384e-01,  3.1530520e-01,
       -7.8101611e-01, -2.8255533e-02,  3.7680027e-01,  1.4239751e-01,
       -2.4524818e-01,  4.0836743e-01,  5.3868568e-01, -3.5229959e-02,
       -2.4528666e-03,  6.3001931e-01,  5.2766448e-01, -4.7586882e-01,
        3.9797042e-02,  6.7331716e-02,  9.5685691e-02, -1.2028452e-01,
       -4.5608345e-01,  2.8427744e-01, -2.9394981e-01, -1.2994224e-01,
        5.1969510e-01,  1.2906422e-01, -7.3352844e-02,  1.4258710e-01,
       -5.1817909e-02, -9.9871524e-02, -7.8935099e-01, -7.4661225e-02,
        7.3149313e-05, -5.7802260e-01,  9.4037224e-03, -3.1019258e-01,
       -1.2252379e-01, -2.6833829e-01,  6.4406760e-02,  2.1438387e-01,
       -4.6708840e-01,  4.6972111e-01,  6.5475023e-01,  2.5733718e-01],
      dtype=float32)

, и я попытался получить ключ на основе значения с помощью:

def get_key(val): 
    for key, value in dictionary.items(): 
         if val == value: 
             return key 

    return "key doesn't exist"

contoh_value = [ 0.3296796,   0.39876923,  0.47616847, -0.85435633,  0.08756444, -0.3249461, -0.9938304,  -0.94971858,  0.96680486, -0.1293482,   0.76376391,  0.56389303,  1.74900006,  1.25801649, -0.24322121, -0.37309024, -0.07400302, -0.31166066,  0.02108994,  0.18042984,  0.23819409,  0.72364472,  0.72723592,  0.47477901, -0.76086017,  1.67910596,  0.5221492,   0.07191082, -0.99006812,  0.30615227,  1.00488158, -0.73874328,  0.89766186, -0.5589205,   0.23986163,  0.59018145, -0.29154907, -0.40612788,  0.68320352, -0.32813038, -0.95184149, -0.58031032, -0.54268715, -0.68725495, -0.35027478, -0.30614226,  0.81348022,  0.40609737,  1.54977913, -0.04884687, -0.47331776, -0.22339089,  0.58311762,  0.13232404,  0.81241847,  0.72163447,  0.23984061, -0.32305742,  0.52193057,  0.506366, -0.56128758, -0.30134899, -0.53561509, -0.90930432, -1.22216257,  0.00341641,  0.41335883, -1.16226898, -0.15699308,  0.56443178,  0.1427298,  -0.24072925, -1.06598538,  0.56613415,  1.16162036,  1.10104698,  0.93053441,  0.88296479,  0.28975529, -0.97775083, -1.45139772, -0.16452539, -1.02581363,  0.65278189,  0.6345808,   0.41010778, -2.14354638,  0.25915023, -0.0490873,  -0.25783952, -0.40967067, -0.96420361, -0.99802028, -0.35535042, -0.09994081,  0.12680747,  1.29304774, -0.35715534, -0.98996135, -0.90942983]

print(get_key(contoh_value))

Но результат "ключ не существует". значение contoh_value является копией из существующего вектора в словаре. Как лучше всего получить ключ из значения np.array?

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

В общем, нет причин создавать ваш словарь. Это избыточный, менее эффективный для оперативной памяти способ хранения той же информации, которая уже есть в вашем model.wv объекте. (Этот объект будет некоторым классом, связанным с типом gensim KeyedVectors.)

Из объекта model.wv у вас уже есть поиск по ключу. И у вас уже есть эффективный упорядоченный массив всех его значений в model.wv.vectors. И model.wv.index2entity - это список, который может отображаться обратно из порядковых позиций в этом массиве в соответствующие слова.

Но также очень редко нужно искать точный вектор по значению. Процесс обучения включает в себя много случайности и не обязательно имеет «правильную» или «идеальную» конечную точку - просто какое-то относительное расположение, которое так же хорошо, как и другие для целевой цели обучения, и примерно так же хорошо -по-это может-получить.

Таким образом, ни точные местоположения не важны - по сравнению с расстояниями / относительным направлением до векторных векторов, ни младшие значащие цифры в полных измерениях - это не что иное, как шум.

Таким образом, единственный способ ожидать найти точный вектор в наборе обученных слов-векторов - это сначала запросить тот же самый вектор из набора - затем искать именно это.

Я подозреваю, что если бы вы сделали это, вместо ввода желаемых значений в литерал list, ваша существующая функция могла бы работать. Вы будете проверять точные правильные координаты и тип массива, который мог бы соответствовать - если бы этот точный вектор был в наборе. Например, ваша функция может работать с вводом:

target_value = dictionary.get('petani')
get_key(target_value)

Гораздо более распространенная операция на наборах векторов состоит в том, чтобы найти в наборе топ-N элементов, близких к некоторому целевому местоположению - с этим местоположением указывается либо как ключ с известным вектором-местоположением, либо как необработанный вектор. Классы gensim KeyedVector предлагают это с помощью метода most_similar(). (Это немного дороже, так как требует оценки косинусного сходства со всеми векторами, затем сортировки и возврата наиболее похожих совпадений. Но это делается с помощью довольно эффективных операций с массивами нативных библиотек.

Например, посмотрите на результаты любого из этих фрагментов кода с вашей моделью:

model.wv.most_similar('petani')

... или ...

target_vector = model.wv['petani']
model.wv.most_similar(positive=[target_vector,])
0 голосов
/ 08 апреля 2020

Поскольку эти значения являются значениями с плавающей запятой, у вас могут возникнуть проблемы при попытке их прямого сравнения на равенство. Вы можете добиться большего успеха, используя функцию numpy .isclose . Эта функция принимает по крайней мере два параметра, как у массива a и как у массива b, и возвращает новый массив с True или False в каждом индексе, который соответствует элементам с одинаковым индексом в a и b близки по значению. Затем вы можете проверить, все ли эти значения близки, используя функцию numpy .all , которая принимает хотя бы один параметр, подобный массиву a, и в случае одномерного массива: проверяет, все ли значения True и возвращает bool. Вы можете изменить свою функцию get_key следующим образом:

def get_key(val): 
    for key, value in dictionary.items():
        if all(isclose(val, value)):
            return key

    return "key doesn't exist"

Таким образом, если все соответствующие значения в двух массивах близки, он вернет ключ, в противном случае он будет go включен следующая пара ключ-значение для сравнения.

Примечание : Это работает, только если элементы массива, которые вы передаете в свою функцию, гарантированно будут в том же порядке, что и массив в словаре

...