Hellenic Spatial Statistics Lab - A Spatial Statistics Primer

Σημειακή ανάλυση προτύπων (Point Pattern Analysis-PPA) για την Περιφερειακή Επιστήμη, #3 tutorial

Authors

Doukissas Leonidas

Pantazis Panagiotis

Psycharis Yannis

Politis Konstantinos

1. Γιατί «Σημειακή ανάλυση προτύπων» στην Περιφερειακή Επιστήμη;

Η Σημειακή ανάλυση προτύπων (Point Pattern Analysis, PPA) μελετά πώς μονάδες (π.χ. επιχειρήσεις, θέσεις εργασίας, πατέντες, κόμβοι logistics) κατανέμονται σε παράθυρο $$W^2$$ Τα χωρικά μοτίβα αποτυπώνουν μηχανισμούς όπως οικονομίες συγκέντρωσης (agglomeration), διαχύσεις γνώσης και χωρικούς περιορισμούς (γαιοπρόσοδος, μεταφορές).

Διακρίνουμε:

  • Ιδιότητες 1ης τάξης: ένταση (ρυθμός) στη θέση (s), δηλ. \[\lambda(s).\]

  • Ιδιότητες 2ης τάξης: αλληλεπίδραση σημείων (π.χ. Ripley (K/L)).

Υπό Πλήρη Χωρική Τυχαιότητα (CSR) (ομογενής Poisson): \[K(r)=\pi r^2,\qquad L(r)=\sqrt{\frac{K(r)}{\pi}}=r.\]

2. Πακέτα & παράθυρο μελέτης

Χρησιμοποιούμε τη σύγχρονη οικογένεια spatstat σε υπο-πακέτα. (Μπορούμε και τη βιβλιοθήκη library(spatstat) εάν προτιμάμε την ευρύτερη οικογένεια πακέτων).

# Προαιρετικά, εγκατάσταση:
# install.packages(c("spatstat.geom","spatstat.random","spatstat.explore","spatstat.model","RColorBrewer"))

library(spatstat.geom)     # ppp, owin, αποστάσεις
Loading required package: spatstat.data
spatstat.geom 3.2-1
library(spatstat.random)   # rpoint, rThomas, προσομοιώσεις
spatstat.random 3.1-5
library(spatstat.explore)  # K/L, envelope, density.ppp
Loading required package: nlme
spatstat.explore 3.2-1
library(spatstat.model)    # ppm, predict, effectfun
Loading required package: rpart
spatstat.model 3.2-4
library(RColorBrewer)

set.seed(123)

3. Γρήγορη οπτικοποίηση (finpines) & marks

data(finpines)

# Χωρικό μοτίβο χωρίς marks
plot(unmark(finpines), cols = '#756bb1', main = 'Finpines: spatial point pattern', border = 'red', pch=19)

# Με marks (αν υπάρχουν)
plot(finpines, cols = '#756bb1', main = 'Finpines με marks', border = 'red')

Γιατί μας απασχολούν όμως τα marks;

Επιτρέπουν την πολυτυπική ανάλυση (όπως για πάραδειγμα η τυπολογία επιχειρήσεων κ.λπ.).

4. Ιδιότητες 1ης τάξης: Ένταση Kernel \(\hat\lambda(s)\)

Ο εκτιμητής kernel δίνει τον «θερμικό χάρτη» δραστηριότητας.

Η επιλογή bandwidth \(\sigma\) ισορροπεί εξομαλύνει με λεπτομέρεια.

sigma <- 0.06
D_fp <- density(finpines, sigma = sigma, at = "pixels", edge = TRUE)
plot(D_fp, main = sprintf("Kernel intensity, σ = %.2f", sigma))
points(finpines, pch=20, cex=.5)

Σε επίπεδο πολιτικής, τα «θερμά σημεία» καθοδηγούν στοχευμένες παρεμβάσεις.

5. Ιδιότητες 2ης τάξης:

Ripley \(L(r)−r\) με φακέλους (envelopes)

Η \(L(r)\) είναι συσσωρευτική μέτρηση δεύτερης τάξης: συγκεντρώνει την πληροφορία “μέχρι” απόσταση \(r\). Μετρά πόσα ζεύγη σημείων βλέπουμε μέχρι την απόσταση \(r\) σε σχέση με αυτό που που θα περιμέναμε υπό την Πλήρη χωρική τυχαιότητα (Complete Spatial Randomness - CSR).

Υπό Πλήρη Χωρική Τυχαιότητα (CSR) αναμένουμε \(L(r)\approx r\), άρα η κεντρική γραμμή \(L(r)-r\) “κάθεται” στο μηδέν. Όταν η παρατηρούμενη καμπύλη βγαίνει πάνω από το ανώτερο όριο του envelope σε κάποιο εύρος \(r\), αυτό υποδεικνύει συσσώρευση (περισσότερα ζεύγη από το τυχαίο) σε εκείνες τις κλίμακες· όταν πέφτει κάτω, υποδεικνύει απώθηση/κανονικότητα.

