Ling 105: session 05: bin. logistic regr. 2 (key)

Author
Affiliations

UC Santa Barbara

JLU Giessen

Published

29 Apr 2024 12-34-56

1 Introduction

We are dealing with the same data set as last session; as a reminder, the data are in _input/genitives.csv and you can find information about the variables/columns in _input/genitives.r. However, this session, we will deal with this in a multifactorial way. Specifically, we are asking, does the choice of a genitive construction (of vs. s) vary as a function of

  • a length-based short-before-long effect, but, this time, if we hypothesize a short-before-long effect, maybe we should not just be looking at the length of the possessor (POR_LENGTH), but how the length of the possessor compares to the length of the possessum (PUM_LENGTH); since such a comparison variable doesn’t exist yet in our data set, we need to create it first;
  • the degree/kind of animacy of the possessor (POR_ANIMACY: animate vs. collective vs. inanimate vs. locative vs. temporal);
  • whether the speakers are non-native speakers or native speakers of English (SPEAKER: nns vs. ns);
  • any pairwise interaction of these predictors;
  • the three-way interaction of these predictors?
rm(list=ls(all.names=TRUE))
library(car); library(effects); library(magrittr); library(multcomp)
source("_helpers/R2s.r"); source("_helpers/C.score.r"); source("_helpers/cohens.kappa.r")
summary(d <- read.delim(        # summarize d, the result of loading
   file="_input/genitives.csv", # this file
   stringsAsFactors=TRUE))      # change categorical variables into factors
      CASE      GENITIVE  SPEAKER       MODALITY      POR_LENGTH
 Min.   :   2   of:2720   nns:2666   spoken :1685   Min.   :  1.00
 1st Qu.:1006   s : 880   ns : 934   written:1915   1st Qu.:  8.00
 Median :2018                                       Median : 11.00
 Mean   :2012                                       Mean   : 14.58
 3rd Qu.:3017                                       3rd Qu.: 17.00
 Max.   :4040                                       Max.   :204.00
   PUM_LENGTH         POR_ANIMACY   POR_FINAL_SIB        POR_DEF
 Min.   :  2.00   animate   : 920   absent :2721   definite  :2349
 1st Qu.:  6.00   collective: 607   present: 879   indefinite:1251
 Median :  9.00   inanimate :1671
 Mean   : 10.35   locative  : 243
 3rd Qu.: 13.00   temporal  : 159
 Max.   :109.00                                                     

2 Deviance & baseline(s)

Let’s already compute the baselines for what will be the response variable, GENITIVE:

(baselines <- c(
   "baseline 1"=max(          # make baselines[1] the highest
      prop.table(             # proportion in the
         table(d$GENITIVE))), # frequency table of the response
   "baseline 2"=sum(             # make baselines[2] the sum of the
      prop.table(                # proportions in the
         table(d$GENITIVE))^2))) # frequency table of the response squared
baseline 1 baseline 2
 0.7555556  0.6306173 

Let’s compute the deviance of the null model:

m_00 <- glm(GENITIVE ~ 1, family=binomial, data=d, na.action=na.exclude)
deviance(m_00)
[1] 4004.273
sum(residuals(m_00)^2)
[1] 4004.273

3 Exploration & preparation

Some exploration of the relevant variables:

# the predictor(s)/response on its/their own
hist(d$LEN_PORmPUM_LOG <- log2(d$POR_LENGTH)-log2(d$PUM_LENGTH), main="")

table(d$POR_ANIMACY)

   animate collective  inanimate   locative   temporal
       920        607       1671        243        159 
table(d$SPEAKER)

 nns   ns
2666  934 
# the predictor(s) w/ the response
spineplot(d$GENITIVE ~ d$LEN_PORmPUM_LOG)

table(d$POR_ANIMACY, d$GENITIVE)

               of    s
  animate     370  550
  collective  408  199
  inanimate  1638   33
  locative    199   44
  temporal    105   54
table(d$SPEAKER, d$GENITIVE)

        of    s
  nns 2024  642
  ns   696  238
ftable(d$POR_ANIMACY, d$SPEAKER, d$GENITIVE)
                  of    s

animate    nns   272  406
           ns     98  144
collective nns   314  138
           ns     94   61
inanimate  nns  1250   27
           ns    388    6
locative   nns   117   34
           ns     82   10
temporal   nns    71   37
           ns     34   17

4 Modeling & numerical interpretation

Let’s fit our initial regression model:

summary(m_01 <- glm(      # make/summarize the gen. linear model m_01:
   GENITIVE ~ 1 +         # GENITIVE ~ an overall intercept (1)
   LEN_PORmPUM_LOG*POR_ANIMACY*SPEAKER, # & these predictors & their interaction
   family=binomial,       # resp = binary
   data=d,                # those vars are in d
   na.action=na.exclude)) # skip cases with NA/missing data

Call:
glm(formula = GENITIVE ~ 1 + LEN_PORmPUM_LOG * POR_ANIMACY *
    SPEAKER, family = binomial, data = d, na.action = na.exclude)

Coefficients:
                                                Estimate Std. Error z value
(Intercept)                                      0.65632    0.09135   7.184
LEN_PORmPUM_LOG                                 -0.70601    0.08154  -8.659
POR_ANIMACYcollective                           -1.77888    0.16150 -11.015
POR_ANIMACYinanimate                            -4.32698    0.21686 -19.953
POR_ANIMACYlocative                             -2.30616    0.27227  -8.470
POR_ANIMACYtemporal                             -1.32138    0.22536  -5.863
SPEAKERns                                       -0.08278    0.17204  -0.481
LEN_PORmPUM_LOG:POR_ANIMACYcollective           -0.46680    0.15054  -3.101
LEN_PORmPUM_LOG:POR_ANIMACYinanimate             0.32099    0.17729   1.811
LEN_PORmPUM_LOG:POR_ANIMACYlocative             -0.29249    0.25885  -1.130
LEN_PORmPUM_LOG:POR_ANIMACYtemporal              0.44522    0.18375   2.423
LEN_PORmPUM_LOG:SPEAKERns                        0.14245    0.16001   0.890
POR_ANIMACYcollective:SPEAKERns                  0.79493    0.29353   2.708
POR_ANIMACYinanimate:SPEAKERns                  -0.28854    0.51213  -0.563
POR_ANIMACYlocative:SPEAKERns                   -0.50011    0.49785  -1.005
POR_ANIMACYtemporal:SPEAKERns                    0.16161    0.41275   0.392
LEN_PORmPUM_LOG:POR_ANIMACYcollective:SPEAKERns -0.14283    0.28943  -0.493
LEN_PORmPUM_LOG:POR_ANIMACYinanimate:SPEAKERns  -0.65372    0.43153  -1.515
LEN_PORmPUM_LOG:POR_ANIMACYlocative:SPEAKERns   -0.19485    0.50679  -0.384
LEN_PORmPUM_LOG:POR_ANIMACYtemporal:SPEAKERns   -0.53061    0.38091  -1.393
                                                Pr(>|z|)
