Saya berjuang dengan masalah pemrograman. Tujuannya adalah untuk menemukan agregat rata-rata optimal dari beberapa kolom, sehingga kolom agregat memaksimalkan korelasi dengan kolom lain.

Sebagai contoh mainan, perhatikan data berikut:

set.seed(123)

df <- cbind(data.frame(FIRM = rnorm(36, 0, 0.05)),
              data.frame(matrix(rnorm(36 * 50, 0, 0.05), 36, 50)))

Jadi: tujuannya adalah untuk menemukan kombinasi optimal dari 50 kolom "X" sehingga ketika mengambil rata-rata baris dari kolom ini korelasi dengan kolom "FIRM" dimaksimalkan. Namun, meskipun ini hanya contoh kecil, sudah ada 50 kemungkinan kombinasi faktorial.

Sebagian dari masalahnya adalah bahwa kumpulan data sebenarnya jauh lebih besar (yaitu, sekitar 20.000 pengoptimalan "FIRM", dengan lebih dari 5.000 kolom "X" yang memungkinkan untuk digabungkan per pengoptimalan). Sampai sekarang, saya mulai dengan beberapa optimasi bertahap, tetapi mengingat ukuran dataset ini sangat tidak efisien. Saya berharap mendapatkan beberapa wawasan dengan cara yang lebih baik dalam mengkodekan masalah ini.

Sejauh ini saya menulis beberapa kode yang mengambil kombinasi linier apa pun dan memaksimalkan korelasi itu dengan kolom awal. Namun, sekarang saya ingin menyesuaikan ini, sehingga kode tidak menimbang kolom dengan bobot selain 1 atau 0.

Kode yang saya miliki sejauh ini adalah:

set.seed(123)

firm <- rnorm(36, 0, 0.05)
peers <- matrix(rnorm(36 * 50, 0, 0.05), 36, 50)

#Function to maximize
cor.model <- function(w = rep(1 / ncol(peers), ncol(peers))){
  f_score <- peers %*% (w / sum(w))
  x <- f_score
  y <- firm
  correl <- cor(x,y)
  return(correl)
}

#Output
out <- optim(par = rep(1 / ncol(peers), ncol(peers)),
             fn = cor.model,
             method = "L-BFGS-B",
             lower = rep(0, ncol(peers)), # W_i >= 0 for all i
             upper = rep(1, ncol(peers)), # W_i <= 1 for all i)
             control = list(fnscale = -1))

out$par/sum(out$par)

cor(firm, rowSums(peers))
cor(firm, rowSums(t(as.vector(out$par/sum(out$par))*t(peers))))

Terima kasih banyak!

2
Oscar 11 Desember 2019, 22:01

1 menjawab

Jawaban Terbaik

Saya akan mencoba Penelusuran Lokal (seperti yang dijelaskan dalam tutorial ini).

Berikut adalah sketsa di R.

FIRM <- as.matrix(df[[1]])
M <- as.matrix(df[, -1])

library("neighbours")  ## https://github.com/enricoschumann/neighbours
library("NMOF")        ## https://github.com/enricoschumann/NMOF

N <- neighbourfun(type = "logical", kmin = 1, kmax = 50)

Sebuah solusi awal.

x <- logical(50)
x[1:5] <- TRUE

Fungsi tujuan. Fungsi yang kita gunakan nanti diminimalkan, jadi saya menempatkan minus di depan perhitungan.

of_cor <- function(x, FIRM, M) {
    -c(cor(FIRM, rowMeans(M[, x])))
}

Tes: pilih semua 50 kolom.

-of_cor(!logical(50), FIRM, M)
## [1] -0.1727944

Tes: gunakan solusi awal.

-of_cor(x, FIRM, M)
## [1] -0.2261783

Jalankan perhitungan yang sebenarnya, dengan Threshold Accepting (yang didasarkan pada Pencarian Lokal).

sol <- TAopt(of_cor,
             list(x0 = x,
                  neighbour = N,
                  nI = 50000),
             M = M,
             FIRM = FIRM)
## Threshold Accepting
## [....]
##   Finished.
##   Best solution overall: -0.6206239

Solusinya memiliki korelasi 0,62.

-of_cor(sol$xbest, FIRM, M)
## [1] 0.6206239

(Pengungkapan: Saya adalah pengelola paket yang saya gunakan.)

3
Enrico Schumann 11 Desember 2019, 20:51