Σημαντικό: οι ζώνες είναι τυχαίες (π.χ. 39–99 προσομοιώσεις) και μπορεί να ανοίγουν/στενεύουν ανά \(r\). Η διόρθωση ορίων (π.χ. translation) μειώνει μεροληψίες στα μικρά \(r\), όπου ο εκτιμητής είναι πιο ασταθής.

Η συνάρτηση \(L(r)=\sqrt{K(r)/\pi}\) ​ συνοψίζει συσσωρευτικά έως την ακτίνα r
Υπό CSR: \(L(r)-r\approx 0\).

Επιθυμούμε να διαγνώσουμε εάν υπάρχει συγκέντρωση (clustering) ή κανονικότητα (regularity) σε κάθε κλίμακα r συγκρίνοντας την καμπύλη \(L(r)−r\) . Yπό τυχαιότητα, ισχύει

\(L(r)-r\approx 0\) οπότε αποκλίσεις πάνω/κάτω από το μηδέν υποδεικνύουν συσσωμάτωση/απώθηση αντίστοιχα.

Στην Περιφερειακή Επιστήμη, θετικές αποκλίσεις του \(L(r)−r\) σε συγκεκριμένες κλίμακες $r$ υποδηλώνουν συσπείρωση οικονομικής δραστηριότητας (agglomeration) σε αυτές τις κλίμακες, άρα «σημαντικές» αποστάσεις για αγορές εργασίας, προμηθευτές/πελάτες, ή διαχύσεις γνώσης.

E_fp <- envelope(
  finpines, fun = Lest, nsim = 39,
  correction = "translation",  # πιο σταθερό σε μικρά r
  global = FALSE
)
Generating 39 simulations of CSR  ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,  39.

Done.
r   <- E_fp$r
obs <- E_fp$obs - r
lo  <- E_fp$lo  - r
hi  <- E_fp$hi  - r

# -- Κόβω πολύ μικρά r (skip τα πρώτα 4 bins) & κάνω ένα ήπιο zoom
rpos <- r[r > 0]
rmin <- if (length(rpos) >= 5) rpos[5] else min(rpos)        # αγνόησε τα 4 πρώτα
rmax <- quantile(r, 0.80)                                    # zoom στο 80% του εύρους
idx  <- r >= rmin & r <= rmax

# -- Plot
plot(NA, xlim = range(r[idx]),
     ylim = range(c(lo[idx], hi[idx], obs[idx])) * 1.05,
     xlab = "r", ylab = "L(r) - r",
     xaxs = "i", yaxs = "i",
     main = "Finpines: L(r) - r")

polygon(c(r[idx], rev(r[idx])),
        c(lo[idx], rev(hi[idx])),
        col = adjustcolor("grey70", 0.25), border = NA)

abline(h = 0, lty = 2, col = "grey35")
lines(r[idx], lo[idx], lty = 3)
lines(r[idx], hi[idx], lty = 3)
lines(r[idx], obs[idx], lwd = 2.8)  # η «μαύρη» καμπύλη, παχύτερη 
grid(col = adjustcolor("grey85", 0.6))

Ripley L(r) - r.

Μη ομογενής (Ιnhomogeneous) \(L(r)-r\) ελέγχουμε την εξάρτηση αφού ελέγξουμε την ένταση

Αν η ένταση πρώτης τάξης \(\lambda(s)\) δεν είναι περίπου σταθερή (π.χ. υπάρχουν “θερμά σημεία”), τότε το κλασικό \(L(r)\) μπορεί να ερμηνεύσει ετερογένεια ως “clustering”. Το \(L_{\text{inhom}}(r)\) χρησιμοποιεί μια εκτίμηση της \(\lambda(s)\) (συνήθως με kernel) για να “διορθώσει” αυτήν την επίδραση και να ελέγξει καθαρότερα τη χωρική αλληλεπίδραση.

Η γραμμή βάσης δεν είναι πια ομοιογενές CSR αλλά inhomogeneous Poisson με την ίδια \(\hat\lambda(s)\). Αν τα ευρήματα (π.χ. θετικές αποκλίσεις) παραμένουν και στο \(L_{\text{inhom}}(r)-r\), τότε το αποτύπωμα δεύτερης τάξης είναι robust και δεν οφείλεται μόνο στην 1ης τάξης ετερογένεια.

Αν η ένταση \(\lambda(s)\) δεν είναι περίπου σταθερή, ο συνηθισμένος L(r) μπορεί να «βλέπει» ψευδο–clustering. Ο \(L_{\text{inhom}}(r)\) αφαιρεί αυτήν την επίδραση χρησιμοποιώντας μια εκτίμηση της λ(s).

Παρακάτω εκτιμούμε \(\lambda(s)\) με kernel, φτιάχνουμε envelopes με inhomogeneous Poisson baseline και παρουσιάζουμε \(L_{\text{inhom}}(r)-r\).

# 1) Εκτίμηση λ(s) με data-driven bandwidth
sig_inhom <- bw.diggle(finpines)
lam_im    <- density(finpines, sigma = sig_inhom, at = "pixels", edge = TRUE)