(Intercept)                                     6.75e-13 ***
LEN_PORmPUM_LOG                                  < 2e-16 ***
POR_ANIMACYcollective                            < 2e-16 ***
POR_ANIMACYinanimate                             < 2e-16 ***
POR_ANIMACYlocative                              < 2e-16 ***
POR_ANIMACYtemporal                             4.54e-09 ***
SPEAKERns                                        0.63039
LEN_PORmPUM_LOG:POR_ANIMACYcollective            0.00193 **
LEN_PORmPUM_LOG:POR_ANIMACYinanimate             0.07022 .
LEN_PORmPUM_LOG:POR_ANIMACYlocative              0.25849
LEN_PORmPUM_LOG:POR_ANIMACYtemporal              0.01539 *
LEN_PORmPUM_LOG:SPEAKERns                        0.37331
POR_ANIMACYcollective:SPEAKERns                  0.00677 **
POR_ANIMACYinanimate:SPEAKERns                   0.57315
POR_ANIMACYlocative:SPEAKERns                    0.31511
POR_ANIMACYtemporal:SPEAKERns                    0.69538
LEN_PORmPUM_LOG:POR_ANIMACYcollective:SPEAKERns  0.62166
LEN_PORmPUM_LOG:POR_ANIMACYinanimate:SPEAKERns   0.12980
LEN_PORmPUM_LOG:POR_ANIMACYlocative:SPEAKERns    0.70062
LEN_PORmPUM_LOG:POR_ANIMACYtemporal:SPEAKERns    0.16362
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 4004.3  on 3599  degrees of freedom
Residual deviance: 2404.3  on 3580  degrees of freedom
AIC: 2444.3

Number of Fisher Scoring iterations: 7
pchisq(              # compute the area under the chi-squared curve
   q =m_01$null.deviance-m_01$deviance, # for this chi-squared value: null - res. dev.
   df=m_01$df.null-m_01$df.residual,    # at this df: null - residual df
   lower.tail=FALSE) # only using the right/upper tail/side
[1] 0
drop1(m_01,      # drop each droppable predictor at a time from m_01 &
   test="Chisq") # test its significance w/ a LRT
Single term deletions

Model:
GENITIVE ~ 1 + LEN_PORmPUM_LOG * POR_ANIMACY * SPEAKER
                                    Df Deviance    AIC    LRT Pr(>Chi)
<none>                                   2404.3 2444.3
LEN_PORmPUM_LOG:POR_ANIMACY:SPEAKER  4   2408.0 2440.0 3.7384   0.4426

Let’s fit the 2nd model with that 3-way interaction LEN_PORmPUM_LOG:POR_ANIMACY:SPEAKER deleted:

summary(m_02 <- update( # make m_02 an update of
   m_01, .~.            # m_01, namely all of it (.~.), but then
   - LEN_PORmPUM_LOG:POR_ANIMACY:SPEAKER)) # remove this interaction

Call:
glm(formula = GENITIVE ~ LEN_PORmPUM_LOG + POR_ANIMACY + SPEAKER +
    LEN_PORmPUM_LOG:POR_ANIMACY + LEN_PORmPUM_LOG:SPEAKER + POR_ANIMACY:SPEAKER,
    family = binomial, data = d, na.action = na.exclude)

Coefficients:
                                      Estimate Std. Error z value Pr(>|z|)
(Intercept)                            0.63865    0.08956   7.131 9.99e-13 ***
LEN_PORmPUM_LOG                       -0.66568    0.07506  -8.869  < 2e-16 ***
POR_ANIMACYcollective                 -1.75874    0.15934 -11.038  < 2e-16 ***
POR_ANIMACYinanimate                  -4.30116    0.21500 -20.006  < 2e-16 ***
POR_ANIMACYlocative                   -2.29342    0.26298  -8.721  < 2e-16 ***
POR_ANIMACYtemporal                   -1.31543    0.22698  -5.795 6.82e-09 ***
SPEAKERns                             -0.01779    0.16826  -0.106   0.9158
LEN_PORmPUM_LOG:POR_ANIMACYcollective -0.50145    0.12853  -3.901 9.56e-05 ***
LEN_PORmPUM_LOG:POR_ANIMACYinanimate   0.20466    0.15951   1.283   0.1995
LEN_PORmPUM_LOG:POR_ANIMACYlocative   -0.34103    0.22263  -1.532   0.1256
LEN_PORmPUM_LOG:POR_ANIMACYtemporal    0.31318    0.16011   1.956   0.0505 .
LEN_PORmPUM_LOG:SPEAKERns             -0.02120    0.11639  -0.182   0.8555
POR_ANIMACYcollective:SPEAKERns        0.72665    0.29266   2.483   0.0130 *
POR_ANIMACYinanimate:SPEAKERns        -0.30015    0.48555  -0.618   0.5365
POR_ANIMACYlocative:SPEAKERns         -0.55095    0.45355  -1.215   0.2245
POR_ANIMACYtemporal:SPEAKERns          0.08259    0.40494   0.204   0.8384
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 4004.3  on 3599  degrees of freedom
Residual deviance: 2408.0  on 3584  degrees of freedom
AIC: 2440

Number of Fisher Scoring iterations: 7
anova(m_01, m_02, # compare m_01 to m_02
   test="Chisq")  # using a LRT
Analysis of Deviance Table

Model 1: GENITIVE ~ 1 + LEN_PORmPUM_LOG * POR_ANIMACY * SPEAKER
Model 2: GENITIVE ~ LEN_PORmPUM_LOG + POR_ANIMACY + SPEAKER + LEN_PORmPUM_LOG:POR_ANIMACY +
    LEN_PORmPUM_LOG:SPEAKER + POR_ANIMACY:SPEAKER
  Resid. Df Resid. Dev Df Deviance Pr(>Chi)
1      3580     2404.3
2      3584     2408.0 -4  -3.7384   0.4426
drop1(m_02,      # drop each droppable predictor at a time from m_02 &
   test="Chisq") # test its significance w/ a LRT
Single term deletions

Model:
GENITIVE ~ LEN_PORmPUM_LOG + POR_ANIMACY + SPEAKER + LEN_PORmPUM_LOG:POR_ANIMACY +
    LEN_PORmPUM_LOG:SPEAKER + POR_ANIMACY:SPEAKER
                            Df Deviance    AIC    LRT  Pr(>Chi)
<none>                           2408.0 2440.0
LEN_PORmPUM_LOG:POR_ANIMACY  4   2439.8 2463.8 31.766 2.136e-06 ***
LEN_PORmPUM_LOG:SPEAKER      1   2408.0 2438.0  0.033   0.85530
POR_ANIMACY:SPEAKER          4   2418.9 2442.9 10.880   0.02794 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Let’s fit the 3rd model with that interaction LEN_PORmPUM_LOG:SPEAKER deleted:

summary(m_03 <- update( # make m_03 an update of
   m_02, .~.            # m_02, namely all of it (.~.), but then
   - LEN_PORmPUM_LOG:SPEAKER)) # remove this interaction

Call:
glm(formula = GENITIVE ~ LEN_PORmPUM_LOG + POR_ANIMACY + SPEAKER +
    LEN_PORmPUM_LOG:POR_ANIMACY + POR_ANIMACY:SPEAKER, family = binomial,
    data = d, na.action = na.exclude)

Coefficients:
                                      Estimate Std. Error z value Pr(>|z|)
(Intercept)                            0.64082    0.08887   7.211 5.57e-13 ***
LEN_PORmPUM_LOG                       -0.67066    0.06999  -9.582  < 2e-16 ***
POR_ANIMACYcollective                 -1.76343    0.15747 -11.198  < 2e-16 ***
POR_ANIMACYinanimate                  -4.30316    0.21475 -20.038  < 2e-16 ***
POR_ANIMACYlocative                   -2.29898    0.26155  -8.790  < 2e-16 ***
POR_ANIMACYtemporal                   -1.31845    0.22659  -5.819 5.93e-09 ***
SPEAKERns                             -0.02626    0.16145  -0.163  0.87078
LEN_PORmPUM_LOG:POR_ANIMACYcollective -0.50226    0.12847  -3.910 9.25e-05 ***
LEN_PORmPUM_LOG:POR_ANIMACYinanimate   0.20638    0.15920   1.296  0.19486
LEN_PORmPUM_LOG:POR_ANIMACYlocative   -0.34169    0.22268  -1.534  0.12492
LEN_PORmPUM_LOG:POR_ANIMACYtemporal    0.31237    0.16007   1.951  0.05100 .
POR_ANIMACYcollective:SPEAKERns        0.73847    0.28489   2.592  0.00954 **
POR_ANIMACYinanimate:SPEAKERns        -0.29379    0.48413  -0.607  0.54396
POR_ANIMACYlocative:SPEAKERns         -0.53295    0.44234  -1.205  0.22827
POR_ANIMACYtemporal:SPEAKERns          0.08969    0.40281   0.223  0.82380
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 4004.3  on 3599  degrees of freedom
Residual deviance: 2408.0  on 3585  degrees of freedom
AIC: 2438

Number of Fisher Scoring iterations: 7
anova(m_02, m_03, # compare m_02 to m_03
   test="Chisq")  # using a LRT
Analysis of Deviance Table

Model 1: GENITIVE ~ LEN_PORmPUM_LOG + POR_ANIMACY + SPEAKER + LEN_PORmPUM_LOG:POR_ANIMACY +
    LEN_PORmPUM_LOG:SPEAKER + POR_ANIMACY:SPEAKER
Model 2: GENITIVE ~ LEN_PORmPUM_LOG + POR_ANIMACY + SPEAKER + LEN_PORmPUM_LOG:POR_ANIMACY +
    POR_ANIMACY:SPEAKER
  Resid. Df Resid. Dev Df  Deviance Pr(>Chi)
1      3584       2408
2      3585       2408 -1 -0.033257   0.8553
drop1(m_03,      # drop each droppable predictor at a time from m_03 &
   test="Chisq") # test its significance w/ a LRT
Single term deletions

Model:
GENITIVE ~ LEN_PORmPUM_LOG + POR_ANIMACY + SPEAKER + LEN_PORmPUM_LOG:POR_ANIMACY +
    POR_ANIMACY:SPEAKER
                            Df Deviance    AIC    LRT  Pr(>Chi)
<none>                           2408.0 2438.0
LEN_PORmPUM_LOG:POR_ANIMACY  4   2440.0 2462.0 31.930 1.977e-06 ***
POR_ANIMACY:SPEAKER          4   2419.1 2441.1 11.066   0.02583 *
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Confint(m_final <- m_03); rm(m_03); invisible(gc())
                                         Estimate        2.5 %      97.5 %
(Intercept)                            0.64081690  0.468616712  0.81724071
LEN_PORmPUM_LOG                       -0.67065848 -0.810966407 -0.53635908
POR_ANIMACYcollective                 -1.76342664 -2.077305396 -1.45947457
POR_ANIMACYinanimate                  -4.30316052 -4.744994412 -3.90029037
POR_ANIMACYlocative                   -2.29898489 -2.838931650 -1.80923537
POR_ANIMACYtemporal                   -1.31844526 -1.772188001 -0.88148760
SPEAKERns                             -0.02626334 -0.341841030  0.29159142
LEN_PORmPUM_LOG:POR_ANIMACYcollective -0.50225743 -0.759750437 -0.25528062
LEN_PORmPUM_LOG:POR_ANIMACYinanimate   0.20637789 -0.102927878  0.52190369
LEN_PORmPUM_LOG:POR_ANIMACYlocative   -0.34169459 -0.798758018  0.07811273
LEN_PORmPUM_LOG:POR_ANIMACYtemporal    0.31237087 -0.008354092  0.62161919
POR_ANIMACYcollective:SPEAKERns        0.73846679  0.180371066  1.29820145
POR_ANIMACYinanimate:SPEAKERns        -0.29379122 -1.331890328  0.59609089
POR_ANIMACYlocative:SPEAKERns         -0.53294681 -1.434208534  0.31251344
POR_ANIMACYtemporal:SPEAKERns          0.08968869 -0.708937514  0.87541391

Let’s compute the overall significance test for this model:

anova(m_00, m_final, # compare m_00 to m_final
   test="Chisq")     # using a LRT
Analysis of Deviance Table

Model 1: GENITIVE ~ 1
Model 2: GENITIVE ~ LEN_PORmPUM_LOG + POR_ANIMACY + SPEAKER + LEN_PORmPUM_LOG:POR_ANIMACY +
    POR_ANIMACY:SPEAKER
  Resid. Df Resid. Dev Df Deviance  Pr(>Chi)
1      3599     4004.3
2      3585     2408.0 14   1596.2 < 2.2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
pchisq(              # compute the area under the chi-squared curve
   q=1596.2,         # for this chi-squared value
   df=14,            # at 14 df
   lower.tail=FALSE) # only using the right/upper tail/side
[1] 0

Let’s make ‘predictions’ and evaluate them:

d$PRED_PP_S <- predict( # make d$PRED_PP_S the result of predicting
   m_final,              # from m_final
   type="response")      # predicted probabilities of "s"
# if you don't say type="response", predict gives you log odds
d$PRED_CAT <- factor(         # make d$PRED_CAT the result of checking
   ifelse(d$PRED_PP_S>=0.5,   # if the predicted prob. of "s" is >=0.5
      levels(d$GENITIVE)[2],  # if yes, predict "s"
      levels(d$GENITIVE)[1])) # otherwise, predict "of"
(c_m <- table(           # confusion matrix: cross-tabulate
   "OBS"  =d$GENITIVE,   # observed genitives in the rows
   "PREDS"=d$PRED_CAT)) # predicted orders in the columns
    PREDS
