ANTsX / ANTs

Advanced Normalization Tools (ANTs)
Apache License 2.0
1.16k stars 375 forks source link

Negative correlations with sparseDecom2 #741

Closed rosebruf closed 2 days ago

rosebruf commented 5 years ago

Hello, I'm am using sCCAn to explore the correlation between errors and atrophy. A priori, I know this correlation should be negative: more errors correlates with less volume. However, sparseDecom2 converges to positive correlations. Is it possible to specify that I am only interested in negative correlations and reject positive correlations with the eigenvectors? Thanks for your help, Rose

stnava commented 5 years ago

i recommend reading through this discussion:

https://github.com/dorianps/LESYMAP/issues/11

because SCCAN rescales the data, you need to check the outside of SCCAN correlations by doing:

cor( originalDataX %% abs( canonicalVariatesX ), originalDataY %% abs( canonicalVariatesY ) )

there might also be useful information here:

https://github.com/ntustison/BrianSccanTutorial

finally, ANTsR is an easier way to do all this.

brian

On Fri, Mar 22, 2019 at 8:00 AM rosebruf notifications@github.com wrote:

Hello, I'm am using sCCAn to explore the correlation between errors and atrophy. A priori, I know this correlation should be negative: more errors correlates with less volume. However, sparseDecom2 converges to positive correlations. Is it possible to specify that I am only interested in negative correlations and reject positive correlations with the eigenvectors? Thanks for your help, Rose

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ANTsX/ANTs/issues/741, or mute the thread https://github.com/notifications/unsubscribe-auth/AATyfnB7yvLO8TaWCI3dHuqKZBjxRmPPks5vZMXzgaJpZM4cDa-2 .

dorianps commented 5 years ago

The correlation itself doesn't mean much, it is the weights of each side combined with the correlation which tell the direction. This is an example how I think of it if A and B are the two sides:

A weights positive, B weights positive, ccasummary positive = positive relationship A weights negative, B weights negative, ccasummary positive = positive relationship A weights positive, B weights negative, ccasummary positive = negative relationship A weights positive, B weights negative, ccasummary negative = positive relationship and so on.

Think that negative weights flip the direction, you should think of the data inverted after that point.

Dorian

On Fri, Mar 22, 2019 at 8:23 AM stnava notifications@github.com wrote:

i recommend reading through this discussion:

https://github.com/dorianps/LESYMAP/issues/11

because SCCAN rescales the data, you need to check the outside of SCCAN correlations by doing:

cor( originalDataX %% abs( canonicalVariatesX ), originalDataY %% abs( canonicalVariatesY ) )

there might also be useful information here:

https://github.com/ntustison/BrianSccanTutorial

finally, ANTsR is an easier way to do all this.

brian

On Fri, Mar 22, 2019 at 8:00 AM rosebruf notifications@github.com wrote:

Hello, I'm am using sCCAn to explore the correlation between errors and atrophy. A priori, I know this correlation should be negative: more errors correlates with less volume. However, sparseDecom2 converges to positive correlations. Is it possible to specify that I am only interested in negative correlations and reject positive correlations with the eigenvectors? Thanks for your help, Rose

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ANTsX/ANTs/issues/741, or mute the thread < https://github.com/notifications/unsubscribe-auth/AATyfnB7yvLO8TaWCI3dHuqKZBjxRmPPks5vZMXzgaJpZM4cDa-2

.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ANTsX/ANTs/issues/741#issuecomment-475601039, or mute the thread https://github.com/notifications/unsubscribe-auth/AIqafVpuLREd5dFiTMV3cXv1fhR-zsBzks5vZMsmgaJpZM4cDa-2 .

stnava commented 5 years ago

yes - @dorianps is correct

just note that this also assumes you've restricted weights to be unsigned ( that is the most common case )

brian

On Fri, Mar 22, 2019 at 10:39 AM dorianps notifications@github.com wrote:

The correlation itself doesn't mean much, it is the weights of each side combined with the correlation which tell the direction. This is an example how I think of it if A and B are the two sides:

A weights positive, B weights positive, ccasummary positive = positive relationship A weights negative, B weights negative, ccasummary positive = positive relationship A weights positive, B weights negative, ccasummary positive = negative relationship A weights positive, B weights negative, ccasummary negative = positive relationship and so on.

Think that negative weights flip the direction, you should think of the data inverted after that point.

Dorian

On Fri, Mar 22, 2019 at 8:23 AM stnava notifications@github.com wrote:

i recommend reading through this discussion:

https://github.com/dorianps/LESYMAP/issues/11

because SCCAN rescales the data, you need to check the outside of SCCAN correlations by doing:

cor( originalDataX %% abs( canonicalVariatesX ), originalDataY %% abs( canonicalVariatesY ) )

there might also be useful information here:

https://github.com/ntustison/BrianSccanTutorial

finally, ANTsR is an easier way to do all this.

brian

On Fri, Mar 22, 2019 at 8:00 AM rosebruf notifications@github.com wrote:

Hello, I'm am using sCCAn to explore the correlation between errors and atrophy. A priori, I know this correlation should be negative: more errors correlates with less volume. However, sparseDecom2 converges to positive correlations. Is it possible to specify that I am only interested in negative correlations and reject positive correlations with the eigenvectors? Thanks for your help, Rose

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ANTsX/ANTs/issues/741, or mute the thread <

https://github.com/notifications/unsubscribe-auth/AATyfnB7yvLO8TaWCI3dHuqKZBjxRmPPks5vZMXzgaJpZM4cDa-2

.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ANTsX/ANTs/issues/741#issuecomment-475601039, or mute the thread < https://github.com/notifications/unsubscribe-auth/AIqafVpuLREd5dFiTMV3cXv1fhR-zsBzks5vZMsmgaJpZM4cDa-2

.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ANTsX/ANTs/issues/741#issuecomment-475646111, or mute the thread https://github.com/notifications/unsubscribe-auth/AATyfnDh0kraDT24T5rvirNz_lNs_EEeks5vZOsfgaJpZM4cDa-2 .

dorianps commented 5 years ago

The same should be true with signed weights, right? The weight sign on each side combined with ccasummary should give the relationship bw a voxel on side A and a voxel on side B, unless I am missing something.

stnava commented 5 years ago

no - it's not the same.

it's more like this:

correlation( A_1 - A_2 , B_1 - B_2 )

ie looking at correlations between pattern differences.

brian

On Fri, Mar 22, 2019 at 10:46 AM dorianps notifications@github.com wrote:

The same should be true with signed weights, right? The weight sign on each side combined with ccasummary should give the relationship bw a voxel on side A and a voxel on side B, unless I am missing something.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ANTsX/ANTs/issues/741#issuecomment-475648942, or mute the thread https://github.com/notifications/unsubscribe-auth/AATyftjon4qIyBNZFcepHRnVlky0HdqDks5vZOzdgaJpZM4cDa-2 .

dorianps commented 5 years ago

What are A_1 and A_2 in this case, different components?

stnava commented 5 years ago

should have written it like this:

correlation( A_pos - A_neg , B_pos - B_neg )

where A is a single component from modality A and B is a single component from modality B

A_pos would be the positively signed part , etc

brian

On Fri, Mar 22, 2019 at 11:30 AM dorianps notifications@github.com wrote:

What are A_1 and A_2 in this case, different components?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ANTsX/ANTs/issues/741#issuecomment-475665885, or mute the thread https://github.com/notifications/unsubscribe-auth/AATyfmSCcv2c26sHskzN7MNX6_OIjr6Sks5vZPcxgaJpZM4cDa-2 .

dorianps commented 5 years ago

I am a bit confused, maybe I should read more. My understanding is that, no matter what sparseness we choose (positive or negative, signed vs. unsigned weights), the canonical correlation would be:

correlation( voxel value A weights A, voxel values B weights B )

That is, just applying the weights on each side to get a component, and then correlate the components.

This is the picture I use to explain things on my slides (weights can be positive or negative): image

stnava commented 5 years ago

