Метрика для ранжированной идентификации ключевых слов - PullRequest
0 голосов
/ 26 июня 2019

Я пытаюсь определить, какие метрики использовать для оценки «охвата» лексикона (списка слов) по отношению к ранжированному списку значимых ключевых слов, которые я извлек из двух разных коллекций текстов. Два списка не имеют общих терминов. Важно отметить, что только слова с самым высоким рейтингом должны считаться «правильными», в то время как слова с самым низким рейтингом должны считаться «неправильными».

Ниже приведен фиктивный пример с ранжированным списком ключевых слов и 4 различными лексиконами, каждый из которых содержит некоторые слова в списке.

rank  keyword    lexicon_1  lexicon_2  lexicon_3  lexicon_4
1     apple      False      True       True       False
2     orange     False      True       True       False
3     banana     False      False      True       False
4     pear       False      False      True       False
5     kiwifruit  True       False      True       False
6     watermelon True       False      True       False
-----------------------------------------------------------
7     car        False      False      False      True
8     bus        False      False      False      True
9     truck      True       False      False      True
10    bike       False      True       False      True

Таким образом, интуиция заключается в том, что чем больше ключевых слов с высоким рейтингом (1-6) включено в лексикон, тем лучше, и чем меньше ключевых слов с более низким рейтингом (7-10), тем лучше.

Расчет точности (P), отзыва (R) и F-показателя (F) является одним из способов количественного определения и сравнения покрытия. Для этого истинные положительные значения (TP) - это когда лексикон содержит правильное слово, ложные положительные значения (FP), когда оно содержит неверное слово, истинные отрицательные значения (TN), когда исключается неправильное слово, и ложные отрицания (FN), когда исключается правильное слово. Имея это в виду, например, для lexicon_1 это дает:

TP=2, FP=1, TN=3, FN=4
P = 2 / (2 + 1)    R = 2 / (2 + 4)    F = 2 * 0.67 * 0.33 / (0.67 + 0.33)
  = 0.67             = 0.33             = 0.44

Для lexicon_2 мы также получаем F=0.44. Для lexicon_3 мы получаем F=1.00, а для lexicon_4 мы получаем F=0 (как неопределено). Таким образом, мы можем видеть, что лексиконы 1 и 2 расположены между 3 (лучший) и 4 (худший), но это не учитывает тот факт, что lexicon_2 имеет слова с более высоким рейтингом, чем lexicon_1 и поэтому должен получить более благоприятную оценку.

Есть ли метрика, которая бы учитывала ранжирование слов в этих случаях? Мне известны average precision и mean average precision, которые учитывают ранжирование полученных результатов, но я не уверен, подходят ли эти показатели для данной ситуации.

РЕДАКТИРОВАТЬ 1:

Я реализовал мое понимание средней точности для этой ситуации:

def avep(df, lexicon_names):
    """
    Calculate average precision for each lexicon from 
    pre-calculated precision and recall scores stored
    in a DataFrame.
    """
    aveps = {}
    for l in lexicon_names:
        ap = 0.0
        for i in range(len(df)):
            p_i = df.iloc[i]['p_' + l]
            if i > 0:
                dr_i = df.iloc[i]['r_' + l] - df.iloc[i - 1]['r_' + l]
            else:
                dr_i = 0.0
            ap += p_i * dr_i
        aveps[l] = ap
    return aveps

Это дает мне следующие результаты:

Lexicon     p                   r                   f                   AP                  
-------     -                   -                   -                   --                  
lexicon_1 : 0.6666666666666666  0.2857142857142857  0.4                 0.2857142857142857  
lexicon_2 : 0.6666666666666666  0.2857142857142857  0.4                 0.14285714285714285 
lexicon_3 : 1.0                 1.0                 1.0                 0.8571428571428571  
lexicon_4 : 0.0                 0.0                 0.0                 0.0     