# 2) Envelopes για Linhom με inhomogeneous Poisson προσομοιώσεις
E_inhom <- envelope(
  finpines, fun = Linhom, nsim = 39, global = FALSE,
  correction = "translation",
  simulate = expression(rpoispp(lam_im)),  # baseline: inhom Poisson με ίδια ένταση
  lambda = lam_im,                         # περνάμε την εκτίμηση στον Linhom
  savefuns = TRUE
)
Warning: Envelope may be invalid; argument 'lambda' appears to have been fixed.
Generating 39 simulations by evaluating expression  ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,  39.

Done.
# 3) Προετοιμασία για L_inhom(r) - r και καθαρό plot
r   <- E_inhom$r
obs <- E_inhom$obs - r
lo  <- E_inhom$lo  - r
hi  <- E_inhom$hi  - r

# Κόβουμε πολύ μικρά r & κάνουμε ένα ήπιο zoom
rpos <- r[r > 0]
rmin <- if (length(rpos) >= 5) rpos[5] else min(rpos)
rmax <- quantile(r, 0.80)
idx  <- r >= rmin & r <= rmax

plot(NA, xlim = range(r[idx]),
     ylim = range(c(lo[idx], hi[idx], obs[idx])) * 1.05,
     xlab = "r", ylab = "L_inhom(r) - r",
     xaxs = "i", yaxs = "i",
     main = "Finpines: Inhomogeneous L(r) - r")

polygon(c(r[idx], rev(r[idx])),
        c(lo[idx], rev(hi[idx])),
        col = adjustcolor("grey70", 0.25), border = NA)
abline(h = 0, lty = 2, col = "grey35")
lines(r[idx], lo[idx], lty = 3)
lines(r[idx], hi[idx], lty = 3)
lines(r[idx], obs[idx], lwd = 2.6)
grid(col = adjustcolor("grey85", 0.6))

Inhomogeneous L(r) - r με translation correction και inhomogeneous Poisson baseline.

Pair Correlation g(r): μη-συσσωρευτικός έλεγχος «ανά κλίμακα»

Η g(r) δείχνει άμεσα σε ποιες αποστάσεις υπάρχει περίσσεια/έλλειμμα ζευγών: g(r)>1 ⇒ περισσότεροι γείτονες απ’ ό,τι θα περιμέναμε υπό τυχαιότητα (clustering στη συγκεκριμένη κλίμακα), g(r)<1 ⇒ αποθάρρυνση. Παρακάτω σχεδιάζουμε g(r)−1 με envelopes για καθαρή ερμηνεία γύρω από το μηδέν.

Η \(g(r)\) είναι ουσιαστικά η “παράγωγος” του \(K\) και δείχνει άμεσα τη συμπεριφορά σε κάθε απόσταση: \(g(r)>1\) σημαίνει “περισσότερα ζεύγη από το τυχαίο” στην ίδια την απόσταση \(r\) (τοπικό clustering), ενώ $g(r)<1$ σημαίνει έλλειμμα (απώθηση). Σε αντίθεση με το \(L\), η \(g(r)\) δεν συσσωρεύει από το \(0\) μέχρι το \(r\), άρα είναι εύχρηστη για να εντοπίζεις “στενές” κλίμακες αλληλεπίδρασης.

Πρακτικά, για καθαρή απεικόνιση αφαιρούμε τη μονάδα και σχεδιάζουμε \(g(r)-1\) γύρω από το μηδέν, με μικρό zoom σε ρεαλιστικές αποστάσεις ώστε να μην κυριαρχεί ο θόρυβος των πολύ μικρών \(r\).

E_pcf <- envelope(
  finpines, fun = pcf, nsim = 39, global = FALSE,
  correction = "translation"
)
Generating 39 simulations of CSR  ...
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,  39.

Done.
r   <- E_pcf$r
obs <- E_pcf$obs - 1
lo  <- E_pcf$lo  - 1
hi  <- E_pcf$hi  - 1

# Ζουμ σε μια εύλογη περιοχή r (κόβουμε πολύ μικρά r)
rpos <- r[r > 0]
rmin <- if (length(rpos) >= 5) rpos[5] else min(rpos)
rmax <- quantile(r, 0.80)
idx  <- r >= rmin & r <= rmax

plot(NA, xlim = range(r[idx]),
     ylim = range(c(lo[idx], hi[idx], obs[idx])) * 1.05,
     xlab = "r", ylab = "g(r) - 1",
     xaxs = "i", yaxs = "i",
     main = "Finpines: Pair correlation (g(r) - 1)")

polygon(c(r[idx], rev(r[idx])),
        c(lo[idx], rev(hi[idx])),
        col = adjustcolor("grey70", 0.25), border = NA)
abline(h = 0, lty = 2, col = "grey35")
lines(r[idx], lo[idx], lty = 3)
lines(r[idx], hi[idx], lty = 3)
lines(r[idx], obs[idx], lwd = 2.4)
grid(col = adjustcolor("grey85", 0.6))

Pair correlation g(r) - 1 (translation correction) με envelopes.

