Латентный семантический анализ в расхождениях Python

Я пытаюсь следовать статье Википедии о скрытой семантической индексации в Python, используя следующий код:

documentTermMatrix = array([[ 0.,  1.,  0.,  1.,  1.,  0.,  1.],
                            [ 0.,  1.,  1.,  0.,  0.,  0.,  0.],
                            [ 0.,  0.,  0.,  0.,  0.,  1.,  1.],
                            [ 0.,  0.,  0.,  1.,  0.,  0.,  0.],
                            [ 0.,  1.,  1.,  0.,  0.,  0.,  0.],
                            [ 1.,  0.,  0.,  1.,  0.,  0.,  0.],
                            [ 0.,  0.,  0.,  0.,  1.,  1.,  0.],
                            [ 0.,  0.,  1.,  1.,  0.,  0.,  0.],
                            [ 1.,  0.,  0.,  1.,  0.,  0.,  0.]])
u,s,vt = linalg.svd(documentTermMatrix, full_matrices=False)

sigma = diag(s)
## remove extra dimensions...
numberOfDimensions = 4
for i in range(4, len(sigma) -1):
    sigma[i][i] = 0
queryVector = array([[ 0.], # same as first column in documentTermMatrix
                     [ 0.],
                     [ 0.],
                     [ 0.],
                     [ 0.],
                     [ 1.],
                     [ 0.],
                     [ 0.],
                     [ 1.]])

Как математика говорит, что это должно работать:

dtMatrixToQueryAgainst = dot(u, dot(s,vt))
queryVector = dot(inv(s), dot(transpose(u), queryVector))
similarityToFirst = cosineDistance(queryVector, dtMatrixToQueryAgainst[:,0]
# gives 'matrices are not aligned' error.  should be 1 because they're the same

Что работает, с математикой, которая выглядит неправильно: ( отсюда)

dtMatrixToQueryAgainst = dot(s, vt)
queryVector  = dot(transpose(u), queryVector)
similarityToFirst = cosineDistance(queryVector, dtMatrixToQueryAgainsst[:,0]) 
# gives 1, which is correct

Почему работает маршрут, а первый - нет, когда все, что я могу найти в математике АЛП, показывает первый как правильный? Я чувствую, что упускаю что-то очевидное...

1 ответ

Решение

В вашем коде есть несколько несоответствий, которые приводят к ошибкам до вашей путаницы. Это затрудняет точное понимание того, что вы пытались и почему вы сбиты с толку (очевидно, вы не выполняли код в том виде, в котором он был вставлен, или он бы вызвал исключение ранее).

Тем не менее, если я буду правильно следовать вашим намерениям, ваш первый подход будет почти правильным. Рассмотрим следующий код:

documentTermMatrix = array([[ 0.,  1.,  0.,  1.,  1.,  0.,  1.],
                            [ 0.,  1.,  1.,  0.,  0.,  0.,  0.],
                            [ 0.,  0.,  0.,  0.,  0.,  1.,  1.],
                            [ 0.,  0.,  0.,  1.,  0.,  0.,  0.],
                            [ 0.,  1.,  1.,  0.,  0.,  0.,  0.],
                            [ 1.,  0.,  0.,  1.,  0.,  0.,  0.],
                            [ 0.,  0.,  0.,  0.,  1.,  1.,  0.],
                            [ 0.,  0.,  1.,  1.,  0.,  0.,  0.],
                            [ 1.,  0.,  0.,  1.,  0.,  0.,  0.]])
numDimensions = 4
u, s, vt = linalg.svd(documentTermMatrix, full_matrices=False)
u = u[:, :numDimensions]
sigma = diag(s)[:numDimensions, :numDimensions]
vt = vt[:numDimensions, :]
lowRankDocumentTermMatrix = dot(u, dot(sigma, vt))
queryVector = documentTermMatrix[:, 0]
lowDimensionalQuery = dot(inv(sigma), dot(u.T, queryVector))
lowDimensionalQuery
vt[:,0]

Вы должны увидеть это lowDimensionalQuery а также vt[:,0] равны. Думать о vt как представление документов в низкоразмерном подпространстве. Сначала мы отображаем наш запрос в это подпространство, чтобы получить lowDimensionalQuery, а затем мы сравниваем его с соответствующим столбцом vt, Ваша ошибка была при попытке сравнить преобразованный запрос с вектором документа из lowRankDocumentTermMatrix, который живет в оригинальном пространстве. Поскольку в преобразованном запросе меньше элементов, чем в "восстановленном" документе, Python пожаловался.

Другие вопросы по тегам