OBS    of    s
  of 2454  266
  s   310  570
c( # evaluate the confusion matrix
   "Prec. for s"     =c_m[ "s", "s"] / sum(c_m[    , "s"]),
   "Acc./rec. for s" =c_m[ "s", "s"] / sum(c_m[ "s",    ]),
   "Prec. for of"    =c_m["of","of"] / sum(c_m[    ,"of"]),
   "Acc./rec. for of"=c_m["of","of"] / sum(c_m["of",    ]),
   "Acc. (overall)"  =mean(d$GENITIVE==d$PRED_CAT))
     Prec. for s  Acc./rec. for s     Prec. for of Acc./rec. for of
       0.6818182        0.6477273        0.8878437        0.9022059
  Acc. (overall)
       0.8400000 
c(R2s(m_01),
  "Cohen's kappa"=cohens.kappa(c_m)[[1]],
  "C"=C.score(d$GENITIVE, d$PRED_PP_S))
  McFadden R-squared Nagelkerke R-squared        Cohen's kappa
           0.3995747            0.5345978            0.5593935
                   C
           0.8985971 

This looks like a pretty decent model, not bad at all (esp. Cohen’s kappa and the C-score).

5 Visual interpretation

5.1 The interaction LEN_PORmPUM_LOG:POR_ANIMACY

Let’s visualize the nature of the effect of LEN_PORmPUM_LOG:POR_ANIMACY based on the predictions:

(lean_d <- data.frame(                    # make lean_d a data frame of
   lean <- effect(                        # the effect
      "LEN_PORmPUM_LOG:POR_ANIMACY",      # of LEN_PORmPUM_LOG:POR_ANIMACY
      xlevels=list(LEN_PORmPUM_LOG=-4:4), # w/ these values for LEN_PORmPUM_LOG
      m_final)))                          # in m_final
   LEN_PORmPUM_LOG POR_ANIMACY         fit          se        lower       upper
1               -4     animate 0.964995167 0.010732807 0.9366654268 0.980911180
2               -3     animate 0.933762692 0.015464168 0.8962219877 0.958354439
3               -2     animate 0.878181385 0.019688827 0.8340490730 0.911818185
4               -1     animate 0.786618460 0.020577239 0.7435273242 0.824181653
5                0     animate 0.653396580 0.017519047 0.6183110604 0.686890163
6                1     animate 0.490837160 0.020513568 0.4507767242 0.531015622
7                2     animate 0.330192632 0.029080480 0.2758733167 0.389455090
8                3     animate 0.201334835 0.031196146 0.1470135317 0.269388791
9                4     animate 0.114190794 0.026335613 0.0718292027 0.176777133
10              -4  collective 0.977108479 0.009125137 0.9504633183 0.989578685
11              -3  collective 0.929623169 0.019952030 0.8790212514 0.960022358
12              -2  collective 0.803450188 0.032664294 0.7315682184 0.859772887
13              -1  collective 0.558501674 0.030970559 0.4972271761 0.618044933
14               0  collective 0.281338372 0.022128739 0.2400611313 0.326662174
15               1  collective 0.108056512 0.017076640 0.0788544432 0.146354725
16               2  collective 0.036135870 0.009475954 0.0215225418 0.060062271
17               3  collective 0.011468910 0.004239852 0.0055436094 0.023577327
18               4  collective 0.003577539 0.001705505 0.0014037321 0.009087051
19              -4   inanimate 0.131443260 0.069510582 0.0438729443 0.332938978
20              -3   inanimate 0.086864232 0.037608215 0.0361996368 0.194153942
21              -2   inanimate 0.056422056 0.018427345 0.0294486514 0.105418163
22              -1   inanimate 0.036225313 0.008239215 0.0231206688 0.056329289
23               0   inanimate 0.023081315 0.004063324 0.0163254197 0.032540495
24               1   inanimate 0.014634072 0.003229110 0.0094845324 0.022515951
25               2   inanimate 0.009249061 0.003021352 0.0048681010 0.017503241
26               3   inanimate 0.005833881 0.002646221 0.0023938177 0.014147422
27               4   inanimate 0.003675066 0.002161627 0.0011583720 0.011596083
28              -4    locative 0.904318818 0.065050659 0.6840949593 0.976331696
29              -3    locative 0.774484239 0.095877338 0.5393933482 0.909678349
30              -2    locative 0.555138390 0.087955205 0.3830574676 0.714940059
31              -1    locative 0.311975694 0.043846419 0.2330327080 0.403589135
32               0    locative 0.141455667 0.026043363 0.0976551339 0.200535737
33               1    locative 0.056486712 0.019914540 0.0279778871 0.110735922
34               2    locative 0.021290829 0.011835875 0.0070950857 0.062112445
35               3    locative 0.007842601 0.006002145 0.0017399124 0.034608204
36               4    locative 0.002864010 0.002793417 0.0004221157 0.019161222
37              -4    temporal 0.683948493 0.127825282 0.4044341600 0.873357610
38              -3    temporal 0.601972295 0.109156405 0.3824363698 0.786943563
39              -2    temporal 0.513847009 0.081662166 0.3577119523 0.667325461
40              -1    temporal 0.424852275 0.053325703 0.3250602122 0.531170088
41               0    temporal 0.340476161 0.038786244 0.2689980630 0.420033935
42               1    temporal 0.265132480 0.045062208 0.1865229243 0.362123903
43               2    temporal 0.201370889 0.055382698 0.1137786495 0.331195140
44               3    temporal 0.149817159 0.060437310 0.0650079736 0.308734224
45               4    temporal 0.109649779 0.059635675 0.0358613321 0.289652708
plot(lean,          # plot the effect of LEN_PORmPUM_LOG:POR_ANIMACY
   type="response", # but plot predicted probabilities
   ylim=c(0, 1),    # ylim: the whole range of possible probabilities
   grid=TRUE)       # & w/ a grid

This might be better with a one-panel kind of plot:

plot(lean,                      # plot the effect of LEN_PORmPUM_LOG:POR_ANIMACY
   type="response",             # but plot predicted probs
   ylim=c(0, 1), grid=TRUE,     # w/ these y-axis limits & w/ a grid
   multiline=TRUE,              # put all lines in one panel
   confint=list(style="auto"),  # keep confidence intervals
   lattice=list(key.args=list(  # make the
      columns=5, cex.title=0))) # legend have 5 columns & no title

BTW: Do you recognize a couple of (related) general conceptual problems here?

5.2 Excursus on predictions and slopes

To better understand the results, we return to my very pedestrian approach from earlier: I generate a data frame nd of all predictions that help me understand the coefficients table in the summary output of the model. That means,

  • on the predictor side of the final model, nd will contain
    • each categorical predictor with all its levels;
    • each numeric predictor with values across its whole range while making sure those include 0 and 1;
  • on the response side of the final model, nd will contain
    • predictions on the probability scale (because those are the ones I usually (!) prefer to visualize);
    • predictions on the log odds scale (because those are the ones the coefficients table returns and because the slopes of curved lines can be difficult to compare).

