Node- und Edgelists erstellen#

import pandas as pd
import itertools
import re
# Pfad für Daten definieren
dataPath = "./corpus"
outputPath = "./network_data"
# Aufbereiteten Korpus einlesen
corpus = pd.read_csv(f'{dataPath}/corpus_all_with_year-author-references.csv', delimiter=',', low_memory=False)
# Autor:innennamen von str in list umwandeln
for i, row in corpus.iterrows(): 
    neu = str(corpus.authors[i]).replace(',', '').split(';')
    corpus.at[i,'authors'] = neu
    names = corpus.authors[i]
    for z in range(len(names)): # Leerzeichen vor & hinter den Namen entfernen
        names[z] = names[z].strip()
corpus = corpus.rename(columns={'authors': 'authorlist'}) # Spalte umbenennen
# DataFrame vorbereiten (1. Zeile: corpus oder testCorpus verwenden)
corpus_citations = corpus[['id', 'authorlist', 'title', 'references', 'publ_year', 'wos_cat', 'abstract']].copy() # Spalten kopieren
corpus_citations.insert(3,'ref_id','')
corpus_citations.insert(1, 'paper_id','')
corpus_citations.insert(6, 'year','')
corpus_citations['abstract'] = corpus_citations['abstract'].fillna('')
# Jahr in ganze Zahlen umwandeln in Spalte 'year'
for i, row in corpus_citations.iterrows():
    alt = corpus_citations.publ_year[i]
    neu = int(alt)
    corpus_citations.at[i,'year'] = neu
# Kommata in Kategorien entfernen
for i, row in corpus_citations.iterrows():
    alt = str(corpus_citations.wos_cat[i])
    neu = alt.replace(',', '')
    corpus_citations.at[i,'wos_cat'] = neu
# Korpusausschnitt als csv-Datei zwischenspeichern
corpus_citations.to_csv(f'corpus/corpus_citations_df.csv', encoding='utf-8', index=False)

IDs für Paper und Referenzen erzeugen#

Um die Publikationen im Korpus mit den Referenzen abgleichen zu können und so Zitationsverbindungen zu entdecken, müssen diese in ein einheitliches Format gebracht werden. Unsere Lösungsidee besteht darin, eine paper_id und eine ref_id zu erstellen, die dann verglichen werden können. Diese IDs erstellen wir im folgenden Format: ‘Nachname der:des ersten Autor:in’ ++ ‘Leerzeichen’ ++ ‘Initial/e des Vornamens’ ++ ‘Leerzeichen’ ++ ‘Jahr’. Für eine weitere Vereinheitlichung wandeln wir alle Buchstaben in Kleinbuchstaben um.

Dieser Lösungsansatz birgt allerdings auch Risiken. Da unterschiedliche Autor:innen mit dem selben Namen vermischt und als eine Person interpretiert werden, bringt er eine gewisse Unschärfe mit sich. Durch das Hinzufügen des Publikationsdatums kann das Risiko einer solchen Fehlinterpretation zwar reduziert, aber nicht ganz verhindert werden.

# paper_id erstellen
for i, row in corpus_citations.iterrows():
    firstauthor = corpus_citations.authorlist[i][0]
    paperID = str(firstauthor + ' ' + str(corpus_citations.year[i]))
    corpus_citations.at[i,'paper_id'] = paperID.casefold()

Die ref_id ist aufgrund der uneinheitlichen Schreibweise, in der die Referenzen im WoS-Datensatz angegeben sind, ebenfalls fehleranfällig. Namen finden sich hier in sehr unterschiedlichen Schreibweisen. Es ist eine starke Einschränkung unserer Vorgehensweise, dass nur Beziehungen zu referenzierten Papern erkannt werden können, deren Autor:in in der Schreibweise ‘Nachname’ ++ ‘Leerzeichen’ ++ ‘Initial/en’ angegeben ist.

# Referenzen im Format '[Nachname] + ' ' + [Anfangsbuchstabe Initialen] + ' ' + [Jahr]' aufbereiten
for i, row in corpus_citations.iterrows():
    alt = str(corpus_citations.references[i])
    reflist = re.split(r"\s*[;]\s*", alt.strip())
    reflistNEU = []
    for k in range(len(reflist)):
        referenzALT = reflist[k]
        referenz = re.split(r"\s*[,]\s*", referenzALT.strip())
        if len(referenz) > 1:
            if referenz[1].isdigit() == True:
                reflistNEU += [str(referenz[0]).replace('.','').casefold() + ' ' + referenz[1]]
    corpus_citations.at[i,'ref_id'] = reflistNEU
    reflistNEU = []
# dict für die Paper im Korpus erstellen, paper_ids als keys
citation_dict = {}
for i, row in corpus_citations.iterrows():
    paper = corpus_citations.paper_id[i]
    citation_dict[paper] = ''
# corpus_citations.head(5) # Dataframe anzeigen

Edge- und Nodelist erstellen#

Um das Netzwerk später visualisieren zu können, brauchen wir eine Liste aller Kanten und eine Liste aller Knoten im Netzwerk. Im Gegensatz zum Ko-Autorenschaftsnetzwerk erstellen wir diesmal neben der Edgelist auch eine Nodelist, die alle Knoten im Netzwerk sowie zugehörige Attribute enthält, die wir bei der Visualisierung berücksichtigen möchten.

# Edgelist schreiben: Gerichtete Beziehung, paper ---zitiert---> paper
relation_count = 0
elem_count = 0
with open (f'{outputPath}/citation_network_EDGELIST.csv', 'w+') as f: # Edgelist-Dokument erstellen
    f.write('source;target')
    f.write('\n')
    for i, row in corpus_citations.iterrows():
        reflist = corpus_citations.ref_id[i]
        for elem in reflist:
            elem_count += 1
            if elem in citation_dict: # Beziehung schreiben, wenn die Referenz im dict - also im Korpus - ist
                f.write(corpus_citations.paper_id[i])
                f.write(';')
                f.write(elem)
                f.write('\n')
                relation_count += 1
print(str(relation_count) + ' Beziehungen entdeckt')
print(str(elem_count) + ' Zitationen insgesamt')
print(str((relation_count/elem_count)*100) + '% aller Zitationsbeziehungen werden abgebildet')
189256 Beziehungen entdeckt
1956824 Zitationen insgesamt
9.671590291206568% aller Zitationsbeziehungen werden abgebildet

Knapp 10% aller Zitationsbeziehungen der Werke finden innerhalb unseres Datensatzes statt, d.h. es werden Werke zitiert die ebenfalls im Korpus vorhanden sind. Das heißt aber auch, dass 90% aller Zitationsbeziehungen zu Werken bestehen, die außerhalb unseres Datensatzes liegen oder mit unserer Vorgehensweise mit paper_ID und ref_ID nicht erkannt werden konnten, und dass diese Beziehungen daher nicht weiter untersucht werden können. Obwohl diese recht hohe Anzahl an nicht weiter nachvollziehbaren Beziehungen eine Limitation für die Ausssagekraft unserer Ergebnisse ist, zeigen die 10 % jedoch auch, dass wir mit unserem Korpus scheinbar ein Netzwerk abgebildet haben, dass sich aufeinander bezieht und auf den vorhandenen Wissenstand aufzubauen scheint. Eine genaue Einordnung der Zahl ist jedoch ohne Vergleichswerte kaum möglich und sollte daher mit Vorsicht betrachtet werden.

# Nodelist schreiben: Für jedes Paper auch Publikationsjahr, Kategorienzuordnung, Titel und Abstract angeben 
with open (f'{outputPath}/citation_network_NODELIST.csv', 'w+') as f: # Nodelist-Dokument erstellen
    f.write('id,year,category,title,abstract')
    f.write('\n')
    for i, row in corpus_citations.iterrows():
        f.write(corpus_citations.paper_id[i])
        f.write(',')
        f.write(str(corpus_citations.year[i]))
        f.write(',')
        k_list = corpus_citations.wos_cat[i]
        f.write(k_list)
        f.write(',')
        f.write(str(corpus_citations.title[i].casefold().replace(',', '')))
        f.write(',')
        f.write(str(corpus_citations.abstract[i].casefold().strip().replace(',', '').replace(';', '')))
        f.write('\n')
# Test, ob die Datei korrekt erstellt wurde
test = pd.read_csv(f'{outputPath}/citation_network_NODELIST.csv', delimiter=',', low_memory=False)
test.tail(5)
id year category title abstract
46564 fernandez rm 2013 2013 Industrial Relations & Labor; Sociology race network hiring and statistical discrimina... purpose - research has shown that employers of...
46565 troesken w 2002 2002 Economics; History; History Of Social Sciences ties that bind: economic and political dilemma... NaN
46566 babic m 2017 2017 Computer Science Information Systems; Computer... new method for determination complexity using ... the paper present new method for determination...
46567 lane t 2005 2005 Economics; History; History Of Social Sciences maritime enterprise and empire: sir william ma... NaN
46568 korte f 2019 2019 Psychology Multidisciplinary play-by-play network analysis in football this study identifies dominant and intermediar...

Edge- und Nodelists einiger Zeitabschnitte für die historische Analyse vorbereiten

Wie in Notebook 2 beschrieben, möchten wir nicht nur das Zitationsnetzwerk aus heutiger Sicht beschreiben, sondern den Zustand des Netzwerkes an verschiedenen Zeitpunkten vergleichen. Hierzu müssen wie für die jeweiligen Zeitabschnitte eigene Edge- und Nodelists erstellen.

Koautorschafts- und Zitationsnetzwerk bis 2015#

print(str(len(corpus_citations.index)) + ' Publikationen insgesamt.')
corpus_citations_bis2015 = corpus_citations[corpus_citations.publ_year < 2016]
print(str(len(corpus_citations_bis2015.index)) + ' Publikationen bis 2015.')
46626 Publikationen insgesamt.
20291 Publikationen bis 2015.
# Edgelist bis 2015 schreiben: Gerichtete Beziehung, paper ---zitiert---> paper
relation_count = 0
elem_count = 0
with open (f'{outputPath}/citation_network_EDGELIST_bis2015.csv', 'w+') as f: # Edgelist-Dokument erstellen
    f.write('source;target')
    f.write('\n')
    for i, row in corpus_citations_bis2015.iterrows():
        reflist = corpus_citations_bis2015.ref_id[i]
        for elem in reflist:
            elem_count += 1
            #print(elem)
            if elem in citation_dict: # Beziehung schreiben, wenn die Referenz im dict - also im Korpus - ist
                f.write(corpus_citations_bis2015.paper_id[i])
                f.write(';')
                f.write(elem)
                f.write('\n')
                relation_count += 1
print(str(relation_count) + ' Beziehungen entdeckt')
print(str(elem_count) + ' Zitationen insgesamt')
print(str((relation_count/elem_count)*100) + '% aller Zitationsbeziehungen werden abgebildet')
60364 Beziehungen entdeckt
753918 Zitationen insgesamt
8.006706299624097% aller Zitationsbeziehungen werden abgebildet
# Nodelist bis  2015 schreiben: Für jedes Paper auch Publikationsjahr und Kategorienzuordnung angeben 
with open (f'{outputPath}/citation_network_NODELIST_bis2015.csv', 'w+') as f: # Nodelist-Dokument erstellen
    f.write('id, year, category, title')
    f.write('\n')
    for i, row in corpus_citations_bis2015.iterrows():
        f.write(corpus_citations_bis2015.paper_id[i])
        f.write(',')
        f.write(str(corpus_citations_bis2015.year[i]))
        f.write(',')
        k_list = corpus_citations_bis2015.wos_cat[i]
        f.write(k_list)
        f.write(',')
        f.write(str(corpus_citations_bis2015.title[i].casefold().replace(',', '')))
        f.write('\n')
test = pd.read_csv(f'{outputPath}/citation_network_NODELIST_bis2015.csv', delimiter=',', low_memory=False)
test.head(5)
id year category title
0 muaremi a 2014 2014 Computer Science Theory & Methods; Telecommuni... merging inhomogeneous proximity sensor systems...
1 hutchins ce 2010 2010 Computer Science Interdisciplinary Application... hiding in plain sight: criminal network analysis
2 ma sj 2014 2014 Computer Science Interdisciplinary Application... node influence identification via resource all...
3 slanina f 2010 2010 Mathematics Interdisciplinary Applications; Mu... eigenvector localization as a tool to study sm...
4 cheatham m 2006 2006 Computer Science Artificial Intelligence; Tele... application of social network analysis to coll...

Koautorschafts- und Zitationsnetzwerk bis 2005#

print(str(len(corpus_citations_bis2015.index)) + ' Publikationen bis 2015.')
corpus_citations_bis2005 = corpus_citations[corpus_citations.publ_year < 2006]
print(str(len(corpus_citations_bis2005.index)) + ' Publikationen bis 2005.')
20291 Publikationen bis 2015.
3376 Publikationen bis 2005.
# Edgelist bis 2005 schreiben: Gerichtete Beziehung, paper ---zitiert---> paper
relation_count = 0
elem_count = 0
with open (f'{outputPath}/citation_network_EDGELIST_bis2005.csv', 'w+') as f: # Edgelist-Dokument erstellen
    f.write('source;target')
    f.write('\n')
    for i, row in corpus_citations_bis2005.iterrows():
        reflist = corpus_citations_bis2005.ref_id[i]
        for elem in reflist:
            elem_count += 1
            #print(elem)
            if elem in citation_dict: # Beziehung schreiben, wenn die Referenz im dict - also im Korpus - ist
                f.write(corpus_citations_bis2005.paper_id[i])
                f.write(';')
                f.write(elem)
                f.write('\n')
                relation_count += 1
print(str(relation_count) + ' Beziehungen entdeckt')
print(str(elem_count) + ' Zitationen insgesamt')
print(str((relation_count/elem_count)*100) + '% aller Zitationsbeziehungen werden abgebildet')
6304 Beziehungen entdeckt
125255 Zitationen insgesamt
5.0329328170532115% aller Zitationsbeziehungen werden abgebildet
# Nodelist bis  2005 schreiben: Für jedes Paper auch Publikationsjahr und Kategorienzuordnung angeben 
with open (f'{outputPath}/citation_network_NODELIST_bis2005.csv', 'w+') as f: # Nodelist-Dokument erstellen
    f.write('id, year, category, title')
    f.write('\n')
    for i, row in corpus_citations_bis2005.iterrows():
        f.write(corpus_citations_bis2005.paper_id[i])
        f.write(',')
        f.write(str(corpus_citations_bis2005.year[i]))
        f.write(',')
        k_list = corpus_citations_bis2005.wos_cat[i]
        f.write(k_list)
        f.write(',')
        f.write(str(corpus_citations_bis2005.title[i].casefold().replace(',', '')))
        f.write('\n')
test = pd.read_csv(f'{outputPath}/citation_network_NODELIST_bis2005.csv', delimiter=',', low_memory=False)
print(len(test.index))
test.head(5)
3326
id year category title
0 weesie j 1989 1989 Anthropology; Sociology a transitive random network model
1 burt rs 1998 1998 Sociology the gender of social capital
2 song cm 2005 2005 Multidisciplinary Sciences self-similarity of complex networks
3 feld sl 2002 2002 Anthropology; Sociology detecting measurement bias in respondent repor...
4 anderson jg 1985 1985 Sociology the diffusion of medical technology - social n...

Koautorschafts- und Zitationsnetzwerk bis 1995#

print(str(len(corpus_citations_bis2005.index)) + ' Publikationen bis 2005.')
corpus_citations_bis1995 = corpus_citations[corpus_citations.publ_year < 1996]
print(str(len(corpus_citations_bis1995.index)) + ' Publikationen bis 1995.')
3376 Publikationen bis 2005.
944 Publikationen bis 1995.
# Edgelist bis 1995 schreiben: Gerichtete Beziehung, paper ---zitiert---> paper
relation_count = 0
elem_count = 0
with open (f'{outputPath}/citation_network_EDGELIST_bis1995.csv', 'w+') as f: # Edgelist-Dokument erstellen
    f.write('source;target')
    f.write('\n')
    for i, row in corpus_citations_bis1995.iterrows():
        reflist = corpus_citations_bis1995.ref_id[i]
        for elem in reflist:
            elem_count += 1
            #print(elem)
            if elem in citation_dict: # Beziehung schreiben, wenn die Referenz im dict - also im Korpus - ist
                f.write(corpus_citations_bis1995.paper_id[i])
                f.write(';')
                f.write(elem)
                f.write('\n')
                relation_count += 1
print(str(relation_count) + ' Beziehungen entdeckt')
print(str(elem_count) + ' Zitationen insgesamt')
print(str((relation_count/elem_count)*100) + '% aller Zitationsbeziehungen werden abgebildet')
1220 Beziehungen entdeckt
29146 Zitationen insgesamt
4.185823097509092% aller Zitationsbeziehungen werden abgebildet
# Nodelist bis  1995 schreiben: Für jedes Paper auch Publikationsjahr und Kategorienzuordnung angeben 
with open (f'{outputPath}/citation_network_NODELIST_bis1995.csv', 'w+') as f: # Nodelist-Dokument erstellen
    f.write('id, year, category, title')
    f.write('\n')
    for i, row in corpus_citations_bis1995.iterrows():
        f.write(corpus_citations_bis1995.paper_id[i])
        f.write(',')
        f.write(str(corpus_citations_bis1995.year[i]))
        f.write(',')
        k_list = corpus_citations_bis1995.wos_cat[i]
        f.write(k_list)
        f.write(',')
        f.write(str(corpus_citations_bis1995.title[i].casefold().replace(',', '')))
        f.write('\n')
test = pd.read_csv(f'{outputPath}/citation_network_NODELIST_bis1995.csv', delimiter=',', low_memory=False)
print(len(test.index))
test.head(5)
944
id year category title
0 weesie j 1989 1989 Anthropology; Sociology a transitive random network model
1 anderson jg 1985 1985 Sociology the diffusion of medical technology - social n...
2 hildum dc 1986 1986 Anthropology; Sociology competence and performance in network structure
3 barney jb 1985 1985 Anthropology; Sociology dimensions of informal social network structur...
4 mclanahan ss 1981 1981 Family Studies; Sociology network structure social support and psycholog...

Zitationsnetzwerk von 2005 bis 2015#

Bei der Visualisierung der historischen Netzwerke mit Gephi haben wir gemerkt, dass unsere Rechnerleistung für das aktuelle - und daher signifikant größere - Netzwerk kaum ausreicht. Das Netzwerk bis 2015 konnten wir in Gephi gerade noch einlesen und bearbeiten, das Netzwerk bis heute - 2022 - konnten wir hingegen nicht mehr visualisieren, da selbst Algorithmen wie Noverlap und LabelAdjust nach mehrstündigen Laufzeiten keine Verbesserung in der Darstellung erzielen konnten.

Somit haben wir uns entschlossen für diesen letzten Zeitabschnitt ein kleinere Node- und Edgelist zu erstellen, die nur den Zeitraum zwischen 2015 und 2022 umfassen.

print(str(len(corpus_citations.index)) + ' Publikationen insgesamt.')
corpus_citations_2015bis2022 = corpus_citations[corpus_citations.publ_year > 2014]
print(str(len(corpus_citations_2015bis2022.index)) + ' Publikationen zwischen 2015 und 2022.')
46626 Publikationen insgesamt.
29558 Publikationen zwischen 2015 und 2022.
# dict für die Paper im Korpus erstellen die früher als 2015 erschienen sind, paper_ids als keys
citation_dict_2015 = {}
for i, row in corpus_citations.iterrows():
    paper = corpus_citations.paper_id[i]
    year = int(paper[-4:])
    if year >= 2015:
        citation_dict_2015[paper] = ''
# Edgelist zwischen 2015 und 2022 schreiben: Gerichtete Beziehung, paper ---zitiert---> paper
relation_count = 0
elem_count = 0
with open (f'{outputPath}/citation_network_EDGELIST_2015bis2022.csv', 'w+') as f: # Edgelist-Dokument erstellen
    f.write('source;target')
    f.write('\n')
    for i, row in corpus_citations_2015bis2022.iterrows():
        reflist = corpus_citations_2015bis2022.ref_id[i]
        for elem in reflist:
            elem_count += 1
            #print(elem)
            if elem in citation_dict_2015: # Beziehung schreiben, wenn die Referenz im dict - also im Korpus - ist
                f.write(corpus_citations_2015bis2022.paper_id[i])
                f.write(';')
                f.write(elem)
                f.write('\n')
                relation_count += 1
print(str(relation_count) + ' Beziehungen entdeckt')
print(str(elem_count) + ' Zitationen insgesamt')
print(str((relation_count/elem_count)*100) + '% aller Zitationsbeziehungen werden abgebildet')
52654 Beziehungen entdeckt
1323196 Zitationen insgesamt
3.979304653278879% aller Zitationsbeziehungen werden abgebildet
test = pd.read_csv(f'{outputPath}/citation_network_EDGELIST_2015bis2022.csv', delimiter=',', low_memory=False)
print(len(test.index))
test.head(5)
52654
source;target
0 liu hy 2021;clifton a 2017
1 liu hy 2021;epskamp s 2017
2 liu hy 2021;liu hy 2018
3 liu hy 2021;sewell dk 2015
4 liu hy 2021;sweet tm 2019