Извлечение значения p из множественной линейной регрессии f-test [duplicate]

Поле, аннотированное @Autowired, является null, потому что Spring не знает о копии MileageFeeCalculator, которую вы создали с помощью new, и не знал, чтобы ее автоустанавливать.

Контейнер Spring Inversion of Control (IoC) имеет три основных логических компонента: реестр (называемый ApplicationContext) компонентов (beans), доступных для использования приложением, система настройки, которая вводит объектов в них путем сопоставления зависимостей с компонентами в контексте и решателя зависимостей, которые могут смотреть на конфигурацию множества различных компонентов и определять, как создавать и настраивать их в необходимом порядке.

Контейнер IoC не является волшебным, и он не может знать о Java-объектах, если вы как-то не сообщаете об этом. Когда вы вызываете new, JVM создает экземпляр нового объекта и передает его прямо вам - он никогда не проходит процесс настройки. Есть три способа, которыми вы можете настроить свои компоненты.

Я опубликовал весь этот код, используя Spring Boot для запуска, в проекте GitHub ; вы можете посмотреть полный рабочий проект для каждого подхода, чтобы увидеть все, что вам нужно, чтобы заставить его работать. Тег с параметром NullPointerException: nonworking

Ввод ваших bean-компонентов

Наиболее предпочтительным вариантом является позволить Spring autowire все ваши компоненты; это требует наименьшего количества кода и является наиболее удобным для обслуживания. Чтобы сделать работу по автоустановке, как вы хотели, также автоустанавливайте MileageFeeCalculator следующим образом:

@Controller
public class MileageFeeController {

    @Autowired
    private MileageFeeCalculator calc;

    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        return calc.mileageCharge(miles);
    }
}

Если вам нужно создать новый экземпляр объекта службы для разных запросов, вы все равно можете использовать используя области весеннего компонента .

Тег, который работает путем ввода объекта службы @MileageFeeCalculator: working-inject-bean

Использовать @Configurable

Если вам действительно нужны объекты, созданные с new, которые будут автообновлены, вы можете использовать аннотацию Spring @Configurable вместе с AspectJ компиляцией во время компиляции для ввода ваших объектов , Этот подход вставляет код в конструктор вашего объекта, который предупреждает Spring о том, что он создается, так что Spring может настроить новый экземпляр. Это требует некоторой конфигурации в вашей сборке (например, компиляции с ajc) и включения обработчиков конфигурации среды Spring (@EnableSpringConfigured с синтаксисом JavaConfig). Этот подход используется системой активных записей Roo, чтобы позволить экземплярам new ваших объектов получать необходимую информацию о сохранении.

@Service
@Configurable
public class MileageFeeCalculator {

    @Autowired
    private MileageRateService rateService;

    public float mileageCharge(final int miles) {
        return (miles * rateService.ratePerMile());
    }
}

Тег, который работает с помощью @Configurable на объекте службы: working-configurable

Ручной поиск: не рекомендуется

Этот подход подходит только для взаимодействия с устаревшим кодом в особых ситуациях. Почти всегда предпочтительнее создавать одноэлементный класс адаптеров, который Spring может использовать для autowire, и устаревший код может вызывать, но можно напрямую спросить контекст приложения Spring для bean-компонента.

Для этого вам нужно класс, к которому Spring может ссылаться на объект ApplicationContext:

@Component
public class ApplicationContextHolder implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;   
    }

    public static ApplicationContext getContext() {
        return context;
    }
}

Затем ваш устаревший код может вызывать getContext() и извлекать необходимые ему компоненты:

@Controller
public class MileageFeeController {    
    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        MileageFeeCalculator calc = ApplicationContextHolder.getContext().getBean(MileageFeeCalculator.class);
        return calc.mileageCharge(miles);
    }
}

Тег, который работает путем ручного поиска объекта службы в контексте Spring: working-manual-lookup

140
задан grautur 7 April 2011 в 22:07
поделиться

11 ответов

r-squared: вы можете вернуть значение r-квадрата непосредственно из объекта подсчета summary(fit)$r.squared. См. names(summary(fit)) для списка всех элементов, которые вы можете извлечь напрямую.

Модель p-value: Если вы хотите получить p-значение общей модели регрессии, это сообщение в блоге описывает функцию для возврата p-значения:

lmp <- function (modelobject) {
    if (class(modelobject) != "lm") stop("Not an object of class 'lm' ")
    f <- summary(modelobject)$fstatistic
    p <- pf(f[1],f[2],f[3],lower.tail=F)
    attributes(p) <- NULL
    return(p)
}