Πολυτυπική ανάλυση (marks): παράδειγμα ants

Όταν υπάρχουν κατηγορίες/τύποι (marks), εξετάζουμε πυκνότητες και συναρτήσεις \(K\) ανά τύπο και μεταξύ τύπων.
Έτσι ανιχνεύουμε συν-χωροθέτηση ή διαχωρισμό μεταξύ «κλάδων»/υποπληθυσμών στον χώρο.

Στα πολυτυπικά πρότυπα, κάθε σημείο φέρει ένα mark (τύπο/κατηγορία). Αυτό μας επιτρέπει να μετρήσουμε τόσο την «ενδο-τύπου» συσχέτιση όσο και τη «μεταξύ-τύπων» συν-χωροθέτηση με συναρτήσεις όπως οι \(K_{ii}(r)\) (εντός τύπου \(i\)) και οι \(K_{ij}(r)\) (μεταξύ τύπων \(i,j\)), αλλά και με την pair-correlation \(g_{ij}(r)\). Αν π.χ. η \(K_{ij}(r)\) ή η \(g_{ij}(r)\) βρίσκεται πάνω από τις ζώνες αναφοράς για κάποιες αποστάσεις \(r\), αυτό υποδεικνύει ελκυσμό/συν-χωροθέτηση των δύο τύπων στις συγκεκριμένες κλίμακες - κάτω από τις ζώνες σημαίνει αποθάρρυνση/διαχωρισμό.

Στο πλαίσιο της Περιφερειακής Επιστήμης, τα marks μπορούν να παριστάνουν κλάδους, υποκλάδους, μέγεθος ή «στάδιο ζωής» επιχειρήσεων (π.χ. startup vs incumbent). Έτσι, η πολυτυπική ανάλυση δίνει απαντήσεις σε ερωτήματα πολιτικής: συν-εντοπίζονται συμπληρωματικοί κλάδοι; σε ποιες αποστάσεις; υπάρχει διαχωρισμός που δείχνει ανταγωνισμό για πόρους/γη; Σημαντικό πρακτικό σημείο: όταν υπάρχει έντονη ετερογένεια πρώτης τάξης, προτιμάμε τις inhomogeneous εκδοχές (\(K_{\text{inhom}}\), \(g_{\text{inhom}}\)) ώστε να μην «μπερδεύουμε» την ένταση με αλληλεπίδραση.

Μικρή περιγραφή του dataset ants

Το ants είναι ένα κλασικό πολυτυπικό σύνολο δεδομένων του spatstat με τις τοποθεσίες φωλιών δύο ειδών μυρμηγκιών μέσα σε ορθογώνιο παράθυρο παρατήρησης. Οι συντεταγμένες αποθηκεύονται ως αντικείμενο τύπου ppp και το mark είναι παράγοντας με δύο στάθμες/τύπους: Cataglyphis και Messor. Είναι ιδανικό για επίδειξη πολυτυπικών εργαλείων: υποσύνολα ανά είδος, εκτίμηση πυκνοτήτων kernel ανά τύπο, καμπύλες \(K_{ii}(r)\) (εντός είδους) και \(K_{ij}(r)\) (μεταξύ ειδών), καθώς και \(g_{ij}(r)\), ώστε να δούμε αν (και σε ποιες αποστάσεις) τα δύο είδη τείνουν να συν-χωροθετούνται ή να αποφεύγουν το ένα το άλλο.

data(ants)
summary(ants)
Marked planar point pattern:  97 points
Average intensity 0.0002261486 points per square unit (one unit = 0.5 feet)

Coordinates are integers
i.e. rounded to the nearest unit (one unit = 0.5 feet)

Multitype:
            frequency proportion    intensity
Cataglyphis        29  0.2989691 6.761144e-05
Messor             68  0.7010309 1.585372e-04

Window: polygonal boundary
single connected closed polygon with 11 vertices
enclosing rectangle: [-25, 803] x [-49, 717] units
                     (828 x 766 units)
Window area = 428922 square units
Unit of length: 0.5 feet
Fraction of frame area: 0.676
ants_dens <- density(ants)
plot(ants_dens, main ="Density of ant nests"); contour(ants_dens, add=TRUE); points(ants, pch=20)

n <- 100
plot(envelope(ants, fun=Kest, nsim=n, verbose=FALSE), main="Ants: Ripley K envelopes")

cataglyphis <- subset(ants, marks=="Cataglyphis", drop=TRUE)
messor      <- subset(ants, marks=="Messor",      drop=TRUE)

plot(density(cataglyphis), main = "Cataglyphis"); points(cataglyphis, pch=20)

plot(density(messor),      main = "Messor");      points(messor, pch=20)

plot(envelope(cataglyphis,fun=Kest,nsim=n,verbose=FALSE), main="K: Cataglyphis")

plot(envelope(messor,     fun=Kest,nsim=n,verbose=FALSE), main="K: Messor")

ants_all_k <- alltypes(ants, "K", envelope=TRUE, verbose=FALSE)
plot(ants_all_k, main="All-types K")

