Сравнение вложенных моделей [duplicate]

После многократного поиска в Java единственное решение, которое, похоже, работает для меня, - это вручную прочитать файл jar, если вы не находитесь в среде разработки (IDE):

/** @return The root folder or jar file that the class loader loaded from */
public static final File getClasspathFile() {
    return new File(YourMainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile());
}

/** @param resource The path to the resource
 * @return An InputStream containing the resource's contents, or
 *         <b><code>null</code></b> if the resource does not exist */
public static final InputStream getResourceAsStream(String resource) {
    resource = resource.startsWith("/") ? resource : "/" + resource;
    if(getClasspathFile().isDirectory()) {//Development environment:
        return YourMainClass.class.getResourceAsStream(resource);
    }
    final String res = resource;//Jar or exe:
    return AccessController.doPrivileged(new PrivilegedAction<InputStream>() {
        @SuppressWarnings("resource")
        @Override
        public InputStream run() {
            try {
                final JarFile jar = new JarFile(getClasspathFile());
                String resource = res.startsWith("/") ? res.substring(1) : res;
                if(resource.endsWith("/")) {//Directory; list direct contents:(Mimics normal getResourceAsStream("someFolder/") behaviour)
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    Enumeration<JarEntry> entries = jar.entries();
                    while(entries.hasMoreElements()) {
                        JarEntry entry = entries.nextElement();
                        if(entry.getName().startsWith(resource) && entry.getName().length() > resource.length()) {
                            String name = entry.getName().substring(resource.length());
                            if(name.contains("/") ? (name.endsWith("/") && (name.indexOf("/") == name.lastIndexOf("/"))) : true) {//If it's a folder, we don't want the children's folders, only the parent folder's children!
                                name = name.endsWith("/") ? name.substring(0, name.length() - 1) : name;
                                baos.write(name.getBytes(StandardCharsets.UTF_8));
                                baos.write('\r');
                                baos.write('\n');
                            }
                        }
                    }
                    jar.close();
                    return new ByteArrayInputStream(baos.toByteArray());
                }
                JarEntry entry = jar.getJarEntry(resource);
                InputStream in = entry != null ? jar.getInputStream(entry) : null;
                if(in == null) {
                    jar.close();
                    return in;
                }
                final InputStream stream = in;//Don't manage 'jar' with try-with-resources or close jar until the
                return new InputStream() {//returned stream is closed(closing the jar closes all associated InputStreams):
                    @Override
                    public int read() throws IOException {
                        return stream.read();
                    }

                    @Override
                    public int read(byte b[]) throws IOException {
                        return stream.read(b);
                    }

                    @Override
                    public int read(byte b[], int off, int len) throws IOException {
                        return stream.read(b, off, len);
                    }

                    @Override
                    public long skip(long n) throws IOException {
                        return stream.skip(n);
                    }

                    @Override
                    public int available() throws IOException {
                        return stream.available();
                    }

                    @Override
                    public void close() throws IOException {
                        try {
                            jar.close();
                        } catch(IOException ignored) {
                        }
                        stream.close();
                    }

                    @Override
                    public synchronized void mark(int readlimit) {
                        stream.mark(readlimit);
                    }

                    @Override
                    public synchronized void reset() throws IOException {
                        stream.reset();
                    }

                    @Override
                    public boolean markSupported() {
                        return stream.markSupported();
                    }
                };
            } catch(Throwable e) {
                e.printStackTrace();
                return null;
            }
        }
    });
}

Примечание: приведенный выше код, похоже, работает правильно для файлов jar, если он находится в основном классе. Я не уверен, почему.

9
задан landroni 24 May 2016 в 15:08
поделиться

5 ответов

Я предполагаю, что вы хотели набрать:

glm1 <-glm(Y ~ X1+X2+X3, family=binomial(link=logit))

glm2 <-glm(Y ~ X1 + X2, family=binomial(link=logit))

Интерфейс формулы для функций регрессии R не распознает запятые как добавление ковариатов к RHS формулы. И не используйте attach(); используйте аргумент данных для функций регрессии.

