MDS Übung

Author

Armin Eichinger

Aufgabe 1

# Einbinden der Bibliothek, in der isoMDS ist
library(MASS)

# Einlesen der Daten
bav_cit_data <- read.csv("https://bookdown.org/Armin_E/mds_ex_1/data/bav_cit.csv",   row.names = 1, sep=",", dec = ".")

# Ausgabe der Daten
bav_cit_data
              Aschaffenburg Augsburg Bamberg Bayreuth Erlangen Fürth Hof
Aschaffenburg             0      322     174      239      175   179 273
Augsburg                324        0     236      238      195   150 290
Bamberg                 174      235       0       72       43    56 106
Bayreuth                241      237      72        0       96   102  56
Erlangen                176      195      43       98        0    16 142
Fürth                   181      150      56      102       15     0 155
Hof                     275      289     106       56      143   156   0
Ingolstadt              281       84     156      159      115   100 211
Kempten                 348      104     340      342      299   277 394
Landshut                355      126     230      232      189   186 250
München                 356       72     231      233      190   175 285
NeuUlm                  273       80     264      266      223   201 318
Nürnberg                189      144      64       84       18    11 136
Passau                  402      245     277      279      236   232 297
Regensburg              287      149     162      164      121   117 178
Rosenheim               426      152     301      304      260   245 356
Schweinfurt             137      279      55      119       99   111 154
Würzburg                 82      252      97      161      105   110 196
              Ingolstadt Kempten Landshut München NeuUlm Nürnberg Passau
Aschaffenburg        280     347      354     355    270      184    400
Augsburg              85     105      124      70     82      143    243
Bamberg              156     340      230     232    264       61    277
Bayreuth             158     342      232     234    266       84    279
Erlangen             116     300      190     192    224       18    237
Fürth                 99     277      201     175    201       12    232
Hof                  211     395      250     286    318      136    297
Ingolstadt             0     198      106      81    155       93    197
Kempten              199       0      191     127     88      270    310
Landshut             107     192        0      76    197      177    120
München               80     127       72       0    143      168    192
NeuUlm               156      88      195     141      0      194    314
Nürnberg              94     271      176     169    195        0    222
Passau               199     311      121     194    316      223      0
Regensburg            84     245       81     128    220      109    121
Rosenheim            151     193      143      69    223      238    169
Schweinfurt          212     304      282     283    228      116    328
Würzburg             210     277      284     286    201      115    331
              Regensburg Rosenheim Schweinfurt Würzburg
Aschaffenburg        286       426         137       81
Augsburg             149       152         279      247
Bamberg              163       302          55       96
Bayreuth             165       304         119      161
Erlangen             123       262          99       99
Fürth                118       245         107      105
Hof                  176       357         153      195
Ingolstadt            83       151         207      205
Kempten              245       193         303      272
Landshut              80       146         281      279
München              125        70         282      279
NeuUlm               220       223         228      196
Nürnberg             109       240         115      113
Passau               120       170         328      325
Regensburg             0       198         213      210
Rosenheim            196         0         352      350
Schweinfurt          214       354           0       46
Würzburg             217       356          47        0
# Umwandeln in den Datentyp Matrix und speichern der Matrix in derselben Variablen
bav_cit_data <- as.matrix(bav_cit_data)

# Symmetrisieren einer unsymmetrischen Matrix
bav_cit_data <- (bav_cit_data + t(bav_cit_data)) / 2

# Die eigentliche MDS für 2 Dimensionen
mds_result <- isoMDS(bav_cit_data,  k=2, trace = FALSE)


##### unwichtig: nur Aufhübschen ###########
# Ermittlung der Ausdehnung der Punkte für k=2
xrange <- range(mds_result$points[, 1])
yrange <- range(mds_result$points[, 2])

# Erweiterung der Ränder, damit Labels nicht abgeschnitten werden
xlim <- xrange + c(-1, 1) * diff(xrange) * 0.2
ylim <- yrange + c(-1, 1) * diff(yrange) * 0.2
########################################


# Ergebnisse plotten für k=2
plot(mds_result$points, type = "p", main = "Bayerische Städte (k=2)", xlab = "Dimension 1", ylab = "Dimension 2", xlim = xlim, ylim = ylim)

# Beschriftung der Datenpunkte
text(mds_result$points, labels = rownames(bav_cit_data), cex = 0.8, pos = 1)

# STRESS-Wert ausgeben (in %)
mds_result$stress
[1] 4.727519

Aufgabe 2: Property Fitting 1


Call:
lm(formula = Längengrade ~ MDS1 + MDS2, data = data)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.14955 -0.04283  0.01695  0.05098  0.09694 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) 11.1553056  0.0169408  658.49  < 2e-16 ***
MDS1        -0.0040168  0.0001443  -27.84  2.5e-14 ***
MDS2        -0.0104501  0.0002077  -50.30  < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.07187 on 15 degrees of freedom
Multiple R-squared:  0.9956,    Adjusted R-squared:  0.995 
F-statistic:  1699 on 2 and 15 DF,  p-value: < 2.2e-16

Aufgabe 3: Property Fitting 2

latitudes <- c(
  49.9783,  # Aschaffenburg
  48.3705,  # Augsburg
  49.8988,  # Bamberg
  49.9427,  # Bayreuth
  49.5986,  # Erlangen
  49.4772,  # Fürth
  50.3139,  # Hof
  48.7665,  # Ingolstadt
  47.7269,  # Kempten
  48.5296,  # Landshut
  48.1351,  # München
  48.3923,  # Neu-Ulm
  49.4521,  # Nürnberg
  48.5667,  # Passau
  49.0134,  # Regensburg
  47.8563,  # Rosenheim
  50.0483,  # Schweinfurt
  49.7913   # Würzburg
)

# Erstellen eines Dataframes mit den MDS-Koordinaten und Breitengraden
data <- data.frame(MDS1 = mds_result$points[, 1], MDS2 = mds_result$points[, 2], Breitengrade = latitudes)

# Durchführung der linearen Regression
regression_model <- lm(Breitengrade ~ MDS1 + MDS2, data=data)

# Zusammenfassung des Regressionsmodells anzeigen
summary(regression_model)

Call:
lm(formula = Breitengrade ~ MDS1 + MDS2, data = data)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.14042 -0.04224  0.02269  0.04738  0.08903 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) 49.1032500  0.0168650 2911.55  < 2e-16 ***
MDS1         0.0066595  0.0001436   46.37  < 2e-16 ***
MDS2        -0.0023975  0.0002068  -11.59 6.92e-09 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.07155 on 15 degrees of freedom
Multiple R-squared:  0.9934,    Adjusted R-squared:  0.9925 
F-statistic:  1126 on 2 and 15 DF,  p-value: < 2.2e-16
# Speichern der Steigung und des Intercepts
b0 <- 0
b1 <- coef(regression_model)[3] / coef(regression_model)[2] # evtl. 2 und 3 vertauschen; ich glaube aber es stimmt so

# Plot der MDS-Koordinaten
plot(mds_result$points, main = "MDS-Lösung mit Regressionsgerade", xlab = "Dimension 1", ylab = "Dimension 2", xlim = xlim, ylim = ylim, asp=1)
text(mds_result$points, labels = rownames(data), pos = 3)

# Hinzufügen der Regressionsgerade
abline(a = b0, b = b1, col = "red", lwd = 2)

steigung <- b1

for (i in 1:nrow(data)) {
  # Koordinaten des Datenpunkts
  x0 <- data$MDS1[i]
  y0 <- data$MDS2[i]
  
  # Berechnung des Lotfußpunkts (x1, y1) auf die Linie y = steigung * x
  x1 <- (x0 + steigung * y0) / (1 + steigung^2)
  y1 <- steigung * x1
  
  # Zeichnen des Lots
  segments(x0, y0, x1, y1, col = "lightgrey", lwd = 2)
  
  # Zeichnen des Lotfußpunkts
  points(x1, y1, col = "lightgrey", pch = 19)
}

Aufgabe 4: Soziale Medien

Ausgangspunkt ist die Summen-Matrix in der Datei auf iLearn (Bereich Q2:Z11).

Kopieren Sie diesen Bereich und fügen Sie ihn in eine Excel-Datei ein.

Speichern Sie die Excel-Datei als csv-Datei.

Meine CSV-Datei sieht so aus:

;Twitter;Instagram;Reddit;LinkedIn;TikTok;SnapChat;YouTube;WhatsApp;Facebook
Twitter;;;;;;;;;
Instagram;0;;;;;;;;
Reddit;6;0;;;;;;;
LinkedIn;1;0;2;;;;;;
TikTok;0;4;0;0;;;;;
SnapChat;0;2;0;0;0;;;;
YouTube;0;2;0;0;7;0;;;
WhatsApp;0;0;0;0;0;5;0;;
Facebook;4;3;1;0;1;0;1;0;
# Einlesen der Daten über die URL (Sie lesen damit also meine Daten ein)
#soz_med_data <- read.csv("https://bookdown.org/Armin_E/mds_ex_1/data/sozmed_dist.csv",   row.names = 1, sep=";", dec = ".")
soz_med_data <- read.csv("./data/sozmed_dist.csv",   row.names = 1, sep=";", dec = ".")

# Ausgabe der Daten
soz_med_data
          Twitter Instagram Reddit LinkedIn TikTok SnapChat YouTube WhatsApp
Twitter         8        NA     NA       NA     NA       NA      NA       NA
Instagram       0         8     NA       NA     NA       NA      NA       NA
Reddit          6         0      8       NA     NA       NA      NA       NA
LinkedIn        1         0      2        8     NA       NA      NA       NA
TikTok          0         4      0        0      8       NA      NA       NA
SnapChat        0         2      0        0      0        8      NA       NA
YouTube         0         2      0        0      7        0       8       NA
WhatsApp        0         0      0        0      0        5       0        8
Facebook        4         3      1        0      1        0       1        0
          Facebook
Twitter         NA
Instagram       NA
Reddit          NA
LinkedIn        NA
TikTok          NA
SnapChat        NA
YouTube         NA
WhatsApp        NA
Facebook         8
# Umwandeln in den Datentyp Matrix und speichern der Matrix in derselben Variablen
soz_med_data <- as.matrix(soz_med_data)

# Symmetrisieren: Vorgehen wir in der Vorlesung
# Bei den bayerischen Städten hatten wir schon eine vollständige Matrix,
# die aber unsymmetrisch war; hier haben wir nur die untere Hälfte der Matrix, 
# die wir nach oben kopieren müssen

soz_med_data[upper.tri(soz_med_data)] <- t(soz_med_data)[upper.tri(soz_med_data)]

# Ausgabe zur Überprüfung
soz_med_data
          Twitter Instagram Reddit LinkedIn TikTok SnapChat YouTube WhatsApp
Twitter         8         0      6        1      0        0       0        0
Instagram       0         8      0        0      4        2       2        0
Reddit          6         0      8        2      0        0       0        0
LinkedIn        1         0      2        8      0        0       0        0
TikTok          0         4      0        0      8        0       7        0
SnapChat        0         2      0        0      0        8       0        5
YouTube         0         2      0        0      7        0       8        0
WhatsApp        0         0      0        0      0        5       0        8
Facebook        4         3      1        0      1        0       1        0
          Facebook
Twitter          4
Instagram        3
Reddit           1
LinkedIn         0
TikTok           1
SnapChat         0
YouTube          1
WhatsApp         0
Facebook         8
# Wir haben Ähnlichkeiten und brauchen Distanzen, daher...:
# Maximale Ähnlichkeit bestimmen
max_value <- max(soz_med_data)
# Dieser Schritt erzeugt die Distanzen
soz_med_data <- max_value - soz_med_data

# Ab jetzt: Distanzen
soz_med_data
          Twitter Instagram Reddit LinkedIn TikTok SnapChat YouTube WhatsApp
Twitter         0         8      2        7      8        8       8        8
Instagram       8         0      8        8      4        6       6        8
Reddit          2         8      0        6      8        8       8        8
LinkedIn        7         8      6        0      8        8       8        8
TikTok          8         4      8        8      0        8       1        8
SnapChat        8         6      8        8      8        0       8        3
YouTube         8         6      8        8      1        8       0        8
WhatsApp        8         8      8        8      8        3       8        0
Facebook        4         5      7        8      7        8       7        8
          Facebook
Twitter          4
Instagram        5
Reddit           7
LinkedIn         8
TikTok           7
SnapChat         8
YouTube          7
WhatsApp         8
Facebook         0
# Die eigentliche MDS für 2 Dimensionen
mds_result <- isoMDS(soz_med_data,  k=2, trace = FALSE)


##### unwichtig: nur Aufhübschen ###########
# Ermittlung der Ausdehnung der Punkte für k=2
xrange <- range(mds_result$points[, 1])
yrange <- range(mds_result$points[, 2])

# Erweiterung der Ränder, damit Labels nicht abgeschnitten werden
xlim <- xrange + c(-1, 1) * diff(xrange) * 0.2
ylim <- yrange + c(-1, 1) * diff(yrange) * 0.2
########################################


# Ergebnisse plotten für k=2
plot(mds_result$points, type = "p", main = "Soziale Medien (k=2)", xlab = "Dimension 1", ylab = "Dimension 2", xlim = xlim, ylim = ylim)

# Beschriftung der Datenpunkte
text(mds_result$points, labels = rownames(soz_med_data), cex = 0.8, pos = 1)

# STRESS-Wert ausgeben (in %)
mds_result$stress
[1] 8.08271