Αποστάσεις & δείκτες μικρής κλίμακας

Οι πίνακες \({d_{ij}}\) και οι αποστάσεις πλησιέστερου γείτονα περιγράφουν τις πολύ κοντινές αλληλεπιδράσεις.
Ο χάρτης empty-space δείχνει πόσο «άδειος» είναι ο χώρος γύρω από τυχαίες τοποθεσίες, ενώ ο Clark–Evans ελέγχει κανονικότητα/συσσώρευση σε μικρές κλίμακες.

pairdist(finpines)[1:3, 1:5]      # δείγμα πίνακα ζευγών αποστάσεων
         [,1]     [,2]     [,3]      [,4]     [,5]
[1,] 0.000000 1.103011 3.105151 2.5306411 2.310020
[2,] 1.103011 0.000000 4.200001 3.6034966 3.322207
[3,] 3.105151 4.200001 0.000000 0.6938005 1.232301
nndist(finpines)[1:5]             # δείγμα αποστάσεων πλησιέστερου γείτονα
[1] 1.1030110 0.4291570 0.6938005 0.5626493 0.1847252
Z <- distmap(finpines)
plot(Z, main="Empty-space distance map"); points(finpines, pch=20, cex=.5)

clarkevans.test(finpines, correction = "donnelly")

    Clark-Evans test
    Donnelly correction
    Monte Carlo test based on 999 simulations of CSR with fixed n

data:  finpines
R = 0.85639, p-value = 0.002
alternative hypothesis: two-sided
plot(Fest(finpines), main="Fest (empty-space CDF)")

Duranton–Overman (DO): KDE στις αποστάσεις \({d_{ij}}\)

Η DO-προσέγγιση εκτιμά πυκνότητα με kernel πάνω στην κατανομή των αποστάσεων και τη συγκρίνει με CSR, ώστε να εντοπίσει σε ποιες αποστάσεις υπάρχει υπέρ-συνύπαρξη.
Κορυφώσεις της παρατηρούμενης καμπύλης πάνω από τις ζώνες υποδεικνύουν λειτουργικές κλίμακες (π.χ. 2–3 km).

Η μέθοδος DO δεν κοιτά “μέχρι \(r\)”. Αντίθετα, εκτιμά πυκνότητα kernel πάνω στην κατανομή αποστάσεων ζευγών \({d_{ij}}\). Έτσι απαντά στο “σε ποιες αποστάσεις τείνουν να συν-χωροθετούνται οι μονάδες;”. Με σύγκριση σε κατάλληλο baseline (συνήθως CSR με το ίδιο πλήθος σημείων και το ίδιο παράθυρο \(W\)) και με envelopes, μια κορυφή πάνω από την ανώτερη ζώνη σημαίνει “υπέρ-συνύπαρξη” στην συγκεκριμένη απόσταση.

Στην Περιφερειακή Επιστήμη αυτό μεταφράζεται ως λειτουργική κλίμακα (π.χ. 2–3 km) συνεργασιών, προμηθειών ή διαχύσεων. Πολλαπλές κορυφές μπορεί να δείχνουν πολυκλιμακική οργάνωση (π.χ. γειτονιά + ενδοαστική).

dv <- as.vector(pairdist(finpines)); dv <- dv[dv>0]
bw_val <- bw.nrd0(dv)
dens_obs <- density(dv, bw = bw_val, from = 0)

nsim <- 99
Xn <- npoints(finpines)
x_grid <- dens_obs$x
Y <- matrix(NA_real_, nrow=length(x_grid), ncol=nsim)

for(s in 1:nsim){
  Xi <- rpoint(Xn, win = Window(finpines))
  di <- as.vector(pairdist(Xi)); di <- di[di>0]
  dens_i <- density(di, bw = bw_val, from=0, to=max(x_grid), n=length(x_grid))
  Y[,s] <- dens_i$y
}

lo <- apply(Y, 1, quantile, probs = 0.05, na.rm=TRUE)
hi <- apply(Y, 1, quantile, probs = 0.95, na.rm=TRUE)

plot(x_grid, dens_obs$y, type="l", xlab = "Απόσταση d", ylab = "Πυκνότητα",
     main="DO-style density of pairwise distances")
polygon(c(x_grid, rev(x_grid)), c(lo, rev(hi)), col=adjustcolor("grey75", .5), border=NA)
lines(x_grid, dens_obs$y, lwd=2)

Μοντελοποίηση έντασης με ppm (dataset bei)

Συνδέουμε τη λογαριθμική ένταση με covariates, π.χ. υψόμετρο και κλίση:

\[ \log \lambda(s) = \beta_0 + \beta_1 \,\text{elev}(s) + \beta_2 \,\text{grad}(s) + \cdots. \]

# Αν λείπει, εγκατάστησέ το: install.packages("spatstat.data")
library(spatstat.data)