Here, this would mean we’d do this (I am skipping the computation of the confidence intervals of the predicted probabilities):

nd <- expand.grid( # create a data frame nd that crosses
   # these values of each of these predictors
   LEN_PORmPUM_LOG=-5:5,
   POR_ANIMACY    =levels(d$POR_ANIMACY),
   SPEAKER        =levels(d$SPEAKER)
   )[,3:1] # change the order of columns to something nicer
# add predictions of the second level of the response: log odds % pred. probs.:
nd$PREDS_LO_S <- predict(m_final, newdata=nd)
nd$PRED_PP_S  <- predict(m_final, newdata=nd, type="response")

For a model like ours, there are two main ways to look at this that are useful: (i) we would just look at the data frame as is but focus on the two numeric values of LEN_PORmPUM_LOG that best illustrate the slope …

nd[nd$LEN_PORmPUM_LOG %in% 0:1,]
    SPEAKER POR_ANIMACY LEN_PORmPUM_LOG  PREDS_LO_S  PRED_PP_S
6       nns     animate               0  0.64081690 0.65493810
7       nns     animate               1 -0.02984158 0.49254016
17      nns  collective               0 -1.12260974 0.24552752
18      nns  collective               1 -2.29552565 0.09149420
28      nns   inanimate               0 -3.66234362 0.02502971
29      nns   inanimate               1 -4.12662421 0.01588099
39      nns    locative               0 -1.65816799 0.16000808
40      nns    locative               1 -2.67052106 0.06473541
50      nns    temporal               0 -0.67762836 0.33679083
51      nns    temporal               1 -1.03591597 0.26193878
61       ns     animate               0  0.61455356 0.64897883
62       ns     animate               1 -0.05610492 0.48597745
72       ns  collective               0 -0.41040630 0.39881470
73       ns  collective               1 -1.58332220 0.17032549
83       ns   inanimate               0 -3.98239818 0.01829976
84       ns   inanimate               1 -4.44667877 0.01158171
94       ns    locative               0 -2.21737814 0.09820074
95       ns    locative               1 -3.22973121 0.03806209
105      ns    temporal               0 -0.61420302 0.35110103
106      ns    temporal               1 -0.97249062 0.27438435

…, or (ii) we group the data a bit differently, but again in a way that makes assessing the slopes of LEN_PORmPUM_LOG as obvious as possible:

nd.grouped <- with( # make nd.grouped the result of
   # taking only the 0:1 length difference subset
   nd[nd$LEN_PORmPUM_LOG %in% 0:1,], tapply( # and apply
      PREDS_LO_S, # a grouping of the log-odds predictions
      list(POR_ANIMACY, LEN_PORmPUM_LOG, SPEAKER), # by all predictors
      c))         # just listing the values (there's just 1 per combo)
nd.grouped # what this looks like
, , nns

                    0           1
animate     0.6408169 -0.02984158
collective -1.1226097 -2.29552565
inanimate  -3.6623436 -4.12662421
locative   -1.6581680 -2.67052106
temporal   -0.6776284 -1.03591597

, , ns

                    0           1
animate     0.6145536 -0.05610492
collective -0.4104063 -1.58332220
inanimate  -3.9823982 -4.44667877
locative   -2.2173781 -3.22973121
temporal   -0.6142030 -0.97249062

This way, we can use apply to immediately see what the slopes of LEN_PORmPUM_LOG are for each level of POR_ANIMACY:

apply(            # apply to
   nd.grouped, 1, # nd.grouped row-by-row
   diff)          # the function diff
        animate collective  inanimate  locative   temporal
[1,] -0.6706585  -1.172916 -0.4642806 -1.012353 -0.3582876
[2,] -0.6706585  -1.172916 -0.4642806 -1.012353 -0.3582876

Why do we get the same result twice? Because apply does this to both the native and the non-native speaker data, but since LEN_PORmPUM_LOG only interacts with POR_ANIMACY and that interaction does not interact with not also with SPEAKER, the slopes are the same for both levels of SPEAKER.

(There is a simpler way to do this – simpler in terms of coding, that is – but as usual I am trying to show you a way that makes the logic of the approach explicit.)

This plot now shows the (straight-line) log odds slopes in a more comparable way:

plot(lean,                      # plot the effect of LEN_PORmPUM_LOG:POR_ANIMACY
   # note: no type="response"
   ylim=c(-5, 5), grid=TRUE,    # w/ these y-axis limits & w/ a grid
   multiline=TRUE,              # put all lines in one panel
   confint=list(style="auto"),  # keep confidence intervals
   lattice=list(key.args=list(  # make the
      columns=5, cex.title=0))) # legend have 5 columns & no title

5.3 The interaction POR_ANIMACY:SPEAKER

Let’s visualize the nature of the effect of POR_ANIMACY:SPEAKER based on the predictions, as always, we do both perspectives:

(ansp_d <- data.frame(       # make ansp_d a data frame of
   ansp <- effect(           # the effect
      "POR_ANIMACY:SPEAKER", # of POR_ANIMACY:SPEAKER
      m_final)))             # in m_final
   POR_ANIMACY SPEAKER        fit          se      lower      upper
1      animate     nns 0.59115315 0.020183766 0.55108531 0.63004555
2   collective     nns 0.16819763 0.021177629 0.13066029 0.21386608
3    inanimate     nns 0.02082207 0.004116296 0.01411360 0.03062019
4     locative     nns 0.11215912 0.029827786 0.06562281 0.18515703
5     temporal     nns 0.30513068 0.047091093 0.22126791 0.40427725
6      animate      ns 0.58479067 0.033545821 0.51791474 0.64868241
7   collective      ns 0.29188394 0.041924818 0.21690178 0.38020223
8    inanimate      ns 0.01520582 0.006205397 0.00680714 0.03361612
9     locative      ns 0.06735270 0.024460582 0.03256874 0.13413561
10    temporal      ns 0.31874217 0.066141896 0.20480038 0.45944946
plot(ansp,          # plot the effect of POR_ANIMACY:SPEAKER
   type="response", # but plot predicted probabilities
   ylim=c(0, 1),    # ylim: the whole range of possible probabilities
   grid=TRUE)       # & w/ a grid

plot(ansp,          # plot the effect of POR_ANIMACY:SPEAKER
   type="response", # but plot predicted probabilities
   ylim=c(0, 1),    # ylim: the whole range of possible probabilities
   x.var="SPEAKER", # w/ this predictor on the x-axis
   grid=TRUE)       # & w/ a grid

A multi-line plot might be better:

plot(ansp,          # plot the effect of POR_ANIMACY:SPEAKER
   type="response", # but plot predicted probabilities
   ylim=c(0, 1),    # ylim: the whole range of possible probabilities
   multiline=TRUE,  # all the lines in one panel, but
   confint=list(style="auto"), # w/ confidence intervals
   grid=TRUE)       # & w/ a grid

