Testen auf lineare Abhängigkeit zwischen den Spalten einer Matrix

26

Ich habe eine Korrelationsmatrix von Sicherheitsrenditen, deren Determinante Null ist. (Dies ist ein wenig überraschend, da die Stichprobenkorrelationsmatrix und die entsprechende Kovarianzmatrix theoretisch eindeutig positiv sein sollten.)

Meine Hypothese ist, dass mindestens ein Wertpapier linear von anderen Wertpapieren abhängig ist. Gibt es eine Funktion in R, die nacheinander für jede Spalte eine Matrix auf lineare Abhängigkeit prüft?

Ein Ansatz wäre beispielsweise, eine Korrelationsmatrix nacheinander aufzubauen und die Determinante bei jedem Schritt zu berechnen. Wenn die Determinante = 0 ist, hören Sie auf, da Sie das Wertpapier identifiziert haben, bei dem es sich um eine lineare Kombination anderer Wertpapiere handelt.

Beliebige andere Techniken zum Identifizieren der linearen Abhängigkeit in einer solchen Matrix sind erwünscht.

Ram Ahluwalia
quelle
Ihre Matrix ist positiv, aber nicht positiv, denn sie ist singulär.
ttnphns
Was sind die Dimensionen (Nr. Variablen; Nr. Proben)?
Karl
Anzahl der Spalten = 480. Anzahl der Zeilen für jede Zeitreihe = 502. Im Allgemeinen ist die Kovarianzmatrix der Stichprobe mit zunehmender Zeitreihe tendenziell positiv. Es gibt jedoch viele Fälle, in denen Sie einen wesentlich kleineren Wert von T (oder ein exponentielles Gewicht) verwenden möchten, um die aktuellen Marktbedingungen widerzuspiegeln.
Ram Ahluwalia
3
Die Frage ist schlecht gestellt. Wenn Ihre Datenmatrix 480 mal 502 ist, entspricht die Aussage, dass die Matrix den Rang (der Spaltenraum der Matrix hat die Dimension ) mathematisch der Aussage, dass eine Spalte eine lineare Kombination der anderen ist, aber Sie können Wählen Sie nicht eine Spalte aus und sagen Sie, dass dies die Spalte ist, die linear abhängig ist. Daher gibt es keine Vorgehensweise, und die vorgeschlagene Vorgehensweise wählt abhängig von der Reihenfolge, in der sie enthalten sind, eine recht willkürliche Sicherheit. q < 480q<480q<480
NRH
Die Kovarianzmatrix ist symmetrisch. Es wird durch transponieren (A) * A erzeugt. Die Matrix A hat die Abmessungen 480x502. Die Kovarianzmatrix ist jedoch 480x480
Ram Ahluwalia

Antworten:

6

Sie scheinen eine wirklich herausfordernde Frage zu stellen: Wie lässt sich bei einer singulären Korrelations- (oder Kovarianz- oder Quadratsummen- und Kreuzprodukt-) Matrix feststellen, welche Spalte linear von welcher abhängt? Ich nehme vorläufig an, dass eine Kehroperation helfen könnte. Hier ist meine Sonde in SPSS (nicht R) zu veranschaulichen.

Lassen Sie uns einige Daten generieren:

        v1        v2        v3         v4          v5
    -1.64454    .35119   -.06384    -1.05188     .25192
    -1.78520   -.21598   1.20315      .40267    1.14790
     1.36357   -.96107   -.46651      .92889   -1.38072
     -.31455   -.74937   1.17505     1.27623   -1.04640
     -.31795    .85860    .10061      .00145     .39644
     -.97010    .19129   2.43890     -.83642    -.13250
     -.66439    .29267   1.20405      .90068   -1.78066
      .87025   -.89018   -.99386    -1.80001     .42768
    -1.96219   -.27535    .58754      .34556     .12587
    -1.03638   -.24645   -.11083      .07013    -.84446

Erstellen wir eine lineare Abhängigkeit zwischen V2, V4 und V5:

compute V4 = .4*V2+1.2*V5.
execute.