# Φόρτωση datasets από το πακέτο δεδομένων
data(bei,       package = "spatstat.data")
data(bei.extra, package = "spatstat.data")
Warning in data(bei.extra, package = "spatstat.data"): data set 'bei.extra' not
found
# Γρήγορος έλεγχος
class(bei)              # "ppp"
[1] "ppp"
names(bei.extra)        # αναμένουμε: "elev" "grad"
[1] "elev" "grad"
plot(bei, main="bei: tropical rain forest trees")

plot(quadratcount(bei), main="Quadrat counts (bei)")

fit0 <- ppm(bei ~ 1)
fit1 <- ppm(bei ~ grad,                   data = bei.extra)
fit2 <- ppm(bei ~ elev + grad,            data = bei.extra)
fit3 <- ppm(bei ~ polynom(grad, elev, 2), data = bei.extra)

fit0; fit1; fit2; fit3
Stationary Poisson process
Fitted to point pattern dataset 'bei'
Intensity: 0.007208
             Estimate       S.E.   CI95.lo   CI95.hi Ztest      Zval
log(lambda) -4.932564 0.01665742 -4.965212 -4.899916   *** -296.1182
Nonstationary Poisson process
Fitted to point pattern dataset 'bei'

Log intensity:  ~grad

Fitted trend coefficients:
(Intercept)        grad 
  -5.391053    5.026710 

             Estimate       S.E.   CI95.lo   CI95.hi Ztest      Zval
(Intercept) -5.391053 0.03001787 -5.449887 -5.332219   *** -179.5948
grad         5.026710 0.24534296  4.545847  5.507573   ***   20.4885
Nonstationary Poisson process
Fitted to point pattern dataset 'bei'

Log intensity:  ~elev + grad

Fitted trend coefficients:
(Intercept)        elev        grad 
-8.56355220  0.02143995  5.84646680 

               Estimate        S.E.     CI95.lo     CI95.hi Ztest       Zval
(Intercept) -8.56355220 0.341113849 -9.23212306 -7.89498134   *** -25.104675
elev         0.02143995 0.002287866  0.01695581  0.02592408   ***   9.371155
grad         5.84646680 0.255781018  5.34514522  6.34778838   ***  22.857313
Nonstationary Poisson process
Fitted to point pattern dataset 'bei'

Log intensity:  ~grad + elev + I(grad^2) + I(grad * elev) + I(elev^2)

Fitted trend coefficients:
   (Intercept)           grad           elev      I(grad^2) I(grad * elev) 
 -1.550702e+02   5.106076e+01   2.025721e+00  -6.388416e+01  -2.054512e-01 
     I(elev^2) 
 -6.871527e-03 

                    Estimate         S.E.       CI95.lo       CI95.hi Ztest
(Intercept)    -1.550702e+02 8.4491373742 -1.716302e+02 -1.385102e+02   ***
grad            5.106076e+01 8.1476798550  3.509160e+01  6.702992e+01   ***
elev            2.025721e+00 0.1141637062  1.801964e+00  2.249477e+00   ***
I(grad^2)      -6.388416e+01 4.4682504606 -7.264177e+01 -5.512655e+01   ***
I(grad * elev) -2.054512e-01 0.0545076013 -3.122842e-01 -9.861830e-02   ***
I(elev^2)      -6.871527e-03 0.0003859161 -7.627908e-03 -6.115145e-03   ***
                     Zval
(Intercept)    -18.353381
grad             6.266908
elev            17.743998
I(grad^2)      -14.297354
I(grad * elev)  -3.769222
I(elev^2)      -17.805753

Τι «είναι» τα fit0–fit3

  • fit0 <- ppm(bei ~ 1)
    Ομοιογενές Poisson (CSR baseline): \(\lambda(s)=\exp(\beta_0)\)
    Υποθέτει σταθερή ένταση παντού. Χρήσιμο ως σημείο αναφοράς.

  • fit1 <- ppm(bei ~ grad, data=bei.extra)
    Ετερογενές Poisson με κλίση:
    \(\lambda(s)=\exp\{\beta_0+\beta_1\,\text{grad}(s)\}\)

  • Αν \(\beta_1>0\), υψηλότερη κλίση ⇒ υψηλότερη ένταση (πολλαπλασιαστικά).

  • fit2 <- ppm(bei ~ elev + grad, data=bei.extra)
    Προσθέτει υψόμετρο:
    \(\lambda(s)=\exp\{\beta_0+\beta_1\,\text{elev}(s)+\beta_2\,\text{grad}(s)\}\)

  • Τα σημεία (δέντρα) αναμένεται να είναι πυκνότερα εκεί όπου οι μεταβλητές με θετικούς συντελεστές παίρνουν μεγάλες τιμές.

  • fit3 <- ppm(bei ~ polynom(grad, elev, 2), data=bei.extra)
    Πολυώνυμο 2ου βαθμού (μη-γραμμικότητες + cross-term):

  • περιλαμβάνει \(\text{elev}^2,, \text{grad}^2\) και όρο αλληλεπίδρασης elev×grad.
    Κατάλληλο αν υποπτεύεσαι καμπύλες σχέσεις (π.χ. μέγιστη ένταση σε μέτρια υψόμετρα).

  • Όλα τα παραπάνω είναι Poisson point process μοντέλα και εκτιμώνται με maximum pseudo-likelihood στο spatstat. Οι συντελεστές αφορούν τη λογαριθμική ένταση:
    \(\log \lambda(s)=\text{(γραμμικός συνδυασμός των covariates)}\).