> lmp(fit)
[1] 1.622665e-05

В случае простой регрессии с одним предиктором p-значение модели и p-значение для коэффициента будут одна и та же.

Коэффициент p-значений: если у вас более одного предиктора, то приведенное выше вернет p-значение модели, а p-значение для коэффициентов можно извлечь, используя:

summary(fit)$coefficients[,4]  

Кроме того, вы можете захватить p-значение коэффициентов из объекта anova(fit) аналогично суммарному объекту выше.

107
ответ дан Jeromy Anglim 22 August 2018 в 10:30
поделиться
  • 1
    Немного лучше использовать inherits, а не class напрямую. А может, вы хотите unname(pf(f[1],f[2],f[3],lower.tail=F))? – hadley 22 December 2011 в 03:08

Другой вариант - использовать функцию cor.test вместо lm:

> x <- c(44.4, 45.9, 41.9, 53.3, 44.7, 44.1, 50.7, 45.2, 60.1)
> y <- c( 2.6,  3.1,  2.5,  5.0,  3.6,  4.0,  5.2,  2.8,  3.8)

> mycor = cor.test(x,y)
> mylm = lm(x~y)

# r and rsquared:
> cor.test(x,y)$estimate ** 2
      cor 
0.3262484 
> summary(lm(x~y))$r.squared
[1] 0.3262484

# P.value 

> lmp(lm(x~y))  # Using the lmp function defined in Chase's answer
[1] 0.1081731
> cor.test(x,y)$p.value
[1] 0.1081731
-1
ответ дан dalloliogm 22 August 2018 в 10:30
поделиться

Я использовал эту функцию lmp довольно много раз.

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

  • p-value
  • a и b
  • и, конечно, аспект точечного распределения

. Приведем пример. Вы здесь

Здесь воспроизводимый пример с разными переменными:

Ex<-structure(list(X1 = c(-36.8598, -37.1726, -36.4343, -36.8644, 
-37.0599, -34.8818, -31.9907, -37.8304, -34.3367, -31.2984, -33.5731
), X2 = c(64.26, 63.085, 66.36, 61.08, 61.57, 65.04, 72.69, 63.83, 
67.555, 76.06, 68.61), Y1 = c(493.81544, 493.81544, 494.54173, 
494.61364, 494.61381, 494.38717, 494.64122, 493.73265, 494.04246, 
494.92989, 494.98384), Y2 = c(489.704166, 489.704166, 490.710962, 
490.653212, 490.710612, 489.822928, 488.160904, 489.747776, 490.600579, 
488.946738, 490.398958), Y3 = c(-19L, -19L, -19L, -23L, -30L, 
-43L, -43L, -2L, -58L, -47L, -61L)), .Names = c("X1", "X2", "Y1", 
"Y2", "Y3"), row.names = c(NA, 11L), class = "data.frame")


library(reshape2)
library(ggplot2)
Ex2<-melt(Ex,id=c("X1","X2"))
colnames(Ex2)[3:4]<-c("Y","Yvalue")
Ex3<-melt(Ex2,id=c("Y","Yvalue"))
colnames(Ex3)[3:4]<-c("X","Xvalue")

ggplot(Ex3,aes(Xvalue,Yvalue))+
          geom_smooth(method="lm",alpha=0.2,size=1,color="grey")+
          geom_point(size=2)+
          facet_grid(Y~X,scales='free')


#Use the lmp function

lmp <- function (modelobject) {
  if (class(modelobject) != "lm") stop("Not an object of class 'lm' ")
  f <- summary(modelobject)$fstatistic
    p <- pf(f[1],f[2],f[3],lower.tail=F)
    attributes(p) <- NULL
    return(p)
    }

# create function to extract different informations from lm