Also haben wir unsere Spalte V4 modifiziert.

matrix.
get X. /*take the data*/
compute M = sscp(X). /*SSCP matrix, X'X; it is singular*/
print rank(M). /*with rank 5-1=4, because there's 1 group of interdependent columns*/
loop i= 1 to 5. /*Start iterative sweep operation on M from column 1 to column 5*/
-compute M = sweep(M,i).
-print M. /*That's printout we want to trace*/
end loop.
end matrix.

Die Ausdrucke von M in 5 Iterationen:

M
     .06660028    -.12645565    -.54275426    -.19692972    -.12195621
     .12645565    3.20350385    -.08946808    2.84946215    1.30671718
     .54275426    -.08946808    7.38023317   -3.51467361   -2.89907198
     .19692972    2.84946215   -3.51467361   13.88671851   10.62244471
     .12195621    1.30671718   -2.89907198   10.62244471    8.41646486

M
     .07159201     .03947417    -.54628594    -.08444957    -.07037464
     .03947417     .31215820    -.02792819     .88948298     .40790248
     .54628594     .02792819    7.37773449   -3.43509328   -2.86257773
     .08444957    -.88948298   -3.43509328   11.35217042    9.46014202
     .07037464    -.40790248   -2.86257773    9.46014202    7.88345168

M
    .112041875    .041542117    .074045215   -.338801789   -.282334825
    .041542117    .312263922    .003785470    .876479537    .397066281
    .074045215    .003785470    .135542964   -.465602725   -.388002270
    .338801789   -.876479537    .465602725   9.752781632   8.127318027
    .282334825   -.397066281    .388002270   8.127318027   6.772765022

M
   .1238115070   .0110941027   .0902197842   .0347389906   .0000000000
   .0110941027   .3910328733  -.0380581058  -.0898696977  -.3333333333
   .0902197842  -.0380581058   .1577710733   .0477405054   .0000000000
   .0347389906  -.0898696977   .0477405054   .1025348498   .8333333333
   .0000000000   .3333333333   .0000000000  -.8333333333   .0000000000

M
   .1238115070   .0110941027   .0902197842   .0347389906   .0000000000
   .0110941027   .3910328733  -.0380581058  -.0898696977   .0000000000
   .0902197842  -.0380581058   .1577710733   .0477405054   .0000000000
   .0347389906  -.0898696977   .0477405054   .1025348498   .0000000000
   .0000000000   .0000000000   .0000000000   .0000000000   .0000000000

Beachten Sie, dass Spalte 5 schließlich mit Nullen gefüllt wurde. Dies bedeutet (so wie ich es verstehe), dass V5 linear mit einigen vorhergehenden Spalten verknüpft ist . Welche Spalten? Schauen Sie sich die Iteration an, in der Spalte 5 zuletzt nicht mit Nullen gefüllt ist - Iteration 4. Wir sehen dort, dass V5 mit den Koeffizienten -.3333 und .8333 mit V2 und V4 verknüpft ist: V5 = -.3333 * V2 + .8333 * V4, was entspricht Was wir mit den Daten gemacht haben: V4 = .4 * V2 + 1.2 * V5.

So wussten wir, welche Spalte linear mit welcher anderen verknüpft ist. Ich habe nicht überprüft, wie hilfreich der obige Ansatz im Allgemeinen bei vielen Gruppen von Abhängigkeiten in den Daten ist. Im obigen Beispiel schien es jedoch hilfreich zu sein.

ttnphns
quelle
Ist das nicht die reduzierte Reihen-Staffelform? Wenn ja, gibt es keine Pakete / Funktionen in R?
Arun
@Arun, ich bin kein R-User, kann es also nicht wissen.
ttnphns
25

Hier ist ein einfacher Ansatz: Berechnen Sie den Rang der Matrix, der sich aus dem Entfernen der einzelnen Spalten ergibt. Die Spalten, deren Entfernung den höchsten Rang ergibt, sind linear abhängig (da das Entfernen dieser Spalten den Rang nicht verringert, während das Entfernen einer linear unabhängigen Spalte dies tut).