If you just think about the mathematics of it you will see that the two things are equivalent, one of the first Eigenanatomy papers discusses this

On Fri, Mar 22, 2019 at 12:03 PM dorianps notifications@github.com wrote:

I am a bit confused, maybe I should read more. My understanding is that, no matter what sparseness we choose (positive or negative, signed vs. unsigned weights), the canonical correlation would be:

correlation( voxel value A weights A, voxel values B weights B )

That is, just applying the weights on each side to get a component, and then correlate the components.

This is the picture I use to explain things on my slides (weights can be positive or negative): [image: image] https://user-images.githubusercontent.com/9083517/54836312-55d1d400-4c9a-11e9-8821-01545278f663.png

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/ANTsX/ANTs/issues/741#issuecomment-475678099, or mute the thread https://github.com/notifications/unsubscribe-auth/AATyfsUrGeN2jlClugzHsF1SpVpRr7DYks5vZP61gaJpZM4cDa-2 .

--

brian

dorianps commented 5 years ago

Ok, good to know we are on the same page. But by this example, any relationship between A and B columns can be found simply by knowing the weight signs and the sign of ccasummary. Meaning that it shouldn't matter if weights are signed. The application of the simple rules we mentioned earlier should be sufficient to know the direction of relationship between a column in A and a column in B.

Thanks. Dorian

stnava commented 5 years ago

that's not correct. it is easy to construct a counter example. but the main reason its wrong is that directionality does not make sense when the weights are signed.

On Fri, Mar 22, 2019 at 12:49 PM dorianps notifications@github.com wrote:

Ok, good to know we are on the same page. But by this example, any relationship between A and B columns can be found simply by knowing the weight signs and the sign of ccasummary. Meaning that it shouldn't matter if weights are signed. The application of the simple rules we mentioned earlier should be sufficient to know the direction of relationship between a column in A and a column in B.

Thanks. Dorian

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ANTsX/ANTs/issues/741#issuecomment-475694888, or mute the thread https://github.com/notifications/unsubscribe-auth/AATyfm13NwhqhwtWGaVMG5KfN3VtBXDeks5vZQl_gaJpZM4cDa-2 .

dorianps commented 5 years ago

Maybe we can have a chat about this approach. So far I have allowed LESYMAP to search for negative sparseness (aka signed weights) and things seem to work well (also matching the outputs of an SVR approach). The computation I use to predict behavior using voxel weights is here.

dorianps commented 5 years ago

And this is the code I use to orient the weights of voxels in the correct relationship with behavior, related to this topic. https://github.com/dorianps/LESYMAP/blob/master/R/lsm_sccan.R#L211-L214

stnava commented 5 years ago

SCCAN will work regardless of whether you constrain the weights to be signed or not ... but the directionality is not a meaningful concept here because of this: https://blogs.sas.com/content/iml/2017/08/07/eigenvectors-not-unique.html

furthermore, when eigenvectors are signed, we can effectively interpret them as measuring differences between regions. so it is not "higher A relates to higher B" it is " the difference between region_1 in A and region_2 in A are related to higher B" or maybe even "the difference between region_1 in A and region_2 in A are related to the difference between region_3 in B and region_4 in B"

dorianps commented 5 years ago

Thanks for following up.

In the LESYMAP case we have (e.g.) 100,000 columns on one side (voxels) and 1 column on the other side (behavior), which should at least resolve the complication of having multiple regions in B. I am not thinking that the magnitude of voxel weights can tell me the degree of relationship with behavior for the reason you mention above, but at least those weight signs, combined with the correlation sign, and with the behavior weight sign, should tell me the direction of relationship between a voxel and behavior. That is, at least know that, after flipping the sign of the weights correctly with respect to behavior with the above code, someone can take a negative weight and say that that the increase of signal in that voxel is inversely related to the increase in behavior scores.

