Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Программирование [игнор отключен] [закрыт для гостей] / генерация случайных чисел в R! по условию / 24 сообщений из 24, страница 1 из 1
26.06.2017, 19:34
    #39477968
PlanB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
Добрый день!

познаю R! для узкой задачи. моя таблица [MYtable] вида [idclient], [iddog], [ead] может содержать более одного договора [iddog] на клиента [idclient]. и это очень жаль, потому что я хочу нагенерить случайные числа таким образом, что бы они были одинаковыми для всех договоров, принадлежащих одному клиенту.

Ничего лучше, чем извлекать уникальные номера клиентов, генерить для них рандомы а потом сливать в основной массив я не придумал! таким образом, из основной таблицы рождается временная [tatemp], а потом уже из [tatemp] и [MYtable] рождается [tatemp2], которой я дальше и пользуюсь.

Код: vbnet
1.
2.
3.
idcl1<-unique(MYtable2$idclient)
tatemp<-data.frame(id=idcl1,r1=runif(NROW(idcl1)),r2=runif(NROW(idcl1)),r3=runif(NROW(idcl1)))
tatemp2<-merge(MYtable,tatemp,by.x="idclient",by.y="id")



как сделать быстрее и проще? Мб какой-нить apply? Я никак не вкурю как его юзать...
...
Рейтинг: 0 / 0
26.06.2017, 20:10
    #39477987
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
Может лучше SQL изучить? Диалект используемого SQL сервера.

Этими средствами гораздо быстрее будет работать, чем гонять данные между БД и клиентом.
...
Рейтинг: 0 / 0
26.06.2017, 21:56
    #39478012
mini.weblab
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
PlanB,

простое решение не генерировать случайных чисел, а использовать seed,
можно написать функцию, которая будет выдавать псевдослучайное значение в зависимости от id

fake_random <- function(id){
set.seed(id)
return( runif() )
}


=)
...
Рейтинг: 0 / 0
26.06.2017, 21:59
    #39478013
mini.weblab
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
mini.weblab пропустила 1 в runif

fake_random <- function(id){
set.seed(id)
return( runif(1) )
}
...
Рейтинг: 0 / 0
27.06.2017, 09:00
    #39478142
PlanB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
Dima TМожет лучше SQL изучить?на уровне данной задачи я знаю sql. нужен r по ряду причин.
...
Рейтинг: 0 / 0
27.06.2017, 09:04
    #39478147
PlanB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
mini.weblabmini.weblab пропустила 1 в runif

fake_random <- function(id){
set.seed(id)
return( runif(1) )
}решение с сидом я обдумывал, но не катит в текущей интерпретации. далее мне нужно провести N=100000 итераций генерации таких рандомов. а с заданным сидом они все будут одинаковые.

хотя можно же задавать set.seed(id+i), где i in 1:100000. слушайте, а не плохо. че я не додумался. есть у сида ограничения по длине числа? айдишники здоровенные... 90 триллионов максимальный пока =))
...
Рейтинг: 0 / 0
27.06.2017, 09:45
    #39478189
PlanB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
mini.weblabmini.weblab пропустила 1 в runif

fake_random <- function(id){
set.seed(id)
return( runif(1) )
}все бы здорово, но я не понял как вызвать функцию так что бы на выходе был вектор. или надо ее прогонять через цикл по каждой строке (каждому id)? тогда это имхо еще дольше, чем через merge
...
Рейтинг: 0 / 0
27.06.2017, 12:54
    #39478399
mini.weblab
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
PlanB,
1)
чтобы выходе был вектор на входе подаем вектор и используем
?sapply
2)
я не верю, что с merge будет эффективней =)
...
Рейтинг: 0 / 0
27.06.2017, 13:24
    #39478421
PlanB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
mini.weblabPlanB,
1)
чтобы выходе был вектор на входе подаем вектор и используем
?sapply
2)
я не верю, что с merge будет эффективней =)

Вариант 1
Код: vbnet
1.
2.
3.
4.
5.
6.
union_random<-function(id)
{
  set.seed(id)
  return(runif(1))
}
tatemp2$c1<-lapply(tatemp2$idclient/10000, union_random)

прошло 1.93

Вариант 2
Код: vbnet
1.
2.
3.
idcl1<-unique(RGScredport$idclient)
tatemp<-data.frame(id=idcl1,r1=runif(NROW(idcl1)),r2=runif(NROW(idcl1)),r3=runif(NROW(idcl1)))
tatemp2<-merge(RGScredport,tatemp,by.x="idclient",by.y="id")

прошло 0.97
...
Рейтинг: 0 / 0
27.06.2017, 13:28
    #39478426
PlanB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
mini.weblabя не верю, что с merge будет эффективней =)можно распараллелить как-то. но, имхо, это уже перебор. должно быть проще решение.


ЗЫ у меня еще один затык - вложенные условия. их дохрена и больше. можно как-то увеличить скорость на коде, представленном ниже?

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
tatemp2$prov_calcstress_p<-ifelse(is.na(tatemp2$pos_ind)==F, #если в поле стоит NA, то договор признается индивидуальной ссудой
                #правила для ПОС
                ifelse(tatemp2$fl_ul=="ЮЛ", 
                    #правила для ЮЛ
                    ifelse(tatemp2$prov_calc_p==0.5,1.5,
                    ifelse(tatemp2$prov_calc_p==1,3,
                    ifelse(tatemp2$prov_calc_p==1.5,10,
                    ifelse(tatemp2$prov_calc_p==3,20,
                    ifelse(tatemp2$prov_calc_p==10,35,
                    ifelse(tatemp2$prov_calc_p==20,50,
                    ifelse(tatemp2$prov_calc_p==35,75,
                    ifelse(tatemp2$prov_calc_p==50,75,tatemp2$prov_calc_p))))))))
                    ,
                    #правила для ФЛ
                    ifelse(tatemp2$prov_calc_p>=0 & tatemp2$prov_calc_p<1,1.5,
                    ifelse(tatemp2$prov_calc_p==1,3,
                    ifelse(tatemp2$prov_calc_p==1.5,10,
                    ifelse(tatemp2$prov_calc_p==2,6,
                    ifelse(tatemp2$prov_calc_p==3,ifelse(tatemp2$backet=="0 Без просрочки",8,20),       
                    ifelse(tatemp2$prov_calc_p>3 & tatemp2$prov_calc_p<10,20,
                    ifelse(tatemp2$prov_calc_p>=10 & tatemp2$prov_calc_p<20,35,
                    ifelse(tatemp2$prov_calc_p>=20 & tatemp2$prov_calc_p<35,50,
                    ifelse(tatemp2$prov_calc_p>=35 & tatemp2$prov_calc_p<75,75,
                    ifelse(tatemp2$prov_calc_p>=75 & tatemp2$prov_calc_p<=100,100,tatemp2$prov_calc_p))))))))))
                    ), 
                #правила для индивидуальных ссуд               
                ifelse(tatemp2$fl_ul=="ЮЛ",
                    
                    #правила для ЮЛ                    
                    ifelse(tatemp2$prov_calc_p<1, #если текущий резерв <1% (I)
                           ifelse(tatemp2$r3<0.9,1,ifelse(tatemp2$r3>=0.99,20,10)),
                    ifelse(tatemp2$prov_calc_p>=1 & tatemp2$prov_calc_p<21, #если текущий резерв [1%,21%) (II)
                           ifelse(tatemp2$r2<0.5, #вероятность смены категории качества при стрессе = 50%
                                  ifelse(tatemp2$prov_calc_p==1, #категория остается прежней (II)
                                         ifelse(tatemp2$r3<0.9,10,20),
                                  ifelse(tatemp2$prov_calc_p==20,
                                         ifelse(tatemp2$r3<0.6,21,ifelse(tatemp2$r3>=0.95,30,50)),20)),
                                  ifelse(tatemp2$r3<0.6,21,ifelse(tatemp2$r3>=0.95,30,50))),  #категория меняется (III)
                    ifelse(tatemp2$prov_calc_p>=21 & tatemp2$prov_calc_p<51, #если текущий резерв [21%,51%) (III)                   
                           ifelse(tatemp2$r2<0.5, #вероятность смены категории качества при стрессе = 50%
                                  ifelse(tatemp2$prov_calc_p==21, #категория остается прежней (III)
                                         ifelse(tatemp2$r3<0.125,30,50),
                                  ifelse(tatemp2$prov_calc_p==50,
                                         ifelse(tatemp2$r3<0.9,51,ifelse(tatemp2$r3>=0.99,100,75)),50)),
                                  ifelse(tatemp2$r3<0.9,51,ifelse(tatemp2$r3>=0.99,100,75))),  #категория меняется (IV)
                    ifelse(tatemp2$prov_calc_p>=51, #если текущий резерв >=51% (IV)                       
                           ifelse(tatemp2$r2<0.5, #вероятность смены категории качества при стрессе = 50%
                                  ifelse(tatemp2$prov_calc_p==51, #категория остается прежней (III)
                                         ifelse(tatemp2$r3<0.9,75,100),100),100),
                                  100)))) #категория меняется (V)
                    ,  
                    #правила для ФЛ
                    ifelse(tatemp2$prov_calc_p<1, #если текущий резерв <1% (I)
                           1,
                    ifelse(tatemp2$prov_calc_p>=1 & tatemp2$prov_calc_p<21, #если текущий резерв [1%,21%) (II)
                           ifelse(tatemp2$r3<0.5,21,50),
                    ifelse(tatemp2$prov_calc_p>=21 & tatemp2$prov_calc_p<51, #если текущий резерв [21%,51%) (III)   
                           ifelse(tatemp2$r2<0.5, #вероятность смены категории качества при стрессе = 50%
                                  ifelse(tatemp2$prov_calc_p==21,50,51), #категория остается прежней (III)
                                  51), #категория меняется (IV)
                           100)))#в остальных случаях 100%
                ) 
           )
  #условия заданы

...
Рейтинг: 0 / 0
27.06.2017, 14:35
    #39478490
mini.weblab
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
PlanB,
так Дима уже ответил: подготовку данных для анализа лучше производить в БД
но если очень хочется это сделать в R, то можно почитать
https://www.packtpub.com/application-development/r-data-structures-and-algorithms
(но я бы на это не подписалась)
=)
...
Рейтинг: 0 / 0
27.06.2017, 15:32
    #39478523
PlanB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
mini.weblabPlanB,
так Дима уже ответил: подготовку данных для анализа лучше производить в БД
но если очень хочется это сделать в R, то можно почитать
https://www.packtpub.com/application-development/r-data-structures-and-algorithms
(но я бы на это не подписалась)
=)у меня монте-карло с моделированием 100к+ экспериментов. недостаток sql - посредственный встроенный рандом. недостаток r, как теперь выясняется - медленная работа. а я так верил в векторизацию! жаль нескольких потраченных дней на его изучение...

не сомневаюсь, что в sql линковаться таблицы будут быстрее. а что, встроенные условия (elseif) будут тоже быстрее отрабатывать? я чет не верю =(((
...
Рейтинг: 0 / 0
27.06.2017, 16:17
    #39478562
mini.weblab
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
mini.weblabя не верю, что с merge будет эффективней =)

a) в случае генерации псевдослучайного числа - цена алгоритма O(n)
b) насколько я знаю в случае с merge данные должны быть предварительно отсортированны по id,
т.е. теоретически только для сортировки цена алгоритма >= O( n*log(n) ) > O(n)

PlanB,
1) в случае перехода с R на что-нибудь еще,
основные проблемы обычно возникают с переписыванием функций типа tatemp2$prov_calcstress_p

2) недостаток sql - посредственный встроенный рандом Вы генерируете число из равномерного распределения, имхо, здесь проблем быть не должно.

3) еще аргумент за использование БД: случае использования БД расчеты будут выполняться на БД сервере =)
...
Рейтинг: 0 / 0
27.06.2017, 16:46
    #39478591
PlanB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
mini.weblab3) еще аргумент за использование БД: случае использования БД расчеты будут выполняться на БД сервере =)три раза ха! на sql экспресс они будут выполняться на моей машине... кто мне место на сервере-то даст...
...
Рейтинг: 0 / 0
27.06.2017, 18:22
    #39478648
PlanB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
mini.weblabmini.weblabя не верю, что с merge будет эффективней =)
a) в случае генерации псевдослучайного числа - цена алгоритма O(n)
b) насколько я знаю в случае с merge данные должны быть предварительно отсортированны по id,
т.е. теоретически только для сортировки цена алгоритма >= O( n*log(n) ) > O(n)ок, вполне допускаю, что я мыслю не категориями стат языка R! и изначально свою задачу решаю некорректными методами. Мне нужно всего-навсего выбрать 25% уникальных записей в [idclient] (и все соответствующие им [iddog]) и просуммировать поле [ead]. Сделать это нужно N=10000 раз и в каждой итерации выборка 25% будет разной.

Я решаю это при помощи генерации псевдослучайных числел и последующего их сравнения с 0,25. возможно, есть более простой способ? (например, в SPSS он есть, а в R я хз)
...
Рейтинг: 0 / 0
27.06.2017, 19:09
    #39478681
mini.weblab
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
PlanB,
1) можно создать таблицу из уникальных id клиентов
2) использовать функцию sample для выборки 25% id (?sample)
3) и просуммировать то что вам нужно
...
Рейтинг: 0 / 0
27.06.2017, 19:57
    #39478697
PlanB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
mini.weblabPlanB,
1) можно создать таблицу из уникальных id клиентов
2) использовать функцию sample для выборки 25% id (?sample)
3) и просуммировать то что вам нужномне нужно выбрать еще и все [iddog], соответствующие [idclient].
...
Рейтинг: 0 / 0
27.06.2017, 22:03
    #39478717
mini.weblab
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
PlanB,
использовать merge =)
...
Рейтинг: 0 / 0
28.06.2017, 00:17
    #39478741
mini.weblab
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
PlanB,

в R я обычно работаю с данными сравнительно небольшого объема использую пакет sqldf
решение будет работать немного медленне чем при использовании merge, но зато будет логичным, понятным и легко читаемым
...
Рейтинг: 0 / 0
28.06.2017, 08:56
    #39478785
PlanB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
mini.weblab, спасибо за ответы! тему можно закрывать.
...
Рейтинг: 0 / 0
29.06.2017, 16:14
    #39479815
PlanB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
в итоге вот оптимизация. не шибко большая. что вычитал, то и буду использовать
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
#присвоение рандома через пользовательскую функцию и apply
union_random<-function(id)
{set.seed(id);return(runif(1))}
system.time({tatemp2$c1<-lapply(tatemp2$idclient/10000, union_random)})
#1.06 sec + проблемы с зернами из-за слишком длинных номеров клиентов

#присвоение рандома через merge (по-эскуэлевски)
id<-unique(RGScredport$idclient)
nid<-NROW(id)
system.time({tatemp<-data.frame(id=id,r1=runif(nid),r2=runif(nid),r3=runif(nid)); tatemp2<-merge(RGScredport,tatemp,by.x="idclient",by.y="id")})
#0.50 sec

#слияние массивов при помощи пакета dplyr
library(dplyr)
system.time({tatemp<-data.frame(id=id,r1=runif(nid),r2=runif(NROW(nid)),r3=runif(NROW(nid))); tatemp2<-left_join(RGScredport,tatemp,by=c("idclient"="id"))})
#0.16 sec
...
Рейтинг: 0 / 0
29.06.2017, 21:44
    #39479994
mini.weblab
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
PlanB,
а сколько у вас уникальных id клиентов?
...
Рейтинг: 0 / 0
29.06.2017, 22:52
    #39480014
mini.weblab
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
mini.weblab,
дело в том, что у меня функция с seed в среднем выдает 10с на последовательность от 1 до 1000000

быстрее всего отрабатывает sample 0.016c на последовательность от 1 до 1000000

это результаты только для выборок
...
Рейтинг: 0 / 0
30.06.2017, 15:18
    #39480471
PlanB
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
генерация случайных чисел в R! по условию
mini.weblabPlanB,
а сколько у вас уникальных id клиентов?178k
...
Рейтинг: 0 / 0
Форумы / Программирование [игнор отключен] [закрыт для гостей] / генерация случайных чисел в R! по условию / 24 сообщений из 24, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]