前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MRM中进行变量筛选

MRM中进行变量筛选

作者头像
Listenlii-生物信息知识分享
发布2020-05-29 11:26:26
1.5K0
发布2020-05-29 11:26:26
举报
文章被收录于专栏:Listenlii的生物信息笔记

写在前面的2+1件事:

1.最近总有人加我好友称呼我的时候把我的姓写错。我的姓是雷厉风行的厉!厉行节约的厉!不明觉厉的厉!不是日历的历啊!

2.从2017.12.4开始至今,已经坚持写了一年多,目前公众号的关注人数每周都在以个位数稳定增长。虽然现在不做任何宣传与推广,全靠读者自发的分享,但还是不断地有新人在关注。我深感欣慰。

+1.本文因为一些原因需要重新发一下。之前的那篇删掉了。本文主体内容和之前相同,只是在最后多加了一点说明。

回归正题:

前几天有人在R——ecodist&MRM methods文章中提问:

如何在MRM中对变量进行forward-selection?

其实我之前对forward-selection是啥意思也不太懂。这篇文章也是在自己学习了相关概念之后的一点粗浅简介。权当班门弄斧抛砖引玉,欢迎讨论~

写之前以为本文会很短,结果写完发现内容很多,因此先列一个提纲。本文内容包括:

1.变量筛选(Variable Selection)

2. 两大类变量筛选的方法

3. R中实现变量筛选

4. 其他方法检验因子之间的相关性及贡献

5. MRM中如何实现变量筛选

01

变量筛选(Variable Selection)

变量筛选是在所有的变量中选出解释或预测能力最好的子集的过程。这样做的原因有以下几个:

根据奥卡姆剃刀原理(Occam’s Razor),越简单的模型就是越好的模型,因此需要去掉冗余的变量;

不必要的变量会给其他变量增加噪声,由这些变量贡献的自由度也会浪费;

太多变量做一件事会增加共线性;

节约时间和金钱,减少成本。

02

两大类变量筛选的方法

01

Stepwise Procedures

Backward Elimination:

先将所有变量都放入模型中进行拟合,计算每个变量的p值;

移除得到最大p值的变量,并对模型进行重新拟合;

反复进行,直到所有的p值都小于你所设定的阈值(如0.05),不再删除变量。

Forward Selection:

和Backward Elimination思想正好相反:在模型中分别放入每一个变量并分别计算p值;

挑出最小p值的变量放入模型,再计算放入其他变量之后的p值;

反复进行,直到剩下变量中最小的p值大于你所设定的阈值(如0.05),不再加入变量。

Backward Elimination相较于Forward Selection的优势在于允许一些低贡献度的变量进入模型,而Forward Selection不能。且这些低贡献度的变量与其他变量组合之后可能贡献度变大。

Stepwise Regression:

这种方法是前两种方法的综合。每一次拟合的过程都可以添加或删除一个变量。但这种方法的缺点也很明显:

同时增加和删除一个变量可能会错过最优的模型;

删除不太重要的变量往往会增加剩余变量的显著性,这样就会高估剩余变量的重要性;

作为一种统计上的方法,这种对变量的筛选并不能直接解决实际的问题,模型的选择不能脱离实验目的。且被删除的变量仍可以与关注的因子相关。

02

Criterion-based

1

使模型的Akaike Information Criterion (AIC)或者Bayes Information Criterion (BIC)尽可能的小。过程和p值的筛选相同,不再赘述。

2

Adjusted R2。R2 = 1- RSS /TSS。增加变量总会减小RSS,最终使得R2增加。因此这种方法并不是很好。

3

使预测的模型残差平方和(Predicted Residual Sum of Squares (PRESS))最小。

4

Mallow’s Cp Statistic:

Criterion-based的方法搜索范围更广,且搜索方式更好。推荐采用这种方法进行变量筛选。

Reference

http://www.biostat.jhsph.edu/~iruczins/teaching/jf/ch10.pdf

03

R中实现Variable Selection

1.最简单的方法就是根据定义,变量一个一个的增加或者删除。

2.现有工具。Adjusted R2和Mallow’s Cp Statistic在R中有多种方式进行计算:

leaps package