6 Excursus: predictions that are most wrong

To explore which predictions are the worst – wrong predictions made most confidently – let’s also compute the contributions to logloss; I’m doing this here in the very explicit two-step procedure just for didactic purposes:

d$PRED_PP_OBS <- ifelse( # d$PRED_PP_OBS is determined by ifelse
   d$GENITIVE=="s",         # if the obs genitive is the 2nd level of the response
     d$PRED_PP_S,        # take its predicted probability
   1-d$PRED_PP_S)        # otherwise take 1 minus its predicted probability
d$CONTRIBS2LL <- -log(d$PRED_PP_OBS)
head(d)
  CASE GENITIVE SPEAKER MODALITY POR_LENGTH PUM_LENGTH POR_ANIMACY
1    2       of     nns   spoken         13          7  collective
2    3       of     nns   spoken         22          7     animate
3    4       of     nns   spoken         11          8     animate
4    5       of     nns   spoken         26          4  collective
5    6        s     nns   spoken          8          4     animate
6    7        s     nns   spoken          7          3     animate
  POR_FINAL_SIB  POR_DEF LEN_PORmPUM_LOG  PRED_PP_S PRED_CAT PRED_PP_OBS
1        absent definite       0.8930848 0.10246571       of   0.8975343
2        absent definite       1.6520767 0.38528810       of   0.6147119
3       present definite       0.4594316 0.58241501        s   0.4175850
4        absent definite       2.7004397 0.01351966       of   0.9864803
5        absent definite       1.0000000 0.49254016       of   0.4925402
6        absent definite       1.2223924 0.45537135       of   0.4553713
  CONTRIBS2LL
1  0.10810395
2  0.48660157
3  0.87326719
4  0.01361188
5  0.70817928
6  0.78664204

There are many ways one could look at this, the following are just two suggestions. First, we could look at the general distribution of the contributions to logloss to see what it looks like and what values might be considered ‘extreme’; an ecdf plot could be good for that:

plot(ecdf(d$CONTRIBS2LL)); grid()
   abline(h=0.9)

This shows a very extreme distribution: about 90% of the logloss values are ≤1 (but then our model was quite good).

Second, we could do a very simple monofactorial exploration of each predictor against logloss; one time, we do so for all logloss values (top row), the other we zoom into the ‘extreme’ logloss values:

par(mfrow=c(2,3))
with(d, {
   plot(CONTRIBS2LL ~ LEN_PORmPUM_LOG, xlim=c(-5,5))
   plot(CONTRIBS2LL ~ POR_ANIMACY)
   plot(CONTRIBS2LL ~ SPEAKER)})
with(d[d$CONTRIBS2LL>1,], {
   plot(CONTRIBS2LL ~ LEN_PORmPUM_LOG, xlim=c(-5,5))
   plot(CONTRIBS2LL ~ POR_ANIMACY)
   plot(CONTRIBS2LL ~ SPEAKER)})

par(mfrow=c(1,1))

It seems as if contributions to logloss values are frequently high for

  • length difference values close to 0, but also positive ones;
  • inanimate possessors;
  • to maybe a lesser extent for non-native speakers.

7 Excursus: prototypes

Something else that may well be worth your time involves taking a quick look at which combinations of predictor values (numeric as well as levels) yields the highest predicted probabilities for each level of the response variable. Why might that be interesting? Because of the connection it makes to prototypes. The prototype of a category can be defined “as an abstract entity – i.e., an abstract notion that may not actually exist in the real world –- that exhibits the features (or properties) f1-n that have the highest cue validity for a category, where cue validity, […], can in turn be defined as follows: A feature/property (e.g., ‘having a beak’) has a high cue validity for a category (e.g., ‘birds’) if

  • many members of the category have the feature (and yes, all birds have beaks);
  • most non-members of the category do not have the feature (most non-birds have no beaks – animals that are not birds but have beaks make up a small set of some turtles, octopuses, platypuses/echidnas, and pufferfish).” (Gries, Slocum, & Tobia 2024)

Armed with this definition, we might follow Gries (2003) and stipulate for our data here that

  • (observed or hypothetical) instances with the highest predicted probabilities of s-genitives should constitute prototypical s-genitives and
  • (observed or hypothetical) instances with the lowest predicted probabilities of s-genitives should constitute prototypical of-genitives

(according to our model at least). We can try and identify such prototypes in three places:

  • the model summary (i.e., the coefficients): m_final$coef;
  • the predictions we generated for new/hypothetical data in nd;
  • the predictions for the actual data (d$PRED_PP_S).

The inferences from these three places will converge but, because of the presence of interactions, identifying the highest predicted probabilities from the model’s coefficients can be tricky even in a relatively small final model like here (because of how you would need to add and subtract values). We will therefore immediately go to nd instead

qwe <- nd[order(nd$PRED_PP_S),]
qwe %>% head(15)
   SPEAKER POR_ANIMACY LEN_PORmPUM_LOG PREDS_LO_S    PRED_PP_S
99      ns    locative               5  -7.279144 0.0006893006
22     nns  collective               5  -6.987189 0.0009227867
44     nns    locative               5  -6.719933 0.0012051645
88      ns   inanimate               5  -6.303801 0.0018259976
77      ns  collective               5  -6.274986 0.0018792794
98      ns    locative               4  -6.266790 0.0018947148
33     nns   inanimate               5  -5.983747 0.0025130383
87      ns   inanimate               4  -5.839521 0.0029017928
21     nns  collective               4  -5.814273 0.0029757667
43     nns    locative               4  -5.707580 0.0033097075
32     nns   inanimate               4  -5.519466 0.0039919879
86      ns   inanimate               3  -5.375240 0.0046084714
97      ns    locative               3  -5.254437 0.0051971336
76      ns  collective               4  -5.102070 0.0060473469
31     nns   inanimate               3  -5.055185 0.0063357865
qwe %>% tail(15)
   SPEAKER POR_ANIMACY LEN_PORmPUM_LOG PREDS_LO_S PRED_PP_S
35     nns    locative              -4   2.391244 0.9161572
14     nns  collective              -3   2.396138 0.9165323
58      ns     animate              -3   2.626529 0.9325495
3      nns     animate              -3   2.652792 0.9341829
89      ns    locative              -5   2.844387 0.9450278
69      ns  collective              -3   3.108341 0.9572355
57      ns     animate              -4   3.297187 0.9643322
2      nns     animate              -4   3.323451 0.9652246
34     nns    locative              -5   3.403597 0.9678168
13     nns  collective              -4   3.569054 0.9725900
56      ns     animate              -5   3.967846 0.9814370
1      nns     animate              -5   3.994109 0.9819094
68      ns  collective              -4   4.281257 0.9863633
12     nns  collective              -5   4.741970 0.9913540
67      ns  collective              -5   5.454173 0.9957398