Τι ελέγχουμε στο summary(fit*)

  • Συντελεστές (Estimate) + SE, z και p-values:
    Σημάδι (+/−+/-+/−) ⇒ κατεύθυνση επίδρασης. Τιμή ⇒ ένταση επίδρασης (με προσοχή στη κλίμακα των covariates).

  • AIC: όσο μικρότερο, τόσο καλύτερη προσαρμογή με ποινή πολυπλοκότητας.

  • Σύγκλιση/προειδοποιήσεις: αν υπάρχει πρόβλημα, δοκίμασε rescaling ή απλούστερο μοντέλο.

  • Units: η \(\lambda(s)\) μετριέται “ανά μονάδα επιφάνειας” (δες unitname(bei)).

Ερμηνεία αποτελεσμάτων:

  • Αν fit2 έχει πολύ χαμηλότερο AIC από fit0/fit1, τότε το υψόμετρο και/ή η κλίση εξηγούν σημαντικό κομμάτι της χωρικής μεταβολής της έντασης.

  • Αν fit3 μειώσει περαιτέρω το AIC και οι τετραγωνικοί/διαδραστικοί όροι είναι σημαντικοί, τότε η σχέση είναι μη-γραμμική ή εξαρτάται από συνδυασμούς των μεταβλητών.

  • Αν κάποιος συντελεστής είναι μη-σημαντικός ή με «παράδοξο» πρόσημο, σκέψου rescaling/standardization (scale()) ή πιθανή συγγραμμικότητα.

9 Πολλαπλασιαστές επίδρασης \(\exp(\beta,\Delta x)\) και προβλέψεις

Για συντελεστή \(\beta\) και μεταβολή \(\Delta x\), η ένταση πολλαπλασιάζεται κατά \(\exp(\beta,\Delta x)\).
Παράγουμε επίσης χάρτες \(\hat\lambda(s)\), αβεβαιότητας και αναμενόμενους αριθμούς σε υπο-περιοχή \(B\).

coefs <- coef(fit2)
grad <- bei.extra$grad; elev <- bei.extra$elev
imp.grad <- exp(coefs["grad"] * max(grad, na.rm=TRUE))
dif.elev <- (max(elev, na.rm=TRUE) - min(elev, na.rm=TRUE))
imp.elev <- exp(coefs["elev"] * dif.elev)
c(impact_grad=imp.grad, impact_elev=imp.elev)
impact_grad.grad impact_elev.elev 
        6.823879         2.340870 
lamhat <- predict(fit3)
plot(lamhat, main="Predicted intensity (fit3)"); points(bei, pch=20, cex=.2)

se_img <- predict(fit3, se=TRUE)$se
plot(se_img, main="SE of predicted log-intensity")

B <- levelset(bei.extra$elev, 130)
predict(fit3, type="count", window=B)
[1] 37.16835
predict(fit3, B, type="count", se=TRUE)
$estimate
[1] 37.16835

$se
[1] 3.613492
predict(fit0, B, type="count", interval="prediction")
 2.5% 97.5% 
  170   226 

Multipliers (επίδραση μεταβολής covariate)

Σε λογαριθμική κλίμακα, μια μεταβολή \(\Delta x\) δίνει πολλαπλασιαστή:
\(\exp(\beta\,\Delta x)\)

  • Αν \(\beta>0\) και \(\Delta x>0\), η ένταση πολλαπλασιάζεται (π.χ. ×1.4 ⇒ +40%).

  • Τα παραδείγματα στον κώδικα συγκρίνουν άκρο–σε–άκρο (από ελάχιστη σε μέγιστη τιμή), που συχνά είναι υπερ-αισιόδοξο. Για πιο ρεαλιστική ανάγνωση, χρησιμοποίησε διατεταρτημοριακό εύρος (IQR) ή 1 SD:

Πώς το ερμηνεύουμε: «Αύξηση της κλίσης κατά 1 SD συνδέεται με ×X στην αναμενόμενη ένταση δέντρων, κρατώντας τα άλλα σταθερά».

Χάρτες προβλεπόμενης έντασης & αβεβαιότητας

  • predict(fit3) επιστρέφει im με \(\lambda(s)\): «πόσα σημεία αναμένουμε ανά μονάδα επιφάνειας».

  • predict(..., se=TRUE)$se επιστρέφει SE του \(\log \hat\lambda(s)\). Μεγάλα SE → αβεβαιότητα (π.χ. άκρες παραθύρου, λίγες παρατηρήσεις, extrapolation).

  • Πώς ερμηνεύουμε τον χάρτη: «Θερμά» χρώματα ⇒ υψηλή αναμενόμενη πυκνότητα σημείων. Αν τα hotspots συμπίπτουν με συγκεκριμένες τιμές covariates (π.χ. μέσες κλίσεις), έχουμε μηχανισμό για πολιτική ερμηνεία.