代码语言:javascript
复制
leaps()对于给定的变量进行穷举搜索,找到线性拟合效果最优的子集。
Usage:
leaps(x=, y=, wt=rep(1, NROW(x)), int=TRUE, method=c("Cp", "adjr2", "r2"), nbest=10,names=NULL, df=NROW(x), strictly.compatible=TRUE)
x:预测的矩阵
y:响应变量
wt:权重
int:模型中增加一个截距
method:计算Cp,Adjusted R2,R2。默认计算Cp
df:自由度
strictly.compatible=TRUE条件下x不能超过31列,即最多31个变量。

> library(leaps)
> x<-matrix(rnorm(100),ncol=4)
> y<-rnorm(25)
> leaps(x,y)
$which
      1     2     3     4
1  TRUE FALSE FALSE FALSE
1 FALSE FALSE  TRUE FALSE
1 FALSE FALSE FALSE  TRUE
1 FALSE  TRUE FALSE FALSE
2  TRUE FALSE  TRUE FALSE
2  TRUE FALSE FALSE  TRUE
2  TRUE  TRUE FALSE FALSE
2 FALSE FALSE  TRUE  TRUE
2 FALSE  TRUE  TRUE FALSE
2 FALSE  TRUE FALSE  TRUE
3  TRUE FALSE  TRUE  TRUE
3  TRUE  TRUE  TRUE FALSE
3  TRUE  TRUE FALSE  TRUE
3 FALSE  TRUE  TRUE  TRUE
4  TRUE  TRUE  TRUE  TRUE

$label
[1] "(Intercept)" "1"           "2"           "3"           "4"          

$size
 [1] 2 2 2 2 3 3 3 3 3 3 4 4 4 4 5

$Cp
 [1] 0.7316891 0.9694651 1.3730445 1.6584606 1.0795534 2.6059937 2.6543183 2.8720554
 [9] 2.9684635 3.3729559 3.0031894 3.0774385 4.5859802 4.8652879 5.0000000

结果中which的每一行为一个模型,穷举共15个。TRUE表示保留x中对应列的变量。 Cp即为15个模型的Cp统计量。

regsubsets

regsubsets是leaps包中另一个函数,其不仅可以进行穷举,还可以用forward,backward stepwise, sequential replacement的方法进行。用法类似,但功能更强大。

MASS package

stepAIC函数可以根据AIC值进行变量筛选。其参数direction可以选择both,forward,backward三种。

olsrr package

1

所有可能的拟合

代码语言:javascript
复制
> model <- lm(mpg ~ disp + hp + wt + qsec, data = mtcars)
> k <- ols_step_all_possible(model);k
#结果给出Cp,Adjusted R2,R2
# A tibble: 15 x 6
   Index     N Predictors      `R-Square` `Adj. R-Square` `Mallow's Cp`
 * <int> <int> <chr>                <dbl>           <dbl>         <dbl>
 1     1     1 wt                   0.753           0.745         12.5 
 2     2     1 disp                 0.718           0.709         18.1 
 3     3     1 hp                   0.602           0.589         37.1 
 4     4     1 qsec                 0.175           0.148        107.  
 5     5     2 hp wt                0.827           0.815          2.37
 6     6     2 wt qsec              0.826           0.814          2.43
 7     7     2 disp wt              0.781           0.766          9.88
 8     8     2 disp hp              0.748           0.731         15.2 
 9     9     2 disp qsec            0.722           0.702         19.6 
10    10     2 hp qsec              0.637           0.612         33.5 
11    11     3 hp wt qsec           0.835           0.817          3.06
12    12     3 disp hp wt           0.827           0.808          4.36
13    13     3 disp wt qsec         0.826           0.808          4.43
14    14     3 disp hp qsec         0.754           0.728         16.3 
15    15     4 disp hp wt qsec      0.835           0.811          5   
> plot(k)

2

最优的子集

代码语言:javascript
复制
> p <- ols_step_best_subset(model);p
   Best Subsets Regression    
------------------------------
Model Index    Predictors
------------------------------
     1         wt              
     2         hp wt           
     3         hp wt qsec      
     4         disp hp wt qsec 
------------------------------

                                                  Subsets Regression Summary                                                   