In R:

rankifremoved <- sapply(1:ncol(your.matrix), function (x) qr(your.matrix[,-x])$rank)
which(rankifremoved == max(rankifremoved))
James
quelle
1
Sehr nützliche Antwort bei der Bestimmung der beleidigenden Spalte in einer Regressionsmatrix, in der ich den Fehler erhalten habe system is exactly singular: U[5,5] = 0 , von dem ich jetzt weiß, dass Spalte 5 das Problem war (im Nachhinein scheint es offensichtlich zu sein, da es sich um eine Spalte mit Nullen handelt!)
Matt Weller
In dem Kommentar von James hat er das Skript gepostet: rankifremoved <- sapply (1: ncol (your.matrix), function (x) qr (your.matrix [, - x]) $ rank) which (rankifremoved == max ( rankifremoved)) Ich habe einen Test mit einer Matrix durchgeführt und möchte wissen, ob die Ausgabe von R linear abhängig ist. Danken!
@ EltonAraújo: Die Ausgabe ist ein Vektor, der die Indizes der linear abhängigen Spalten angibt: also (2,4,5) für das Beispiel in der Antwort von ttnphns. Ich frage mich jedoch, wie sich Probleme mit der numerischen Genauigkeit auf diese Methode auswirken werden.
Scortchi
rankifremoved enthält alle Spalten, die linear voneinander oder voneinander abhängig sind. In einigen Anwendungen möchten wir möglicherweise eine oder mehrere Spalten beibehalten und nicht alle
löschen
Sollte dies nicht ein leeres Set für zurückgeben your.matrix = matrix(1:4, 2)?
Holger Brandl
15

Bei der Frage geht es darum, "zugrunde liegende [lineare] Beziehungen" zwischen Variablen zu identifizieren.

Die schnelle und einfache Methode zum Erkennen von Beziehungen besteht darin, mithilfe Ihrer bevorzugten Software eine andere Variable (verwenden Sie eine Konstante, gerade) gegen diese Variablen zu regressieren: Mit jeder guten Regressionsprozedur wird die Kollinearität erkannt und diagnostiziert. (Sie werden sich nicht einmal die Regressionsergebnisse ansehen müssen. Wir verlassen uns lediglich auf einen nützlichen Nebeneffekt beim Einrichten und Analysieren der Regressionsmatrix.)

0

(Es gibt eine Kunst und eine Menge Literatur, die sich mit der Identifizierung einer "kleinen" Belastung befasst. Um eine abhängige Variable zu modellieren, würde ich vorschlagen, sie in die unabhängigen Variablen in der PCA aufzunehmen, um die Komponenten zu identifizieren - unabhängig davon ihre Größen - wobei die abhängige Variable eine wichtige Rolle spielt. Aus dieser Sicht bedeutet "klein" viel kleiner als jede solche Komponente.)


Schauen wir uns einige Beispiele an. (Diese werden Rfür die Berechnungen und das Plotten verwendet.) Beginnen Sie mit einer Funktion zum Durchführen von PCA, suchen Sie nach kleinen Komponenten, zeichnen Sie sie und geben Sie die linearen Beziehungen zwischen ihnen zurück.

pca <- function(x, threshold, ...) {
  fit <- princomp(x)
  #
  # Compute the relations among "small" components.
  #
  if(missing(threshold)) threshold <- max(fit$sdev) / ncol(x)
  i <- which(fit$sdev < threshold)
  relations <- fit$loadings[, i, drop=FALSE]
  relations <- round(t(t(relations) / apply(relations, 2, max)), digits=2)
  #
  # Plot the loadings, highlighting those for the small components.
  #
  matplot(x, pch=1, cex=.8, col="Gray", xlab="Observation", ylab="Value", ...)
  suppressWarnings(matplot(x %*% relations, pch=19, col="#e0404080", add=TRUE))

  return(t(relations))
}

B,C,D,EEIN

process <- function(z, beta, sd, ...) {
  x <- z %*% beta; colnames(x) <- "A"
  pca(cbind(x, z + rnorm(length(x), sd=sd)), ...)
}