Remember, this is all done to match the sign of traditional univariate scores (i.e., t-scores) with the sign of SCCAN weights so that at least voxel signs have a similar meaning in univariate and multivariate analysis. Sorry for returning to this topic again and again but I need to figure out if something is wrong in the LESYMAP code, or if a completely different approach must be taken, i.e., your proposal of using 2 components to split the eventual positive and negative sides (but I suspect that I would need to flip the signs with the above code in that case, too).

stnava commented 5 years ago

i see your point but i think you are wrong. here is an example:

set.seed( 99099 )
n = 50
p = 500
voxels = matrix( rnorm( n * p , 0, 1 ) , nrow = n )
inds1 = sample( 1:p )[1:10]
inds2 = sample( 1:p )[1:10]
behavior = rowMeans( voxels[ , inds1 ]  - voxels[ , inds2 ] )  
cor( behavior, voxels[ , inds1 ]  )
cor( behavior, voxels[ , inds2 ]  )

if you look at the individual voxel correlations, they are not necessarily related to behavior. it is the collection and full set of differences that matters.

the larger the number of voxels, the more complicated this gets.

dorianps commented 5 years ago

I assume the problem with example you showed is that all inds2 voxels should be negatively correlated with behavior, most of which are but not all. Got the point. SCCAN however smooths the weights in internal iterations, maybe part of this problem is mitigated. I also ran SCCAN on your example and each time I run I see no problem. All weights that are supposed to be positive are positive (or zero), and vice versa all supposedly negatives are negative.


library(ANTsR)
set.seed( 199099 )
n = 50
p = 500
voxsample = 10
voxels = matrix( rnorm( n * p , 0, 1 ) , nrow = n )

# first half region A, second half region B
inds1 = sample( 1:(p/2) )[1:voxsample] # voxel samples A
inds2 = sample( (p/2+1):p )[1:voxsample] # voxel samples B

voxmat = cbind(voxels[ , inds1 ] , voxels[ , inds2 ])
behavior = cbind( rowMeans( voxels[ , inds1] - voxels[ , inds2] ) )

sccan = sparseDecom2(inmatrix = list(voxels, behavior), inmask = c(NA,NA),
                     nvecs = 1, sparseness = c(-0.2, -0.99), its = 20, robust = 1)

sccan$eig1[inds1]
sccan$eig1[inds2]
sccan$eig2
sccan$ccasummary
stnava commented 5 years ago

No guarantee that there will be a correlation at all ,,, If you look at the example results you will see that even the best voxel level correlations are much lower than the ground truth which is a correlation of one. Many are very close to zero.

Therefore you cannot conclude what you claimed to be able to conclude before.

On Tue, Mar 26, 2019 at 2:15 PM dorianps notifications@github.com wrote:

I assume the problem with example you showed is that all inds2 voxels should be negatively correlated with behavior, most of which are but not all. Got the point. SCCAN however smooths the weights in internal iterations, maybe part of this problem is mitigated. I also ran SCCAN on your example and each time I run I see no problem. All weights that are supposed to be positive are positive (or zero), and vice versa all supposedly negatives are negative.

library(ANTsR) set.seed( 199099 ) n = 50 p = 500 voxsample = 10 voxels = matrix( rnorm( n * p , 0, 1 ) , nrow = n )

first half region A, second half region B

inds1 = sample( 1:(p/2) )[1:voxsample] # voxel samples A inds2 = sample( (p/2+1):p )[1:voxsample] # voxel samples B

voxmat = cbind(voxels[ , inds1 ] , voxels[ , inds2 ]) behavior = cbind( rowMeans( voxels[ , inds1] - voxels[ , inds2] ) )

sccan = sparseDecom2(inmatrix = list(voxels, behavior), inmask = c(NA,NA), nvecs = 1, sparseness = c(-0.2, -0.99), its = 20, robust = 1)

sccan$eig1[inds1] sccan$eig1[inds2] sccan$eig2 sccan$ccasummary

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/ANTsX/ANTs/issues/741#issuecomment-476781941, or mute the thread https://github.com/notifications/unsubscribe-auth/AATyfr6zIrz6Qb405RwoOWOln4iIDR9bks5vamPPgaJpZM4cDa-2 .

--

brian