-------------------------------------------------------------------------------------------------------------------------------
                       Adj.        Pred                                                                                         
Model    R-Square    R-Square    R-Square     C(p)        AIC        SBIC        SBC        MSEP      FPE       HSP       APC  
-------------------------------------------------------------------------------------------------------------------------------
  1        0.7528      0.7446      0.7087    12.4809    166.0294    74.2916    170.4266    9.8972    9.8572    0.3199    0.2801 
  2        0.8268      0.8148      0.7811     2.3690    156.6523    66.5755    162.5153    7.4314    7.3563    0.2402    0.2091 
  3        0.8348      0.8171       0.782     3.0617    157.1426    67.7238    164.4713    7.6140    7.4756    0.2461    0.2124 
  4        0.8351      0.8107       0.771     5.0000    159.0696    70.0408    167.8640    8.1810    7.9497    0.2644    0.2259 
-------------------------------------------------------------------------------------------------------------------------------
AIC: Akaike Information Criteria 
 SBIC: Sawa's Bayesian Information Criteria 
 SBC: Schwarz Bayesian Criteria 
 MSEP: Estimated error of prediction, assuming multivariate normality 
 FPE: Final Prediction Error 
 HSP: Hocking's Sp 
 APC: Amemiya Prediction Criteria 

> plot(p)

3

Stepwise Forward Regression

代码语言:javascript
复制
> model <- lm(y ~ ., data = surgical)
> k<- ols_step_forward_p(model)
Forward Selection Method    
---------------------------

Candidate Terms: 

1. bcs 
2. pindex 
3. enzyme_test 
4. liver_test 
5. age 
6. gender 
7. alc_mod 
8. alc_heavy 

We are selecting variables based on p value...

Variables Entered: 

✔ liver_test 
✔ alc_heavy 
✔ enzyme_test 
✔ pindex 
✔ bcs 

No more variables to be added.

Final Model Output 
------------------

                          Model Summary                           
-----------------------------------------------------------------
R                       0.884       RMSE                 195.454 
R-Squared               0.781       Coef. Var             27.839 
Adj. R-Squared          0.758       MSE                38202.426 
Pred R-Squared          0.700       MAE                  137.656 
-----------------------------------------------------------------
 RMSE: Root Mean Square Error 
 MSE: Mean Square Error 
 MAE: Mean Absolute Error 

                                 ANOVA                                  
-----------------------------------------------------------------------
                   Sum of                                              
                  Squares        DF    Mean Square      F         Sig. 
-----------------------------------------------------------------------
Regression    6535804.090         5    1307160.818    34.217    0.0000 
Residual      1833716.447        48      38202.426                     
Total         8369520.537        53                                    
-----------------------------------------------------------------------

                                      Parameter Estimates                                        
------------------------------------------------------------------------------------------------
      model         Beta    Std. Error    Std. Beta      t        Sig         lower       upper 
------------------------------------------------------------------------------------------------
(Intercept)    -1178.330       208.682                 -5.647    0.000    -1597.914    -758.746 
 liver_test       58.064        40.144        0.156     1.446    0.155      -22.652     138.779 
  alc_heavy      317.848        71.634        0.314     4.437    0.000      173.818     461.878 
enzyme_test        9.748         1.656        0.521     5.887    0.000        6.419      13.077 
     pindex        8.924         1.808        0.380     4.935    0.000        5.288      12.559 
        bcs       59.864        23.060        0.241     2.596    0.012       13.498     106.230 
------------------------------------------------------------------------------------------------
> plot(k)

4

Stepwise Backward Regression

代码语言:javascript
复制
> model <- lm(y ~ ., data = surgical)
> k <- ols_step_backward_p(model)
Backward Elimination Method 
---------------------------

Candidate Terms: 

1 . bcs 
2 . pindex 
3 . enzyme_test 
4 . liver_test 
5 . age 
6 . gender 
7 . alc_mod 
8 . alc_heavy 

We are eliminating variables based on p value...

Variables Removed: 

✖ alc_mod 
✖ gender 
✖ age 

No more variables satisfy the condition of p value = 0.3


Final Model Output 
------------------

                          Model Summary                           