The most obvious results from looking at all theoretically possible combinations as generated in nd are that

  • very low predicted probabilities, i.e. prototypical of-genitives, are strongly associated with possessors that are much longer than their possessums;
  • very high predicted probabilities, i.e. prototypical s-genitives, are strongly associated with possessors that are much shorter than their possessums.

We can see this clearly, for instance, if we sort nd by the predicted probabilities and then plot the predicted probabilities on the x-axis and whether the length difference is the positive extreme (5, red) or the negative extreme (-5, blue) on the y-axis: extremely high predicted probabilities of s-genitives on the right only arise with blue lines, i.e. when the length difference is smallest, and extremely high predicted probabilities of of-genitives on the left only arise with red lines, i.e. when the length difference is largest:

plot(type="h", col="#FF000040", axes=FALSE,
   xlab="Predicted probability of an s-genitive"    , qwe$PRED_PP_S,
   ylab="Length difference is 5 (red) or -5 (blue)?", qwe$LEN_PORmPUM_LOG==5)
lines(qwe$PRED_PP_S, qwe$LEN_PORmPUM_LOG==-5, type="h", col="#0000FF40")
axis(1); axis(2, at=0:1, labels=c("FALSE", "TRUE"))

In addition, we can see that

  • very low predicted probabilities, i.e. prototypical of-genitives, are strongly associated with inanimate and locative possessors;
  • very high predicted probabilities, i.e. prototypical s-genitives, are strongly associated with animate (and maybe collective) possessors.
plot(type="h", col="#FF000040", axes=FALSE,
   xlab="Predicted probability of an s-genitive", qwe$PRED_PP_S,
   ylab="Animate (red) or inanimate (blue)?"    , qwe$POR_ANIMACY=="animate")
lines(qwe$PRED_PP_S, qwe$POR_ANIMACY=="inanimate", type="h", col="#0000FF40")
axis(1); axis(2, at=0:1, labels=c("FALSE", "TRUE"))

And we know from POR_ANIMACY:SPEAKER above that animate, inanimate, and locative possessors don’t differ much in their predictions between the two levels of SPEAKER so we can leave it at that. (In fact, we will later see that SPEAKER only makes a significant difference for collectives.)

The above already made a lot of sense, but it was based on nd, i.e. all theoretically possible configurations of values. To be safe, I recommend you also look at d or, more specifically, d$PRED_PP_S because it is possible that many of the theoretically possible configurations in nd are actually never attested. That would be fine because we said above a prototype is “an abstract notion that may not actually exist in the real world” – we’re just looking at the combination(s) of features – but wouldn’t we want to know whether the abstract prototype we infer from our model actually exists? (Hint: the answer is “yes”.) So let’s check out d:

qwe <- d[order(d$PRED_PP_S),]
qwe %>% head(15)
     CASE GENITIVE SPEAKER MODALITY POR_LENGTH PUM_LENGTH POR_ANIMACY
661   741       of     nns   spoken         79          4  collective
3442 3853       of      ns  written         90          4   inanimate
3263 3646       of      ns  written         88          5   inanimate
2904 3243       of      ns   spoken         99          6   inanimate
1779 1993       of     nns  written         94          4   inanimate
1074 1192       of     nns   spoken        116          5   inanimate
804   900       of     nns   spoken         88          4   inanimate
3149 3524       of      ns  written         40          3   inanimate
2366 2633       of     nns  written         62          3   inanimate
3218 3597       of      ns  written         89          4  collective
245   278       of     nns   spoken         58          4  collective
261   296       of     nns   spoken         58          4  collective
654   734       of     nns   spoken         76          4   inanimate
239   271       of     nns   spoken         52          3   inanimate
1449 1615       of     nns  written         68          4   inanimate
     POR_FINAL_SIB    POR_DEF LEN_PORmPUM_LOG   PRED_PP_S PRED_CAT PRED_PP_OBS
661         absent   definite        4.303781 0.002085659       of   0.9979143
3442        absent indefinite        4.491853 0.002310730       of   0.9976893
3263        absent indefinite        4.137504 0.002722820       of   0.9972772
2904        absent   definite        4.044394 0.002842763       of   0.9971572
1779       present indefinite        4.554589 0.003088579       of   0.9969114
1074        absent indefinite        4.536053 0.003115190       of   0.9968848
804         absent   definite        4.459432 0.003227640       of   0.9967724
3149        absent   definite        3.736966 0.003277476       of   0.9967225
2366        absent   definite        4.369234 0.003365210       of   0.9966348
3218        absent   definite        4.475733 0.003470205       of   0.9965298
245         absent   definite        3.857981 0.003513241       of   0.9964868
261         absent   definite        3.857981 0.003513241       of   0.9964868
654         absent indefinite        4.247928 0.003559484       of   0.9964405
239         absent indefinite        4.115477 0.003784387       of   0.9962156
1449        absent indefinite        4.087463 0.003833740       of   0.9961663
     CONTRIBS2LL
661  0.002087837
3442 0.002313404
3263 0.002726533
2904 0.002846812
1779 0.003093358
1074 0.003120053
804  0.003232860
3149 0.003282859
2366 0.003370885
3218 0.003476241
245  0.003519426
261  0.003519426
654  0.003565834
239  0.003791566
1449 0.003841108
qwe %>% tail(15)
     CASE GENITIVE SPEAKER MODALITY POR_LENGTH PUM_LENGTH POR_ANIMACY
24     27        s     nns   spoken          4         26     animate
872   972        s     nns   spoken          3         25  collective
898  1003        s     nns   spoken          3         25  collective
671   753        s     nns   spoken          4         34  collective
1386 1545        s     nns  written          1          7     animate
1406 1565        s     nns  written          1          7     animate
887   990        s     nns   spoken          3         26  collective
2968 3317        s      ns   spoken          4         25  collective
3238 3619        s      ns  written          4         27  collective
1147 1273        s     nns   spoken          6         59     animate
2466 2756        s     nns  written         11        109     animate
2981 3330        s      ns   spoken          4         28  collective
2979 3328        s      ns   spoken          4         31  collective
529   595        s     nns   spoken          3         36  collective
689   771        s     nns   spoken          4         64  collective
     POR_FINAL_SIB  POR_DEF LEN_PORmPUM_LOG PRED_PP_S PRED_CAT PRED_PP_OBS
24          absent definite       -2.700440 0.9206995        s   0.9206995
872         absent definite       -3.058894 0.9216670        s   0.9216670
898         absent definite       -3.058894 0.9216670        s   0.9216670
671         absent definite       -3.087463 0.9240524        s   0.9240524
1386        absent definite       -2.807355 0.9257793        s   0.9257793
1406       present definite       -2.807355 0.9257793        s   0.9257793
887         absent definite       -3.115477 0.9263265        s   0.9263265
2968        absent definite       -2.643856 0.9364706        s   0.9364706
3238        absent definite       -2.754888 0.9437919        s   0.9437919
1147        absent definite       -3.297681 0.9454444        s   0.9454444
2466        absent definite       -3.308753 0.9458261        s   0.9458261
2981        absent definite       -2.807355 0.9469688        s   0.9469688
2979        absent definite       -2.954196 0.9549815        s   0.9549815
529         absent definite       -3.584963 0.9561546        s   0.9561546
689         absent definite       -4.000000 0.9725900        s   0.9725900
     CONTRIBS2LL
