Загрузка тысяч URL-адресов для поиска веб-страниц, связанных с ML - код ОЧЕНЬ медленный, нужны советы по эффективности - PullRequest
0 голосов
/ 10 февраля 2019

Я строю набор данных путем скребания данных с различных веб-сайтов для алгоритма прогнозирования биржевого сигнала.Способ, которым настроен мой алгоритм, включает в себя многоуровневое создание циклов for и загрузку тысяч URL-адресов, поскольку каждая ссылка ссылается на акции и их различные количественные статистические данные.Нужна помощь в увеличении скорости обработки.Любые советы?

Я говорил с несколькими разными людьми о том, как решить эту проблему, и некоторые люди рекомендовали векторизацию, но для меня это ново.Я также пытался перейти к таблице данных, но я не видел много изменений.Строки eval - это уловка, которой я научился манипулировать данными так, как я хочу, но я думаю, что это может быть причиной того, что они медленные, но я сомневаюсь в этом.Мне также интересно узнать об удаленной обработке, но это, вероятно, выходит за рамки мира R.

Для приведенного ниже кода представьте, что есть еще 4 таких раздела для других переменных с разных веб-сайтов, которые я хочу загрузить, и всеэти блоки находятся в еще большем цикле for, потому что я генерирую два набора данных (set = c ("training, testing")).

tryCatch предназначен для предотвращения остановки кода в случае возникновения ошибкизагрузка URL.URL-адреса загружаются в список, по одному для каждой акции - поэтому они довольно длинные.Второй цикл for очищает данные из URL-адресов и отправляет их правильно отформатированными во фрейм данных.

library(quantmod)
library(readr)
library(rvest)
library(data.table)

urlsmacd <-  vector("list", length = 
eval(parse(text=as.name(paste0("nrow(", set[y], ")", sep = "")))))
for(h in 1:eval(parse(text=as.name(paste0("nrow(", set[y], ")", sep = 
""))))){
  urlsmacd[h] <- paste0('http://www.stockta.com/cgi-bin/analysis.pl? 
symb=',eval(parse(text=as.name(paste0(set[y],"[,1][h]", sep = 
"")))),'&mode=table&table=macd&num1=1', sep = '')
}

for(j in 1:eval(parse(text=as.name(paste0("nrow(", set[y], ")", sep = 
""))))){
  tryCatch({
html <- read_html(urlsmacd[[j]])

#get macd html
MACD26 <- html_nodes(html,'.borderTd~ .borderTd+ .borderTd:nth-child(3) 
font')
MACD26 <- toString(MACD26)
MACD26 <-  gsub("<[^>]+>", "", MACD26)
if(!is.na(MACD26)){
  MACD26 <- as.double(MACD26)
}
eval(parse(text=as.name(paste0(set[y],"$","MACD26[j] <- MACD26"))))

MACD12 <- html_nodes(html,'.borderTd+ .borderTd:nth-child(2) font')
MACD12 <- toString(MACD12)
MACD12 <-  gsub("<[^>]+>", "",MACD12)
if(!is.na(MACD12)){
  MACD12 <- as.double(MACD12)
}
eval(parse(text=as.name(paste0(set[y],"$","MACD12[j] <- MACD12"))))

  }, error=function(e){cat("ERROR :",conditionMessage(e), "\n")})
    }

Все это сказано и сделано, этот процесс занимает около 6 часов.В таком случае, если вы сэкономите время на этом процессе, это значительно облегчит выполнение моего проекта.

Спасибо вам, сотрудники StackOverflow, за вашу поддержку.

1 Ответ

0 голосов
/ 10 февраля 2019

Проверьте пакет doParallel.Он имеет параллельную реализацию цикла foreach.Это позволяет вам использовать больше ядер вашего ЦП (если они есть) для выполнения параллельных R-сеансов для определенной функции.Например:

library(doParallel)  
no_cores <- detectCores() - 1  
cl <- makeCluster(no_cores, type="FORK")  
registerDoParallel(cl)  
result <- foreach(i=10:10000) %dopar% 
getPrimeNumbers(i)

Если URL-адреса хранятся в списке, то также есть параллельное сообщение.

Пример взят из этого великого поста:

https://www.r -bloggers.com / позволяет быть более быстрым и более параллельным в r-with-doparallel-package / amp /

Надеюсь, это поможет.

...