-----------------------------------------------------------------
R                       0.884       RMSE                 195.454 
R-Squared               0.781       Coef. Var             27.839 
Adj. R-Squared          0.758       MSE                38202.426 
Pred R-Squared          0.700       MAE                  137.656 
-----------------------------------------------------------------
 RMSE: Root Mean Square Error 
 MSE: Mean Square Error 
 MAE: Mean Absolute Error 

                                 ANOVA                                  
-----------------------------------------------------------------------
                   Sum of                                              
                  Squares        DF    Mean Square      F         Sig. 
-----------------------------------------------------------------------
Regression    6535804.090         5    1307160.818    34.217    0.0000 
Residual      1833716.447        48      38202.426                     
Total         8369520.537        53                                    
-----------------------------------------------------------------------

                                      Parameter Estimates                                        
------------------------------------------------------------------------------------------------
      model         Beta    Std. Error    Std. Beta      t        Sig         lower       upper 
------------------------------------------------------------------------------------------------
(Intercept)    -1178.330       208.682                 -5.647    0.000    -1597.914    -758.746 
        bcs       59.864        23.060        0.241     2.596    0.012       13.498     106.230 
     pindex        8.924         1.808        0.380     4.935    0.000        5.288      12.559 
enzyme_test        9.748         1.656        0.521     5.887    0.000        6.419      13.077 
 liver_test       58.064        40.144        0.156     1.446    0.155      -22.652     138.779 
  alc_heavy      317.848        71.634        0.314     4.437    0.000      173.818     461.878 
------------------------------------------------------------------------------------------------
> plot(k)

5

Stepwise Regression

代码语言:javascript
复制
> model <- lm(y ~ ., data = surgical)
> k <- ols_step_both_p(model)
>plot(k)

6

Stepwise AIC Forward Regression

代码语言:javascript
复制
> model <- lm(y ~ ., data = surgical)
> k <- ols_step_forward_aic(model)
Forward Selection Method 
------------------------

Candidate Terms: 

1 . bcs 
2 . pindex 
3 . enzyme_test 
4 . liver_test 
5 . age 
6 . gender 
7 . alc_mod 
8 . alc_heavy 


Variables Entered: 

✔ liver_test 
✔ alc_heavy 
✔ enzyme_test 
✔ pindex 
✔ bcs 

No more variables to be added.


                             Selection Summary                               
----------------------------------------------------------------------------
Variable         AIC        Sum Sq           RSS         R-Sq      Adj. R-Sq 
----------------------------------------------------------------------------
liver_test     771.875    3804272.477    4565248.060    0.45454      0.44405 
alc_heavy      761.439    4743349.776    3626170.761    0.56674      0.54975 
enzyme_test    750.509    5515514.136    2854006.401    0.65900      0.63854 
pindex         735.715    6278360.060    2091160.477    0.75015      0.72975 
bcs            730.620    6535804.090    1833716.447    0.78091      0.75808 
----------------------------------------------------------------------------
> plot(k)

7&8

Others

Stepwise AIC Backward Regression 和 Stepwise AIC Regression类似,不再赘述。

Reference

https://cran.r-project.org/web/packages/olsrr/vignettes/variable_selection.html

https://stackoverflow.com/questions/21099840/variable-selection-methods

04

其他方法检验因子之间的相关性及贡献

要考察很多因子之间的相关性及他们对另一个因子的影响,方法目前也有很多,我之前很多文章都有提及。

效应量可以表征因子之间的相关性,详见效应量的计算——Cohen's d statistic

PCA,DCA,NMDS等降维方法也可以挑出其主要作用的成分

在计算CCA之前通常要计算膨胀系数(R中的vif.cca函数)来判断环境因子中的共线性,并删除高度共线性的因子。这部分以后可以简单写一下。

R包Hmisc中的varclus函数可对因子进行相关性聚类,找到共线性的因子

R包hier.part可用来计算多种因子对响应因子的贡献度,详见R-hier.part包的层次划分方法及重大bug

05

MRM中实现变量筛选

以上说了这么多,终于可以试着回答读者的提问了。需要注意的是上文第三部分提及的R中实现的变量筛选都是针对向量进行的,而MRM的输入数据是矩阵。

