Латентный семантический анализ в расхождениях 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 пожаловался.