2010-02-23 2 views
3

Я разработал некоторую java-программу для вычисления подобия косинуса на основе TF * IDF. Он работал очень хорошо. Но есть одна проблема .... :(проблема сходства java-косинуса

, например: Если я следующие две матрицы, и я хочу, чтобы вычислить косинуса сходство это не работает, как строки не одинаковы в длину

doc 1 
1 2 3 
4 5 6 

doc 2 
1 2 3 4 5 6 
7 8 5 2 4 9 

если строки и colums одинаковы по длине, то моя программа работает очень хорошо, но это не делает, если строки и столбцы не в одинаковой длины.

Любые советы ???

ответ

3

Я не уверен в своей реализации, но cosine distance двух векторов равно нормированному точечному произведению этих векторов.

Точечный продукт двух матриц может быть выражен как a. b = a T b. В результате, если матрица имеет разную длину, вы не можете взять точечный продукт для идентификации косинуса.

Теперь в стандартном подходе TF * IDF термины в вашей матрице должны быть проиндексированы term, document, в результате любые термины, не появляющиеся в документе, должны отображаться как нули в вашей матрице.

Теперь, как вы его создали, кажется, что есть два разных матрицы для ваших двух документов. Я не уверен, что это ваше намерение, но оно кажется неправильным.

С другой стороны, если одна из ваших матриц должна быть вашим запросом, то она должна быть вектором, а не матрицей, так что транспонирование дает правильный результат.

Полное объяснение TF * IDF следующим образом:

Хорошо, в классическом TF * IDF вы построить матрицу терм-документ a. Каждое значение в матрице a характеризуется как i, j, где i является термином и j является документом. Это значение представляет собой комбинацию локальных, глобальных и нормализованных весов (хотя, если вы нормализуете свои документы, нормализованный вес должен быть 1). Таким образом, I, J = F I, J * D/D я, где F I, J частота слова i в док j, D является размер документа, и г я это количество документов с термином i.

Ваш запрос - это вектор терминов, обозначенных как b. Для каждого термина b i, q в вашем запросе относится к термину i для запроса q. б I, Q = F I, Q, где F I, Q частота термина i в запросе q. В этом случае каждый запрос представляет собой вектор, а несколько запросов образуют матрицу.

Затем мы можем рассчитать единичные векторы каждого из них, так что, когда мы возьмем точечный продукт, он произведет правильный косинус. Для достижения единичного вектора мы разделим как матрицу a, так и запрос b на их Frobenius norm.

Наконец, мы можем выполнить косинус-расстояние, взяв транспонирование вектора b для данного запроса. Таким образом, один запрос (или вектор) вычисляется. Это обозначается как b T a. Конечным результатом является вектор с оценкой для каждого члена, где более высокий балл обозначает более высокий ранг документа.

+0

Спасибо за ваш ответ. Да, моя первая матрица - это запрос. Что такое diff. между запросом и вектором? разве они почти такие же? Я использую один документ в качестве запроса, а второй - как цель. Именно по этой причине я вычисляю tf * idf для цели отдельно и tf * idf для запроса. Я не могу использовать transponse coz, я точно не знаю, какие числа столбцов и строк будут. Это просто пример :). Не могли бы вы объяснить немного больше, как я могу решить свою проблему? Должен ли я создать один tf * idf для запроса и цели? если да, то как я буду вычислять косинус? – user238384

+0

Я постараюсь добавить к моему ответу – tzenes

+0

@agazerboy было достаточно или вам нужно больше объяснений? – tzenes

3

простой Java косинус сходство

static double cosine_similarity(Map<String, Double> v1, Map<String, Double> v2) { 
      Set<String> both = Sets.newHashSet(v1.keySet()); 
      both.removeAll(v2.keySet()); 
      double sclar = 0, norm1 = 0, norm2 = 0; 
      for (String k : both) sclar += v1.get(k) * v2.get(k); 
      for (String k : v1.keySet()) norm1 += v1.get(k) * v1.get(k); 
      for (String k : v2.keySet()) norm2 += v2.get(k) * v2.get(k); 
      return sclar/Math.sqrt(norm1 * norm2); 
    } 
Смежные вопросы