How to calculate distance from center of a hypersphere (whitened PCA) - linear-algebra

Lets say that I have calculated the principal components of a reference data set including whitening. The transformation matrix created from the principal component vectors is then applies to a test data set, projecting it onto the subspace of PCs. Now, I should be able to measure the distance of each of the test data vectors from the center of the PC hypersphere by simply adding up the coefficients of each column. Is this correct? Applying this transformation to my reference data gives a length of zero for all columns, and the length of the vectors seems to decrease as I make the test data look more like the reference data and grows as I make the two sets more distinct.
Am I correct that I can judge "distance" in a multidimensional space in this way? Is it just the sum of the coefficients of the projected matrix?
Thanks very much for any insight you can provide.

Distance is not a linear sum, and it is never zero (outside the origin). It is computed as:
distance(x) = square_root( sum ( x(i)^2 ) )
If this was not what you where looking for, please expand your question and include some code and examples.

Related

Calculating just a single row of dissimilarity/distance matrix

I have a data-frame with 30k rows and 10 features. I would like to calculate distance matrix like below;
gower_dist <- daisy(data-frame, metric = "gower"),
This function returns whole dissimilarity matrix. I want to get just the first row.
(Just distances of the first element in data-frame). How can I do it? Do you have an idea?
You probably need to get the source and extend it.
I suggest you extend the API by adding a second parameter y that defaults to x. Then the method should return the pairwise distances of each element in x to each element in y.
Fortunately, R is GPL open source, so this is easy.
This would likely be a welcome extension, you should submit it to the package authors for inclusion.

How to "adjust" a data set so that the total sum is equal to 1. (I thought I knew the correct term for this)

I apologize ahead of time for the crude way this question is worded. I was under the impression for the longest time that what I'm trying to do is called "Normalizing data" but after googling to try and find the method to do this, I seem to be mistaken so I'm not sure exactly what it's called that I'm trying to do (bear with me please).
I have a set of data like this:
0.17407
0.05013
0.08520
0.02892
0.02986
0.06286
0.04453
0.00425
0.20470
0.02267
0.01470
0.02460
0.01735
0.01069
0.02168
0.13912
0.02004
0.02018
0.07837
When you add them all you get 1.05392.
I'd like to "adjust" the data set so that the relative values all remain the same but the sum is equal to 1. When I googled normalizing data sets, I found a formula like this:
(x-min(x))/(max(x)-min(x))
However, this simply "ranks" each data point as a certain percentage of the maximum value so that your max value in your data set is equal to 1 and the minimum, 0.
Extra: Could someone enlighten me what this is called if not normalizing data. Obviously I've been carrying around this ignorant belief for far too long.
If you want your data to sum to 1 you normalize your data. You normalize by dividing by the sum of you series (sum_i x_i, where x_i are the elements of your data series).
The formula you mention is another possible rescaling, but as you observed it has a different effect. Note that in the first case you map x -> c*x (in your case: x -> 1/1.05392*x), while the second case rescales with x -> c*x + offset. Note also, that the later is not linear (unless min(x) = 0), that is f(x+y) != f(x) + f(y).
If your whole confusion is about the naming of things, than I would not worry to much. After all there is only convention and common agreement, but no absolute truth/authority. And the terms are reused in different fields, cf. Normalization on Wikipedia:
Normalization or normalisation refers to a process that makes something more normal or regular

Cortest.mat converting to class "psych,sim"

I've been using the psych package to compare two correlation matrices using the function cortest.
Now I want to try the cortest.mat and cortest.jennrich function which require an object of the class phychand sim. I have tried converting mi correlation matrices with sim.structure which results in an object of such classes but I get an error when running either function.
Here is what I've tried using Random numbers:
Random<-cor(matrix(rnorm(400, 0, .25), nrow=(20), ncol=(20)))
SimRandom<-sim.structure(Random)
class(SimRandom)
cortest.jennrich(SimRandom,SimRandom,n1=400, n2=400)
Yields the following:
Error in if (dim(R1)[1] != p) { : argument is of length zero
I sure I'm doing it wrong 'cause of the error message and 'cause the values in Random and SimRandom are not exactly the same.
Which is the correct way to translate a correlation matrix to a type -phych, sim- to use as input for running cortest.mat?
Thanks in advance.
EDIT: Short explanation on what I want to do. Using Random numbers serves just as an example. The actual correlation matrices to compare are done as follows. I have a huge list of files each composed of 100 observations for a specific genetic location. These files can be grouped into say 20 files based on known genetic relationships, thus I use those groups of files, load them into a matrix as columns and calculate cor(). That gives a correlation matrix. As a control I load random files and treat them the same way. This matrix contains real data, but the grouping is done randomly. In the end I have two correlation matrices 1-That contains the correlations of pre-selected files and 2- that contains the correlations between randomly loaded files. Both matrices are the same size.
What I would like to do is to compare the two correlation matrices to have an idea whether the grouping has an influence on the correlation values observed.
Sorry for not explaining this earlier, I wanted to avoid the long explanation and keep the question simple.

How to add weight to attribute inside feature vector for distance measure?

I am attempting to measure the distance between two feature vectors, but I want to give more importance to one attribute inside the feature vector beyond the rest. For example, if the vector I had below were filled with numeric features, how would I place more value on "taste"?
V = [ Taste, Smell, Feel, Look ]
I know I could just isolate that value and perform the distance measure on that, but I wasn't sure if that were the best way and if I would lose the "rest of the picture" by doing so. When I search for weighted distance measures, I tend to land on pages where the weight is just being used for normalization or standardization of the data which doesn't appear to carry the same meaning as what I would like.
Am I better off using the distance measure on the full vector and then applying something like KNN with weights later on?
I think you can try matrix multiply means you can give a weight matrix and just multiply this weight matrix with your data.

Creating a correlation matrix using novel distance function

I'm trying to write a function that will create a correlation matrix using a fancy distance estimate (dcorr, Brownian distance). More generally, I want to write code for a generic "correlation" matrix in which you can plug in any distance estimator.
My data is formatted such that columns are variables and rows are observations.
I'm having problems with my basic code. My algorithm is as follows:
Use apply to take a variable
Pass to function that will again take apply on the entire matrix
At this point you should have two pairs of variables
Use na.omit to remove missing observations (necessary for dcorr)
Calculate dcorr
I was hoping this would result in the correlation matrix but I'm having a lot of problems with basic variable managment. I'm having difficulty passing variables to the apply function. In particular, I want to pass a the column that was pulled in the first apply and pass it to the second apply (that is applied on the entire original matrix)
My code:
dcormatrix <- function(Matrix){
dcorhelper <- function (Col1){
as.matrix(apply(Matrix,2,function(Col2){
B <- na.omit(cbind(Col1,Col2))
dcor(B[,1],B[,2],index=1)
},Col1=Col1))
}
apply(Matrix,2,dcorhelper(),Matrix=Matrix)
}
Any ideas? I'm sure there's gotta be an easy way to do this.
You may want to check out designdist from the vegan package. It allows one to define alternate distance / dissimilarity matrices. See here.

Resources