Wir sind alle bereit zu gehen: Es bleibt nur B zu generieren , ...B,,EEIN=B+C+D+EEIN=B+(C+D)/2+Esweep

n.obs <- 80 # Number of cases
n.vars <- 4 # Number of independent variables
set.seed(17)
z <- matrix(rnorm(n.obs*(n.vars)), ncol=n.vars)
z.mean <- apply(z, 2, mean)
z <- sweep(z, 2, z.mean)
colnames(z) <- c("B","C","D","E") # Optional; modify to match `n.vars` in length

B,,EEIN

Ergebnisse

Die Ausgabe im oberen linken Bereich war

       A  B  C  D  E
Comp.5 1 -1 -1 -1 -1

00EIN-B-C-D-E

Die Ausgabe für das obere mittlere Panel war

       A     B     C     D     E
Comp.5 1 -0.95 -1.03 -0.98 -1.02

(EIN,B,C,D,E)

       A     B     C     D     E
Comp.5 1 -1.33 -0.77 -0.74 -1.07

EIN=B+C+D+E

1,1/2,1/2,1

In der Praxis ist es häufig nicht der Fall, dass eine Variable als offensichtliche Kombination der anderen herausgegriffen wird: Alle Koeffizienten können vergleichbare Größen und unterschiedliche Vorzeichen haben. Wenn es mehr als eine Dimension von Beziehungen gibt, gibt es keine eindeutige Möglichkeit, sie zu spezifizieren: Weitere Analysen (z. B. Zeilenreduzierung) sind erforderlich, um eine nützliche Grundlage für diese Beziehungen zu ermitteln. So funktioniert die Welt: Alles, was Sie sagen können, ist, dass diese speziellen Kombinationen, die von PCA ausgegeben werden, nahezu keinen Schwankungen der Daten entsprechen. Um dies zu bewältigen, verwenden einige Leute die größten ("Haupt-") Komponenten direkt als unabhängige Variablen in der Regression oder der nachfolgenden Analyse, in welcher Form auch immer. Vergessen Sie in diesem Fall nicht, zuerst die abhängige Variable aus dem Variablensatz zu entfernen und die PCA zu wiederholen!


Hier ist der Code, um diese Figur zu reproduzieren:

par(mfrow=c(2,3))
beta <- c(1,1,1,1) # Also can be a matrix with `n.obs` rows: try it!
process(z, beta, sd=0, main="A=B+C+D+E; No error")
process(z, beta, sd=1/10, main="A=B+C+D+E; Small error")
process(z, beta, sd=1/3, threshold=2/3, main="A=B+C+D+E; Large error")

beta <- c(1,1/2,1/2,1)
process(z, beta, sd=0, main="A=B+(C+D)/2+E; No error")
process(z, beta, sd=1/10, main="A=B+(C+D)/2+E; Small error")
process(z, beta, sd=1/3, threshold=2/3, main="A=B+(C+D)/2+E; Large error")

(Ich musste in den Fällen mit großen Fehlern an der Schwelle herumspielen, um nur eine einzelne Komponente anzuzeigen. Dies ist der Grund, warum dieser Wert als Parameter für angegeben wurde process.)


Benutzer ttnphns hat uns freundlicherweise auf einen eng verwandten Thread aufmerksam gemacht. Eine seiner Antworten (von JM) schlägt den hier beschriebenen Ansatz vor.

