Aumente el rendimiento en una función R utilizando un enfoque vectorizado -- performance campo con r campo con iteration campo con vectorization camp codereview Relacionados El problema

Increase performance in an R function using a vectorized approach


1
vote

problema

Español

Meta

Escriba un R Función para generar probabilidades modeladas por la siguiente ecuación (IRT; 2 modelo logístico de parámetros): ingrese la descripción de la imagen aquí

DATOS

  set.seed(1) a = runif(10, 1.5, 3) b = rnorm(10, 0, 1) theta = rnorm(10000000) # the output of the implementation should result in  # a matrix with 100 mil. rows and 10 columns   

Implementación

estrategia A

  # the implementation of the equation computeProbability = function(theta, b, a) {     x = exp(1) ^ (a * (theta - b))     return(x / (1 + x)) }  strategy.A = function(theta, b, a) {     n.rows = length(theta)     n.cols = length(b)      prob_mtx = matrix(nrow = n.rows, ncol = n.cols)      for(i in 1:n.rows)     {         prob_mtx[i, ] = computeProbability(theta[i], b, a)     }     return(prob_mtx) }   

Estrategia B

  strategy.B = function(theta, b, a) {    return(t(sapply(theta, computeProbability, b = b, a = a))) }   

estrategia C

  strategy.C = function(theta, b, a) {     return(1 / (1 + exp(-sweep(outer(theta, b, "-"), 2, a, "*")))) }   

Tiempos

      # Strategy A        |       # Strategy B        |       # Strategy C                         |                           |  user  system elapsed   |    user  system elapsed   |   user  system elapsed 64.76    0.27   65.08   |   82.01    0.91   82.93   |   7.81    0.64    8.46   

Pregunta: Estrategia C es con mucho la forma más eficiente, pero ¿cómo puedo hacerlo aún más rápido?

Original en ingles

Goal

Write an R function to generate probabilities modeled by the following equation (IRT; 2 Parameter Logistic Model): enter image description here

Data

set.seed(1) a = runif(10, 1.5, 3) b = rnorm(10, 0, 1) theta = rnorm(10000000) # the output of the implementation should result in  # a matrix with 100 mil. rows and 10 columns 

Implementation

Strategy A

# the implementation of the equation computeProbability = function(theta, b, a) {     x = exp(1) ^ (a * (theta - b))     return(x / (1 + x)) }  strategy.A = function(theta, b, a) {     n.rows = length(theta)     n.cols = length(b)      prob_mtx = matrix(nrow = n.rows, ncol = n.cols)      for(i in 1:n.rows)     {         prob_mtx[i, ] = computeProbability(theta[i], b, a)     }     return(prob_mtx) } 

Strategy B

strategy.B = function(theta, b, a) {    return(t(sapply(theta, computeProbability, b = b, a = a))) } 

Strategy C

strategy.C = function(theta, b, a) {     return(1 / (1 + exp(-sweep(outer(theta, b, "-"), 2, a, "*")))) } 

Timings

    # Strategy A        |       # Strategy B        |       # Strategy C                         |                           |  user  system elapsed   |    user  system elapsed   |   user  system elapsed 64.76    0.27   65.08   |   82.01    0.91   82.93   |   7.81    0.64    8.46 

Question: Strategy C is by far the most efficient way, but how can I make it even faster?

           
     
     

Lista de respuestas

1
 
vote

Su estrategia C es probablemente ya casi óptima. Aquí hay una solución basada en RCPP para exprimir algunos segundos adicionales

  debug9  

puntos de referencia con sus datos:

  help0  
 

Your strategy C is probably already nearly optimal. Here is an Rcpp based solution to squeeze out some additional seconds