lmtable<-function (var1,var2,data,signi=NULL){
  #var1= y data : colnames of data as.character, so "Y1" or c("Y1","Y2") for example
  #var2= x data : colnames of data as.character, so "X1" or c("X1","X2") for example
  #data= data in dataframe, variables in columns
  # if signi TRUE, round p-value with 2 digits and add *** if <0.001, ** if < 0.01, * if < 0.05.

  if (class(data) != "data.frame") stop("Not an object of class 'data.frame' ")
  Tabtemp<-data.frame(matrix(NA,ncol=6,nrow=length(var1)*length(var2)))
  for (i in 1:length(var2))
       {
  Tabtemp[((length(var1)*i)-(length(var1)-1)):(length(var1)*i),1]<-var1
  Tabtemp[((length(var1)*i)-(length(var1)-1)):(length(var1)*i),2]<-var2[i]
  colnames(Tabtemp)<-c("Var.y","Var.x","p-value","a","b","r^2")

  for (n in 1:length(var1))
  {
  Tabtemp[(((length(var1)*i)-(length(var1)-1))+n-1),3]<-lmp(lm(data[,var1[n]]~data[,var2[i]],data))

  Tabtemp[(((length(var1)*i)-(length(var1)-1))+n-1),4]<-coef(lm(data[,var1[n]]~data[,var2[i]],data))[1]

  Tabtemp[(((length(var1)*i)-(length(var1)-1))+n-1),5]<-coef(lm(data[,var1[n]]~data[,var2[i]],data))[2]

  Tabtemp[(((length(var1)*i)-(length(var1)-1))+n-1),6]<-summary(lm(data[,var1[n]]~data[,var2[i]],data))$r.squared
  }
  }

  signi2<-data.frame(matrix(NA,ncol=3,nrow=nrow(Tabtemp)))
  signi2[,1]<-ifelse(Tabtemp[,3]<0.001,paste0("***"),ifelse(Tabtemp[,3]<0.01,paste0("**"),ifelse(Tabtemp[,3]<0.05,paste0("*"),paste0(""))))
  signi2[,2]<-round(Tabtemp[,3],2)
  signi2[,3]<-paste0(format(signi2[,2],digits=2),signi2[,1])

  for (l in 1:nrow(Tabtemp))
    {
  Tabtemp$"p-value"[l]<-ifelse(is.null(signi),
         Tabtemp$"p-value"[l],
         ifelse(isTRUE(signi),
                paste0(signi2[,3][l]),
                Tabtemp$"p-value"[l]))
  }

   Tabtemp
}

# ------- EXAMPLES ------

lmtable("Y1","X1",Ex)
lmtable(c("Y1","Y2","Y3"),c("X1","X2"),Ex)
lmtable(c("Y1","Y2","Y3"),c("X1","X2"),Ex,signi=TRUE)

Конечно, это более быстрое решение, чем эта функция, но оно работает.

4
ответ дан Dorian Grv 22 August 2018 в 10:30
поделиться
x = cumsum(c(0, runif(100, -1, +1)))
y = cumsum(c(0, runif(100, -1, +1)))
fit = lm(y ~ x)
> names(summary(fit))
[1] "call"          "terms"        
 [3] "residuals"     "coefficients" 
 [5] "aliased"       "sigma"        
 [7] "df"            "r.squared"    
 [9] "adj.r.squared" "fstatistic"   
[11] "cov.unscaled" 
    summary(fit)$r.squared
1
ответ дан Jojo 22 August 2018 в 10:30
поделиться
  • 1
    Позаботьтесь о том, чтобы объяснить, почему работает этот код? – aribeiro 26 March 2016 в 21:21
  • 2
    как это улучшается в отношении существующих ответов (и, в частности, принятого ответа)? – Ben Bolker 27 March 2016 в 00:05

Вы можете увидеть структуру объекта, возвращенного функцией summary(), вызвав str(summary(fit)). Доступ к каждой части осуществляется с помощью $. Значение p для статистики F легче получить от объекта, возвращаемого anova.

Вкратце, вы можете сделать это:

rSquared <- summary(fit)$r.squared
pVal <- anova(fit)$'Pr(>F)'[1]
39
ответ дан joran 22 August 2018 в 10:30
поделиться
  • 1
    Удивительно, спасибо. – Contango 5 April 2013 в 12:41
  • 2
    это работает только для одномерных регрессий, где p val регрессии совпадает с предсказателем – Bakaburg 20 December 2014 в 16:08

Я рассматриваю этот вопрос, исследуя предлагаемые решения для аналогичной проблемы; Я полагаю, что для будущей ссылки может быть полезно обновить доступный список ответов с помощью решения, использующего пакет broom .

Пример кода

x = cumsum(c(0, runif(100, -1, +1)))
y = cumsum(c(0, runif(100, -1, +1)))
fit = lm(y ~ x)
require(broom)
glance(fit)

Результаты

>> glance(fit)
  r.squared adj.r.squared    sigma statistic    p.value df    logLik      AIC      BIC deviance df.residual
1 0.5442762     0.5396729 1.502943  118.2368 1.3719e-18  2 -183.4527 372.9055 380.7508 223.6251          99

Боковые заметки

Я нашел полезную функцию glance, поскольку она аккуратно суммирует полезные значения. В качестве дополнительного преимущества результаты сохраняются как data.frame, что облегчает дальнейшие манипуляции:

>> class(glance(fit))
[1] "data.frame"
6
ответ дан Konrad 22 August 2018 в 10:30
поделиться