24    0.08262154
872   0.08157127
898   0.08157127
671   0.07898655
1386  0.07711937
1406  0.07711937
887   0.07652856
2968  0.06563719
3238  0.05784957
1147  0.05610022
2466  0.05569653
2981  0.05448917
2979  0.04606335
529   0.04483566
689   0.02779269

It seems that our prototypes as inferred from nd are also attested:

  • the most strongly predicted of-genitives have long possessors, short possessums and are mostly inanimate (but also some collectives). Also, while we didn’t include the predictor POR_DEF in the model, it is striking to see that there is about a 50-50 balance of definite and indefinite for these of-genitives;
  • the most strongly predicted s-genitives have short possessors, long possessums and are mostly animate and collectives. Also, while we didn’t include the predictor POR_DEF in the model, it is striking to see that there is not a single case of indefinite for these s-genitives.

8 Write-up

To determine whether the choice of a genitive construction (of vsn s) varies as a function of

  • the length difference between logged possessor length and logged possessum length;
  • the degree/kind of animacy of the possessor (POR_ANIMACY: animate vs. collective vs. inanimate vs. locative vs. temporal);
  • whether the speakers are non-native speakers or native speakers of English (SPEAKER: nns vs. ns);
  • any pairwise interaction of these predictors;
  • the three-way interaction of these predictors,

A generalized linear model selection process was undertaken (using backwards stepwise model selection of all predictors and controls based on significance testing). The final model resulting from the elimination of ns predictors contained the effects of LEN_PORmPUM_LOG:POR_ANIMACY and SPEAKER:POR_ANIMACY and was highly significant (LR=1596.2, df=14, p<0.0001) with a good amount of explanatory/predictive power (McFadden’s R2=0.397, Nagelkerke’s R2=0.534, C=0.899). The summary table of the model is shown here.

Estimate 95%-CI se z p2-tailed
(Intercept (LEN_PORmPUM_LOG=0, POR_ANIMACY=animate, SPEAKER=nns) 0.64 [0.47, 0.82] 0.09 7.21 <0.001
LEN_PORmPUM_LOG0→1 -0.67 [-0.81, -0.54] 0.07 -9.58 <0.001
POR_ANIMACYanimatecollective -1.76 [-2.08, -1.46] 0.16 -11.20 <0.001
POR_ANIMACYanimateinanimate -4.30 [-4.74, -3.90] 0.21 -20.04 <0.001
POR_ANIMACYanimatelocative -2.30 [-2.84, -1.81] 0.26 -8.79 <0.001
POR_ANIMACYanimatetemporal -1.32 [-1.77, -0.88] 0.23 -5.82 <0.001
SPEAKERnnsns -0.03 [-0.34, 0.29] 0.16 -0.16 0.8708
POR_ANIMACYanimatecollective + LEN_PORmPUM_LOG0→1 -0.50 [-0.76, -0.26] 0.13 -3.91 0.001
POR_ANIMACYanimateinanimate + LEN_PORmPUM_LOG0→1 0.21 [-0.10, 0.52] 0.16 1.30 0.1949
POR_ANIMACYanimatelocative + LEN_PORmPUM_LOG0→1 -0.34 [-0.80, 0.08] 0.22 -1.53 0.1249
POR_ANIMACYanimatetemporal + LEN_PORmPUM_LOG0→1 0.31 [-0.01, 0.62] 0.16 1.95 0.051
POR_ANIMACYanimatecollective:SPEAKERnnsns 0.74 [0.18, 1.30] 0.28 2.59 0.0095
POR_ANIMACYanimateinanimate:SPEAKERnnsns -0.29 [-1.33, 0.60] 0.48 -0.61 0.544
POR_ANIMACYanimatelocative:SPEAKERnnsns -0.53 [-1.43, 0.31] 0.44 -1.20 0.2283
POR_ANIMACYanimatetemporal:SPEAKERnnsns 0.09 [-0.71, 0.88] 0.40 0.22 0.8238

The results indicate that

  • the interaction LEN_PORmPUM_LOG:POR_ANIMACY has the effect that
    • the length difference effect is strongest for collective possessors, followed by locatives, then animates, then inanimates, then temporals, but all of them are significantly different from 0;
    • the only differences between slopes for different animacy levels that are significant (acc. to post-hoc tests adjusted for multiple testing with Holm’s procedure) are the following:
      • collective vs. animate;
      • collective vs. inanimate;
      • collective vs. temporal;
  • the interaction SPEAKER:POR_ANIMACY only has the effect that native speakers are significantly more likely to use s genitives with collectives than learners are – all other speaker differences within each animacy level are ns. [Show plots]

If we operationalize prototypes with extreme values of predictions, prototypival of-genitives have long possessors, short possessums and are mostly inanimate (with some collectives) whereas prototypical s-genitives have short possessors, long possessums and are mostly animate and collectives; also, while we didn’t include the predictor POR_DEF in the model, prototypical s-genitives seem to ‘dislike’ indefinite possessors.

Finally, the model did particularly badly with length difference values close to 0 or positive and/or inanimate possessors, but also, to a lesser extent, with non-native speakers.

sessionInfo()
R version 4.3.3 (2024-02-29)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Pop!_OS 22.04 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so;  LAPACK version 3.10.0

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C
 [9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

time zone: America/Los_Angeles
tzcode source: system (glibc)

attached base packages:
[1] stats     graphics  grDevices utils     datasets  compiler  methods
[8] base

other attached packages:
 [1] multcomp_1.4-25 TH.data_1.1-2   MASS_7.3-60.0.1 survival_3.5-8
 [5] mvtnorm_1.2-4   effects_4.2-2   car_3.1-2       carData_3.0-5
 [9] STGmisc_1.0     Rcpp_1.0.12     magrittr_2.0.3

loaded via a namespace (and not attached):
 [1] Matrix_1.6-5      jsonlite_1.8.8    survey_4.4-2      splines_4.3.3
 [5] boot_1.3-30       yaml_2.3.8        fastmap_1.1.1     lattice_0.22-6
 [9] knitr_1.45        htmlwidgets_1.6.4 nloptr_2.0.3      insight_0.19.10
[13] nnet_7.3-19       minqa_1.2.6       DBI_1.2.2         rlang_1.1.3
[17] xfun_0.43         estimability_1.5  cli_3.6.2         digest_0.6.35
[21] grid_4.3.3        rstudioapi_0.16.0 sandwich_3.1-0    lme4_1.1-35.1
[25] nlme_3.1-164      evaluate_0.23     codetools_0.2-19  zoo_1.8-12
[29] mitools_2.4       abind_1.4-5       colorspace_2.1-0  rmarkdown_2.26
[33] tools_4.3.3       htmltools_0.5.8