library('Rcpp') cppFunction(includes = '#include <math.h>',             code = 'Rcpp::NumericMatrix strategy_rcpp(const Rcpp::NumericVector& theta,                                                       const Rcpp::NumericVector& b,                                                       const Rcpp::NumericVector& a) {   const int n = theta.size();   const int m = a.size();   if (m != b.size())       Rcpp::stop("a and b must have equal length");   const double e = exp(1.0);   Rcpp::NumericMatrix ret(n, m);   for (int j = 0; j < m; ++j) {       for (int i = 0; i < n; ++i) {          ret(i, j) = 1.0 / (1.0 + pow(e, -a[j] * (theta[i] - b[j])));       }   }   return ret; }') 

Benchmarks with your data:

library('microbenchmark') microbenchmark(times = 1,                strategy.C(theta, b, a),                strategy_rcpp(theta, b, a) )  Unit: seconds                                                                                        expr       min        lq      mean    median        uq     strategy.C(theta, b, a) 10.996822 10.996822 10.996822 10.996822 10.996822  strategy_rcpp(theta, b, a)  6.921705  6.921705  6.921705  6.921705  6.921705 
 
 

Relacionados problema

3  Generar vectores de la unidad aleatoria alrededor del círculo  ( Generate random unit vectors around circle ) 
Estoy tratando de generar un montón de vectores de unidad de distribución uniformemente alrededor del círculo de la unidad. Aquí está mi código, que está func...

5  Evaluando una serie de polinomios legendra  ( Evaluating a series of legendre polynomials ) 
La siguiente función representa el potencial electrostático, en coordenadas esféricas, debido a un anillo de carga $ Q = 1 $ y RADIUS $ R = 1 $, colocado ...

1  Vectorizamos gradiente 2D con contenedores espacialmente variables  ( Vectorize 2d gradient with spatially varying bins ) 
El siguiente código lleva a algunos valores ssh y resuelve las ecuaciones para el movimiento geostrófico (diapositiva 8 aquí ). La parte principal del Có...

2  Encuentra el primer umbral de cruce en la matriz NUTPY  ( Find first threshold crossing in numpy array ) 
Dado los siguientes datos generados artificialmente: t_steps = 30 data = np.array([ np.arange(t_steps) * .05, np.arange(t_steps) * .1, np.aran...

6  Cálculo de estacionamientos y estadísticas de carga para un servicio compartido de automóviles  ( Calculating parking and charging statistics for a car sharing service ) 
Estoy buscando ayuda para diseñar mi código de manera más eficiente y también en mantener la pendiente de mi curva de aprendizaje personal empinada: Para un...

4  Crosstabulación vectorizada en Python para dos matrices con dos categorías cada una  ( Vectorized crosstabulation in python for two arrays with two categories each ) 
Tengo dos listas de Python, label y presence1 . Quiero hacer la tabulación cruzada y obtener el recuento para cada bloque de cuatro, como A, B, C y D en ...

5  Vectorización para simulación de temperatura  ( Vectorization for temperature simulation ) 
Soy nuevo en Matlab y me gustaría saber consejos para reducir el tiempo de procesamiento de dicho programa. El esquema del código real es muy similar al códig...

2  Escalado e incremento de elementos no cero de una matriz adorable  ( Scaling and incrementing non zero elements of a numpy matrix ) 
Tengo una matriz adorable C y desea crear una copia cPrime , que tiene algún funcionamiento de la matriz original a todos los valores no cero. En el código...

4  Vectorizando un bucle de conversión de coordenadas polares en un proceso de coincidencia de huellas dactilares  ( Vectorizing a polar coordinate conversion loop in a fingerprint matching process ) 
Estoy trabajando en una técnica de coincidencia de huellas dactilares y se necesita mucho tiempo de computación para obtener el resultado. Estoy tratando de i...

6  ¿Cómo hacer que mis operaciones de Groupby y Transponen eficientes?  ( How to make my groupby and transpose operations efficient ) 
Tengo un DataFrame 3,745,802 filas y 30 columnas. Me gustaría realizar cierto 9988776665544331 y 9988776655544332 terminará finalmente con más columnas ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos