Я пытаюсь использовать R для оценки полиномиальной логит-модели с ручной спецификацией. Я нашел несколько пакетов, которые позволяют оценивать модели MNL здесь или здесь .
Здесь я нашел некоторые другие записи о "прокрутке" вашей собственной функции MLE . Однако, судя по моим поискам, все эти функции и пакеты полагаются на внутреннюю функцию optim
.
В моих тестовых тестах узким местом является optim
. Используя смоделированный набор данных с ~ 16000 наблюдений и 7 параметрами, R на моей машине занимает около 90 секунд. Эквивалентная модель в Biogeme занимает ~ 10 секунд. Коллега, который пишет свой собственный код в Ox , сообщает о 4 секундах для этой же модели.
Есть ли у кого-нибудь опыт написания своей собственной функции MLE или может ли кто-нибудь указать мне направление чего-то, что оптимизировано помимо функции по умолчанию optim
(без каламбура)?
Если кто-то хочет, чтобы код R воссоздал модель, дайте мне знать - я с радостью предоставлю его. Я не предоставил его, поскольку он не имеет прямого отношения к проблеме оптимизации функции optim
и экономии места ...
EDIT: Спасибо всем за ваши мысли. Основываясь на несметном количестве комментариев ниже, мы смогли получить R на том же уровне, что и Biogeme, для более сложных моделей, а R был на самом деле быстрее для нескольких меньших / более простых моделей, которые мы запускали. Я думаю, что долгосрочное решение этой проблемы будет заключаться в написании отдельной функции максимизации, которая опирается на библиотеку fortran или C, выражение хранилища
Вот метод, который я создал ...
public User GetUser(DbUser user, long uid)
{
return new User
{
Uid = user.uid,
FirstName = user.first_name,
LastName = user.last_name
};
}
И я вызываю такой метод ...
public User GetUser(long uid)
{
using (var entities = new myEntities()) {
return
entities.DbUsers.Where( x => x.uid == uid && x.account_status == ( short )AccountStatus.Active ).
Select( x => GetUser( x, uid ) ).FirstOrDefault( );
}
}
ОБНОВЛЕНИЕ: вот код, который работает встроенно
public User GetUser(long uid, long uid_user)
{
using (var entities = new myEntities())
{
var q = from u in entities.DbUsers
where u.uid == uid_user
select new User
{
Uid = u.uid,
FirstName = u.first_name,
LastName = u.last_name,
BigPicUrl = u.pic_big,
Birthday = u.birthday,
SmallPicUrl = u.pic_small,
SquarePicUrl = u.pic_square,
Locale = u.locale.Trim(),
IsFavorite = u.FavoriteFriends1.Any(x => x.uid == uid),
FavoriteFriendCount = u.FavoriteFriends.Count,
LastWishlistUpdate = u.WishListItems.OrderByDescending(x => x.added).FirstOrDefault().added,
Sex = (UserSex)u.sex
};
var user = q.FirstOrDefault();
user.DaysUntilBirthday = user.Birthday.DaysUntilBirthday();
return user;
}
}