代码语言:javascript
复制
> library(ecodist)
>data(graze)
>head(graze)

         sitelocation forestpct ACMI2 ANOD ASSY BRIN2 CIAR4 CIIN CIVU DAGL ELRE4
1.1.2001    12.187743     63.88     0    0  0.0     0     0  0.0  0.0 20.5   4.7
1.2.2001    12.186077     71.33     0    0  0.5     0     0  0.0  5.1  0.0   6.4
2.1.2001    12.406362     72.45     0    0  0.0     0     0  0.0  0.0  2.2  21.5
2.2.2001    12.416265     77.13     0    0  0.0     0     0  0.0  0.0  1.5   3.4
3.1.1998     8.409213     18.35     0    0  0.0     0     0  0.0  0.2  0.0   0.0
3.1.1999     8.409213     18.35     0    0  0.0     0     0  0.5  0.7  0.0   0.0
         GAMO LOAR10 LOCO6 LOPE OXST PLMA2 POPR PRVU RAAC3 RUCR SORU2 STGR TAOF
1.1.2001    0    1.5     0    0  0.0   4.0 35.0  1.7   0.9  0.2     0 22.5 58.0
1.2.2001    0    8.9     0    0  0.0   0.0 54.5  1.0   0.5  0.0     0 10.8 39.0
2.1.2001    0    7.0     0    0  0.7   0.0 52.0  0.0   0.2  0.0     0  8.7  7.4
2.2.2001    0   14.5     0   32  0.2   0.0 11.0  0.0   0.0  0.0     0 11.4  5.7
3.1.1998    0   36.5     0    0  0.5   6.9  0.1  0.0   0.0  3.7     0  0.0  2.9
3.1.1999    0   71.5     0    4  0.0   3.6  0.0  0.0   0.0  1.4     0  0.0  4.4
         TRPR2 TRRE3 VEOF2
1.1.2001  21.5  53.5     0
1.2.2001   3.7  39.5     0
2.1.2001  32.0  40.0     0
2.2.2001   5.2  72.5     0
3.1.1998   0.5  16.5     0
3.1.1999   0.0   4.8     0

>MRM(dist(LOAR10) ~ dist(sitelocation), data=graze, nperm=100)

$coef
                   dist(LOAR10) pval
Int                  10.4452883 0.22
dist(sitelocation)   -0.4174337 0.42

$r.squared
         R2        pval 
0.003978668 0.420000000 

$F.test
       F   F.pval 
4.885349 0.420000 

结果中$coef里的pval是所有输入数据转化为矩阵的p值。

对于Backward Elimination思想,可将环境因子依次去掉一个做MRM,扔掉去掉因子后得到最小p值的因子,并重复这个过程。直到最大的p小于设定的阈值。

对于Forward Selection思想,可将环境因子依次与响应变量做MRM,保留最小的p值进入模型,并重复这个过程。直到最小的p大于设定的阈值。

手动挑选这种方法对因子比较少时适用。当因子多的时候还是要想点可以偷懒的策略。但是我在ecodist中也没有看到相关的函数。那就只能自己写代码了!

代码语言:javascript
复制
#Backward Elimination方法
>data(graze)
>test = graze[,-c(1:3)]
>head(test)

         ANOD ASSY BRIN2 CIAR4 CIIN CIVU DAGL ELRE4 GAMO LOAR10 LOCO6 LOPE OXST PLMA2
1.1.2001    0  0.0     0     0  0.0  0.0 20.5   4.7    0    1.5     0    0  0.0   4.0
1.2.2001    0  0.5     0     0  0.0  5.1  0.0   6.4    0    8.9     0    0  0.0   0.0
2.1.2001    0  0.0     0     0  0.0  0.0  2.2  21.5    0    7.0     0    0  0.7   0.0
2.2.2001    0  0.0     0     0  0.0  0.0  1.5   3.4    0   14.5     0   32  0.2   0.0
3.1.1998    0  0.0     0     0  0.0  0.2  0.0   0.0    0   36.5     0    0  0.5   6.9
3.1.1999    0  0.0     0     0  0.5  0.7  0.0   0.0    0   71.5     0    4  0.0   3.6
         POPR PRVU RAAC3 RUCR SORU2 STGR TAOF TRPR2 TRRE3 VEOF2