Αναμενόμενος αριθμός σε υπο-περιοχή & διαστήματα

  • type="count" δίνει E[N(B)] για περιοχή B (π.χ. {elev≤130} }).

  • interval="confidence": αβεβαιότητα στη μέση τιμή.

  • interval="prediction": περιλαμβάνει και τη στοχαστική διακύμανση (Poisson) των μετρήσεων.

Ερμηνεία αποτελεσμάτων:

  • Αν E[N(B)] από το fit3 >> E[N(B)] από fit0, τότε οι covariates εξηγούν πολύ υψηλότερη (ή χαμηλότερη) αναμενόμενη πυκνότητα μέσα στο BBB.

  • Αν το prediction interval είναι πλατύ, υποδηλώνει υπολογίσιμη τυχαιότητα στις μετρήσεις (ακόμη και με σωστά covariates).

  • «Κανόνες ανάγνωσης»

  • Σήμα vs Μέγεθος: Μη στέκεσαι μόνο στο p-value. Δες πόσο μεγάλος είναι ο multiplier για ρεαλιστική μεταβολή covariate (IQR/SD).

  • Κλίμακα/μονάδες covariates: Αν οι συντελεστές φαίνονται ακραίοι, κάνε scale τις covariates (scale()) για καλύτερη ερμηνεία.

  • AIC & ANOVA: Διάλεξε το πιο απλό μοντέλο που εξηγεί επαρκώς τα δεδομένα (Occam).

  • Χάρτες έντασης: Οι πολιτικές/χωρικές αποφάσεις πατάνε σε μοτίβα \(\hat\lambda\) που επαναλαμβάνονται (όχι σε θόρυβο των άκρων).

  • Cross-check: Αν έχεις αμφιβολία για 1ης τάξης ετερογένεια, χρησιμοποίησε και \(L_{\text{inhom}}(r)\) (που ήδη φτιάξαμε) για να επιβεβαιώσουμε ότι το “clustering” δεν είναι “δημιούργημα” της έντασης.

Ενδεικτική βιβλιογραφία

  • Baddeley, A., Rubak, E., & Turner, R. (2015). Spatial Point Patterns: Methodology and Applications with R. Chapman & Hall/CRC.
  • Baddeley, A., & Turner, R. (2005). spatstat: An R Package for Analyzing Spatial Point Patterns. Journal of Statistical Software, 12(6), 1–42.
  • Clark, P. J., & Evans, F. C. (1954). Distance to nearest neighbor as a measure of spatial relationships. Ecology, 35(4), 445–453.
  • Combes, P.-P., Duranton, G., & Gobillon, L. (2015). The Empirics of Agglomeration Economies. In Handbook of Regional and Urban Economics (Vol. 5). Elsevier.
  • Diggle, P. J. (2014). Statistical Analysis of Spatial and Spatio-Temporal Point Patterns (3rd ed.). CRC Press.
  • Dixon, P. M. (2002). Ripley’s K function. In A. El-Shaarawi & W. W. Piegorsch (Eds.), Encyclopedia of Environmetrics. Wiley.
  • Duranton, G., & Overman, H. G. (2005). Testing for Localization Using Micro-Geographic Data. The Review of Economic Studies, 72(4), 1077–1106.
  • Illian, J., Penttinen, A., Stoyan, H., & Stoyan, D. (2008). Statistical Analysis and Modelling of Spatial Point Patterns. Wiley.
  • Møller, J. (2018). Introduction to Spatial Point Processes and Simulation-Based Inference (lecture notes).
  • Møller, J., & Waagepetersen, R. P. (2004). Statistical Inference and Simulation for Spatial Point Processes. Chapman & Hall/CRC.
  • Ripley, B. D. (1976). The second-order analysis of stationary point processes. Journal of Applied Probability, 13(2), 255–266.
  • Ripley, B. D. (1977). Modelling spatial patterns. Journal of the Royal Statistical Society: Series B, 39(2), 172–212.

Άδεια / Αναδημοσίευση

© 2025 Doukissas Leonidas, Pantazis Panagiotis, Psycharis Yannis, Politis Konstantinos.

Κείμενο: Διατίθεται με άδεια Creative Commons CC BY 4.0.
Μπορείτε να αναδιανείμετε και να προσαρμόσετε, με αναφορά στους δημιουργούς.
Άδεια: https://creativecommons.org/licenses/by/4.0/

Κώδικας R: MIT License (ελεύθερη χρήση, τροποποίηση, αναδιανομή με αναφορά).
Άδεια: https://opensource.org/licenses/MIT

Δεδομένα/Εικόνες τρίτων: Παραμένουν στις αρχικές τους άδειες.
Για χρήσεις πέραν των παραπάνω, επικοινωνήστε: .

Προτεινόμενη αναφορά:
Doukissas, L., Pantazis, P., Psycharis, Y., & Politis, K. (2025). Hellenic Spatial Statistics Lab – HSSL. RPubs. Διαθέσιμο στο: https://rpubs.com/LeonidasD/1338607