Но это дает лучший результат для lexicon_1, чем lexicon_2, что противоположно тому, что я хочу (и AP подозрительно равна отзыву для lexicon_1 и 2 x recall для lexicon_2). Кроме того, не уверены, что делать с первой строкой, где разница в возврате не определена (используется 0). Это дает значение менее 1,0 для «совершенного» * ​​1047 *.

Любые лучшие предложения будут высоко оценены!

РЕДАКТИРОВАТЬ 2:

Вот моя Python-реализация решения, предоставленного RobertBaron:

def coverage_metric(df, lexicon_names):
    scores = {}

    max_score = int(''.join([str(x) for x in df.index]))

    for l in lexicon_names:
        correct_score = int(''.join([str(x) for x in df.loc[df[l] == True].index]))
        incorrect_score = int(''.join([str(x) for x in df.loc[df[l] == False].index]))
        scores[l] = (correct_score - incorrect_score) / max_score

    scores = sorted(scores.items(), key=lambda x: x[1], reverse=True)

    return scores

Это реализация преобразования чисел, необходимого для решения RobertBaron (насколько я понимаю):

def int2base(n, b):
    """
    Implementation of the algorith; described at http://www.cs.trincoll.edu/~ram/cpsc110/inclass/conversions.html
    """
    x = ''
    while n > 0:
        d = int(n / b)
        r = n % b
        x += str(r)
        n = d

    return int(x)

1 Ответ

0 голосов
/ 26 июня 2019

Вот метрика. Есть n + m рангов. Итак, присвойте цифру из чисел в базе n + m + 1 каждому ключевому слову, чтобы ключевое слово самого высокого ранга было самой большой цифрой. В вашем примере у нас есть 10 ключевых слов, поэтому цифры взяты из базы 11 и идут от A до 1 (с использованием шестнадцатеричных цифр), как показано ниже.

rank  digit  keyword    lexicon_1  lexicon_2  lexicon_3  lexicon_4
1     A      apple      False      True       True       False
2     9      orange     False      True       True       False
3     8      banana     False      False      True       False
4     7      pear       False      False      True       False
5     6      kiwifruit  True       False      True       False
6     5      watermelon True       False      True       False
------------------------------------------------------------------
7     4      car        False      False      False      True
8     3      bus        False      False      False      True
9     2      truck      True       False      False      True
10    1      bike       False      True       False      True

Для каждого лексикона показатель покрытия рассчитывается следующим образом. Для правильных ключевых слов, начиная с наивысшего ранга, создайте число, объединяя цифры ключевых слов в лексиконе. Например, для наших 4 лексиконов мы имеем соответственно 65, A9, A98765 и 0. Сделайте то же самое для неправильных ключевых слов. Это дает нам 2, 1, 0 и 4321. Окончательный показатель получается путем вычитания двух чисел, построенных для каждого лексикона, то есть 65 - 1 = 64, A9 - 1 = A8, A98765 - 0 = A98765 и 0 - 4321 = -4321.

Если вам нужна метрика в диапазоне [0 1], вы можете разделить ее на A98765, что является максимальным значением, которое может иметь лексикон в этом примере.

Для удобства числа n + m + 1 можно преобразовать в базу 10 для расчетов. См. Алгоритмы преобразования чисел .

В нашем примере, который является базой 11, для лексики 1 нам нужно преобразовать 65, 1 и A98765 в базу 10. У нас есть:

6 x 11 1 + 5 x 11 0 = 71

1 x 11 0 = 1

10 x 11 5 + 9 x 11 4 + 8 x 11 3 + 7 x 11 2 + 6 x 11 1 + 5 х 11 0 = 1753845

А показатель для лексики 1 равен (71 - 1) / 1753845 = 0,000039912307

В примере есть небольшая ошибка. Поскольку у нас могут быть отрицательные значения, диапазон возможных значений изменяется от -4321 до A98765. Итак, чтобы получить показатель в [0 1], нам нужно сместить на 4321 и разделить на A98765 + 4321.

...