1.1.2001 35.0  1.7   0.9  0.2     0 22.5 58.0  21.5  53.5     0
1.2.2001 54.5  1.0   0.5  0.0     0 10.8 39.0   3.7  39.5     0
2.1.2001 52.0  0.0   0.2  0.0     0  8.7  7.4  32.0  40.0     0
2.2.2001 11.0  0.0   0.0  0.0     0 11.4  5.7   5.2  72.5     0
3.1.1998  0.1  0.0   0.0  3.7     0  0.0  2.9   0.5  16.5     0
3.1.1999  0.0  0.0   0.0  1.4     0  0.0  4.4   0.0   4.8     0

>response = test[,1:5] #前5列为响应变量
>predictor = test[,-c(1:5)] #剩余变量作为输入变量
>all = MRM(dist(response) ~ dist(predictor), nperm=10)
>origin.p = all$coef[2,2];origin.p # p = 0.276
[1] 0.276
#设定一个阈值,如p=0.2时终止
>p.set = 0.2
>p.last = origin.p
>while (p.last > p.set){  
#每一列分别进行MRM,最大的p去掉后再重新对整体做MRM
p.each = c()
 for (i in 1:ncol(predictor)) {
  each = MRM(dist(response) ~ dist(predictor[,-i]), nperm=10)
  p.each = cbind(p.each,each$coef[2,2])
 }
p.each  ##去掉最大p值的变量,再重新对剩下来的整体做MRM。这里有个小缺陷,如果同时有多个最大值,则一次全去掉了。
predictor = predictor[,-c(which(p.each == max(p.each)))]

all.new = MRM(dist(response) ~ dist(predictor), nperm=10)
p.last = all.new$coef[2,2]
print(ncol(predictor))
}
[1] 18
>p.last
[1] 0.185
>ncol(predictor)
[1] 18

Backward Elimination的方法只去掉一个因子就满足了条件。最终p为0.185。

代码语言:javascript
复制
###############
#Forward Selection
>data(graze)
>test = (graze[,-c(1:3)])
>head(test)
>response = test[,1:5] #前5列为响应变量
>predictor = test[,-c(1:5)] #剩余变量作为输入变量
#设定一个阈值,如p=0.2时终止
>p.set = 0.2
>p.last = 0.01
>predictor.new = matrix(data=NA,nrow=nrow(test))
>while (p.last < p.set){  
  #每一列分别进行MRM,取最小的p值加入predictor后重新对整体做MRM
  p.each = c()
  for (i in 1:ncol(predictor)) {
    each = MRM(dist(response) ~ dist(cbind(predictor.new,predictor[,i])), nperm=10)
    p.each = cbind(p.each,each$coef[2,2])
  }
  p.each  ##取最小p值的变量,再重新对剩下来的整体做MRM。这里有个小缺陷,如果同时有多个最小值,则一次全加入模型。
  predictor.new = cbind(predictor.new, predictor[,c(which(p.each == min(p.each)))] )
  predictor = predictor[,-c(which(p.each == min(p.each)))]

  all = MRM(dist(response) ~ dist(predictor.new), nperm=10)
  p.last = all$coef[2,2]
  print(ncol(predictor.new))
}
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
[1] 8
>p.last
[1] 0.216
>ncol(predictor.new)
[1] 8

Forward Selection进行了7次循环。最终变量为8个,p为0.216。 此结果再次证明了第二部分中,Backward Elimination更有优势的观点,其能够保留更多的变量。

这两种方法的代码在小细节上有不少差别,需要仔细看哦~

这两段代码很多地方还可以优化,如一次只严格的去掉或增加一个变量;for循环的优化等。以后用到了再做吧。 还有一个细节需要注意,如果nperm次数太少每次的结果都会差挺大的。nperm=1000每次结果也会有差别。

Plus:

最后的代码只是我自己在学习了基本概念之后进行的练习,并不一定完全正确,仅供参考。

Plus plus:

向别人提问是学习的一种正常途径。对问题的不同看法更可以让彼此多了解一种观点。如果有问题欢迎讨论。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Listenlii 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Backward Elimination的方法只去掉一个因子就满足了条件。最终p为0.185。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档