0
ответ дан 42- 26 August 2018 в 09:08
поделиться

Чтобы избежать ошибки "models were not all fitted to the same size of dataset", вы должны подгонять обе модели к одному и тому же подмножеству данных. Существует два простых способа сделать это:

  • либо использовать data=glm1$model во второй модели fit
  • , либо получить правильно подмножество набора данных, используя data=na.omit(orig.data[ , all.vars(formula(glm1))]) во втором model fit

Вот пример воспроизводимости с использованием lm (для glm тот же подход должен работать) и update:

# 1st approach
# define a convenience wrapper
update_nested <- function(object, formula., ..., evaluate = TRUE){
    update(object = object, formula. = formula., data = object$model, ..., evaluate = evaluate)
}

# prepare data with NAs
data(mtcars)
for(i in 1:ncol(mtcars)) mtcars[i,i] <- NA

xa <- lm(mpg~cyl+disp, mtcars)
xb <- update_nested(xa, .~.-cyl)
anova(xa, xb)
## Analysis of Variance Table
## 
## Model 1: mpg ~ cyl + disp
## Model 2: mpg ~ disp
##   Res.Df    RSS Df Sum of Sq      F  Pr(>F)  
## 1     26 256.91                              
## 2     27 301.32 -1   -44.411 4.4945 0.04371 *
## ---
## Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

# 2nd approach
xc <- update(xa, .~.-cyl, data=na.omit(mtcars[ , all.vars(formula(xa))]))
anova(xa, xc)
## Analysis of Variance Table
## 
## Model 1: mpg ~ cyl + disp
## Model 2: mpg ~ disp
##   Res.Df    RSS Df Sum of Sq      F  Pr(>F)  
## 1     26 256.91                              
## 2     27 301.32 -1   -44.411 4.4945 0.04371 *
## ---
## Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

См. также:

3
ответ дан Community 26 August 2018 в 09:08
поделиться

Причина хорошо описана Грегом Сноу. Альтернативным и очень простым решением является добавление новой переменной, совпадающей с NA NA проблемной переменной, и в противном случае со значением 1. Включите ее в обе модели, и R исключит те же строки в обеих моделях (-> набор данных будет соответствовать).

0
ответ дан cpt. couteau 26 August 2018 в 09:08
поделиться

Решение состоит в том, чтобы использовать:

glm1 <-glm(Y ~ X1 + X2 + X3, family = binomial(link = logit), na.action = na.exclude)
glm2 <-glm(Y ~ X1 + X2, family = binomial(link = logit), na.action = na.exclude)

anova(glm2,glm1)

Это приведет к тому, что R включает случаи с отсутствующими данными (NA) в установленной модели. Это гарантирует, что наборы данных идентичны для разных моделей подгонки независимо от того, как распределяются недостающие данные.

1
ответ дан Deleet 26 August 2018 в 09:08
поделиться

Основной причиной этой ошибки является отсутствие значений в одной или нескольких переменных предиктора. В последних версиях R действие по умолчанию состоит в том, чтобы опустить все строки, у которых отсутствуют какие-либо значения (предыдущим значением по умолчанию было создание ошибки). Так, например, если в кадре данных есть 100 строк и в X3 есть одно отсутствующее значение, тогда ваша модель glm1 будет соответствовать 99 строкам данных (отбрасывая строку, где отсутствует X3), но объект glm2 будет полностью укомплектован 100 строк данных (поскольку он не использует X3, никакие строки не нужно удалять).

Итак, функция anova дает вам ошибку, потому что две модели подходят для разных наборов данных (и как вы вычисляете степени свободы и т. д.).

Одним из решений является создание нового фрейма данных, который имеет только те столбцы, которые будут использоваться, по крайней мере, в одной из ваших моделей и удалять все строки с любыми (функция na.omit или na.exclude сделает это проще), затем установите обе модели в один и тот же фрейм данных, у которого нет каких-либо отсутствующих значений.

Другими вариантами были бы просмотр инструментов для множественного вменения или других способов устранения недостающих данных.

10
ответ дан Greg Snow 26 August 2018 в 09:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: