0
$\begingroup$

I want to find the optimal weights so that the pairwise Euclidean distances in my training dataset are closest possible to the differences in ordinal rankings. In other words, I want to train the weights to increase the rate of correct classifications based on nearest neighbour. There are a numbers of issues here: (1) which distance metric is best to evaluate the similarity of two ordinal rankings, (2) how best to transform the pairwise Euclidean distances into a comparable ordinal ranking, and (3) which optimization model to use.

The objective of this exercise is to provide a simple and intuitive method to improve correct classifications in a clustering algorithm. I do not want to add further assumptions to the model at this stage, for instance by defining the number of clusters.

For (1) I have used the Normalized Discounted Cumulative Gain as the simpler Kendall distance does not penalize for large deviations between the rankings. The issue with the current code is that the chosen optimization model fails to find a global optimum (3), in part due to issues on how the scaling is applied in (2) that provides a biased output in (1).

Let's assume a training dataset 'data' containing in the first column the ids of the entities to classify, in the second their ordinal ranking, and in the p+2 columns their features.

library(rrecsys)

WF <- function(weights, data) {   ## function to optimise
  weightedData <- as.matrix(data[,-c(1,2)]) %*% diag(weights) # weigh each dimension
  distMatrix <- as.matrix(dist(weightedData, method = "euclidean")) # Euclidean distance matrix
  distMatrix <- stack(as.data.frame(distMatrix)) # long format
  rankMatrix <- matrix(data[,2],nrow=dim(data)[[1]],ncol=dim(data)[[1]],byrow=TRUE) # turn ordinal rankings into pairwise matrix
  rankDifferentiationMatrix <- abs(rankMatrix-t(rankMatrix)) # substract pairwise and create new ranking on relative distances
  rankDifferentiation <- stack(as.data.frame(rankDifferentiationMatrix)) # long format
  output <- as.data.frame(cbind(rankDifferentiation[,1], distMatrix[,1])) # merge
  output<- output[which(output[,1] != 0 | output[,2] != 0),] # remove diagonal
  output <- unique(output) # remove upper triangle
  output[,1] <- round(((1-output[,1])^2)^(0.5)/max(output[,1]),2) # scale ranking to 0-1
  output[,2] <- round(((1-output[,2])^2)^(0.5)/max(output[,2]),2) # scale pairwise distances to 0-1
  DCG <- eval_nDCG(output[,1], output[,2]) # Normalized Discounted Cumulative Gain
  return(1-DCG)
}

OptWeights <- optim(par=rep(1,p),fn=WF, data=data) # Find optimal weights
$\endgroup$
2
  • 1
    $\begingroup$ Distance between ordinal ranking looks can be gaged through Spearman's correlation coefficient (rho), which is implemented in cor() with method = "spearman". $\endgroup$
    – csgroen
    Commented Jul 9, 2020 at 13:11
  • $\begingroup$ That solves (2) and (3) but I still have issues with the optimization model (1) that converges on a local minimum that performs worse than the equally distributed weights (ie: naive). Any suggestions? $\endgroup$
    – Marc F
    Commented Jul 10, 2020 at 11:25

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.