whuber
quelle
Wow, hier ist, was ich aus Ihrer Antwort verstehe. Regress meine Variablen gegen jede andere Variable. Verwenden Sie das VIF, um dann ID-bezogene Variablen anzuzeigen. Dies funktioniert. Ist es am besten, dies mit Datenblöcken gleichzeitig zu tun? Entfernen Sie auch irgendetwas, wenn Sie Kolinearität anhand der Regression erkennen? .. Was ich unter PCA verstehe, ist im Allgemeinen, dass Sie die größten PCs (die die größte Varianz erklären) basierend auf den Eigenwerten verwenden, da diese die größte Varianz erklären Grad mit den ursprünglichen Variablen. Ich bin nicht sicher, mit welchen kleinen Ladungen und was sie colinear sind
Samuel
Diese Antwort erklärt, wie man die kleinen Komponenten interpretiert: Sie zeigen die Kollinearitäten. Ja, Sie können Untergruppen von Variablen verwenden, wenn Sie möchten. Die Regressionsmethode ist nur zu erkennen das Vorhandensein von Kollinearität zu erkennen und nicht die kollinearen Beziehungen zu identifizieren: das ist, was die PCA tut.
Whuber
"loadings," which are linear combinations of the original variablesDiese Aussage sieht nicht präzise aus. Beladungen sind die Koeffizienten von Linearkombinationen von Komponenten in Vorhersagevariablen . Meinten Sie vielleicht A - 1?EINEIN-1 ?
TTNPHNS
Darf ich Sie auch bitten, Ihre Meinung zu einer möglichen Verwendung des Kehrvorgangs zu hinterlassen ( stats.stackexchange.com/a/16391/3277 ) für die Suche nach linear abhängigen Teilmengen von Variablen zu äußern ?
TTNPHNS
XX=UWVVprincompXV=UWWUW0XVX , wie angegeben - alle Null.
whuber
5

502×480

JM ist kein Statistiker
quelle
3

Ich bin vor ungefähr zwei Wochen auf dieses Problem gestoßen und habe festgestellt, dass ich es erneut prüfen muss, da es bei umfangreichen Datenmengen unmöglich ist, diese Dinge manuell auszuführen.

Ich habe eine for () - Schleife erstellt, die den Rang der Matrix spaltenweise berechnet. Für die erste Iteration ist der Rang also 1. Der zweite, 2. Dies geschieht so lange, bis der Rang WENIGER wird als die von Ihnen verwendete Spaltennummer.

Sehr einfach:

for (i in 1:47) {

  print(qr(data.frame[1:i])$rank) 
  print(i) 
  print(colnames(data.frame)[i])
  print("###") 
}

für () Schleifenzusammenbruch

  1. berechnet den Rang für die i-te Spalte
  2. Gibt die Iterationsnummer aus
  3. druckt den Spaltennamen als Referenz
  4. teilt die Konsole mit "###", so dass Sie leicht durchblättern können

Ich bin sicher, dass Sie eine if-Anweisung hinzufügen können, ich brauche sie noch nicht, da ich mich nur mit 50ish-Spalten befasse.

Hoffe das hilft!

Nick P
quelle
2
Obwohl theoretisch nichts falsch daran ist, handelt es sich um einen numerisch instabilen und ineffizienten Algorithmus. Insbesondere bei einer großen Anzahl von Spalten kann es fehlschlagen, Kollinearität zu erkennen und Kollinearität fälschlicherweise zu erkennen, wenn keine vorhanden ist.
whuber
2

Rang, r einer Matrix = Anzahl linear unabhängiger Spalten (oder Zeilen) einer Matrix. Für eine nxn- Matrix A ist Rang (A) = n => alle Spalten (oder Zeilen) sind linear unabhängig.

Arun
quelle
2

Nicht, dass die Antwort von @Whuber wirklich erweitert werden müsste, aber ich dachte, ich würde eine kurze Beschreibung der Mathematik geben.

XXv=0v0vXXλ=0XXXXXλ=0XXvλ

κj=λmeinxλj
das die Größe der kleinsten Eigenwerte relativ zu den größten misst. Eine allgemeine Faustregel lautet, dass eine bescheidene Multikollinearität mit einem Zustandsindex zwischen 100 und 1.000 assoziiert ist, während eine schwere Multikollinearität mit einem Zustandsindex über 1.000 assoziiert ist (Montgomery, 2009).

XX=[0,0010000,0010000,001].
λ1=λ2=λ3=0,001
κ=λmeinxλmichn=1

Zitate

Montgomery, D. (2012). Einführung in die lineare Regressionsanalyse, 5. Auflage. John Wiley & Sons Inc.

tjnel
quelle
1
X
Q.RXnkn>>kXR