Хотя оба вышеперечисленных ответа хороши, процедура извлечения частей объектов более общая.

Во многих случаях функции возвращают списки, а к отдельным компонентам можно получить доступ с помощью str(), которые будет печатать компоненты вместе с их именами. Затем вы можете получить к ним доступ с помощью оператора $, то есть myobject$componentname.

В случае объектов lm существует ряд предопределенных методов, которые можно использовать, например coef(), resid(), summary() и т. д., но вам не всегда будет так повезло.

22
ответ дан posdef 22 August 2018 в 10:30
поделиться

Это самый простой способ вывести значения p:

coef(summary(modelname))[, "Pr(>|t|)"]
6
ответ дан RTrain3k 22 August 2018 в 10:30
поделиться
  • 1
    Я пробовал этот метод, но он будет терпеть неудачу, если линейная модель содержит любые члены NA – j_v_wow_d 25 December 2016 в 01:10

Использование:

(summary(fit))$coefficients[***num***,4]

, где num - это число, которое обозначает строку матрицы коэффициентов. Это будет зависеть от того, сколько функций у вас есть в вашей модели и какой из них вы хотите вытащить p-значение. Например, если у вас есть только одна переменная, для перехвата будет 1 p-значение, которое будет [1,4], а следующее - для вашей фактической переменной, которая будет [2,4]. Таким образом, ваш num будет равен 2.

0
ответ дан Saranjith 22 August 2018 в 10:30
поделиться

Расширение ответа @Vincent answer :

Для lm() сгенерированных моделей:

summary(fit)$coefficients[,4]   ##P-values 
summary(fit)$r.squared          ##R squared values

Для gls() сгенерированных моделей:

summary(fit)$tTable[,4]         ##P-values
##R-squared values are not generated b/c gls uses max-likelihood not Sums of Squares

Чтобы изолировать индивидуальное p-значение, вы должны добавить номер строки в код:

Например, чтобы получить доступ к p-значению перехвата в обеих моделях summary:

summary(fit)$coefficients[1,4]
summary(fit)$tTable[1,4]  
  • Обратите внимание: вы можете заменить номер столбца на имя столбца в каждом из указанных выше экземпляров:
    summary(fit)$coefficients[1,"Pr(>|t|)"]  ##lm 
    summary(fit)$tTable[1,"p-value"]         ##gls 
    

Если вы «все еще не уверены в том, как получить доступ к форме значения, в итоговой таблице используйте str(), чтобы выяснить структуру сводной таблицы:

str(summary(fit))
8
ответ дан theforestecologist 22 August 2018 в 10:30
поделиться

Обратите внимание, что summary(fit) генерирует объект со всей необходимой информацией. В нем хранятся бета, se, t и p векторы. Получите значения p, выбрав четвертый столбец матрицы коэффициентов (сохраненный в суммарном объекте):

summary(fit)$coefficients[,4] 
summary(fit)$r.squared

Попробуйте str(summary(fit)), чтобы просмотреть всю информацию, содержащуюся в этом объекте.

Редактировать: я неправильно понял ответ Чейза, который в основном говорит вам, как добраться до того, что я здесь даю.

127
ответ дан Vincent 22 August 2018 в 10:30
поделиться
  • 1
    Примечание. Это единственный метод, который дает вам легкий доступ к p-значению перехвата, а также к другим предикторам. Безусловно лучшее из вышеперечисленного. – Daniel Egan 7 December 2012 в 18:57
  • 2
    Это правильный ответ. Ответ с наивысшим рейтингом НЕ работал для меня. – Chris 29 September 2015 в 01:37
  • 3
    ЕСЛИ ВЫ ХОТИТЕ ЛЕГКО ДОСТУП К П-ЗНАЧЕНИЮ, ИСПОЛЬЗУЙТЕ ЭТО ОТВЕТ. Зачем вам нужно писать многострочные функции или создавать новые объекты (т. Е. Выходы anova), когда вам просто нужно немного усерднее найти p-значение в самом сводном выходе. Чтобы изолировать индивидуальное p-значение, вы должны добавить номер строки к ответу Винсента: например, summary(fit)$coefficients[1,4] для пользователя – theforestecologist 24 November 2015 в 02:09
  • 4
    Примечание. Этот метод работает для моделей, созданных с помощью lm(), но не работает для моделей gls(). – theforestecologist 20 February 2016 в 04:26
  • 5
    См. мой ответ ниже для расширения этого ответа, который работает для lm() AND gls() – theforestecologist 12 July 2017 в 05:51
Другие вопросы по тегам:

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