Schlagwort-Archiv: Step by Step

Scraping Web Data with Rapidminer

After my last post about the chracteristics of Bundesliga players‘ body data by position I have been asked whether there is a relationship between the height of players or teams and their tactics on the field. For example, is a team with taller forwards more likely to make use of crosses and headers to score? While I’m still working on this topic, I thought it would be nice to show how I build a dataset of all Bundesliga goals in the past season to answer this question.

So here is a short introduction to scraping web data with Rapidminer. My goal: Build a dataset including all goals of the last Bundesliga season including additional information such as the kind of assist which preceded it. A good data source is Transfermarkt.de, which offers a game sheet for every match.

For a few matches, the relevent data can be extracted by hand. The problem arises when you plan to collect data for a whole season. So here is how I did it, step by step.

Preparing a list of websites to scrape

  1. The first thing to do is to build up a collection of pages that contain the information you’re looking for. Transfermarkt offers a season overview containing all matches and links to their respective game sheets.
  2. The next step is to view the source code of the the page which contains all the links.
  3. Copy the html-code to Excel or any other spreadsheet application.
  4. You’ll realize that you’ve copied thousands of lines of code. In this case only 306, the total sum of matches per season, are of interest. A good procedure to separate the lines containing valueable information is to sort the whole table document. Having a unique structure, the relevant lines will be concentrated in one section, while all others lines can be deleted.
  5. When only the relevant lines of code are left, the next step is to separate the relevant links from the remaining html-structure. A good way to do this is to use quotation marks as separators.
  6. Having deleted all irrelevant columns, the last step is to add the domain name common to all links in front of them, in this case „www.transfermarkt.de/“ In Excel you can merge strings by using „&“. The result is a list of all html pages to scrape which can be used in Rapidminer.

Scraping with Rapidminer

From here on I assume, that you have a basic understanding how Rapidminer works and how processes can be designed. So I won’t start with the absolute basics. If you don’t have already, you should now install Rapidminer along with the newest version of the webmining package.

At the end, your main process should look like this:

  1. After having opened a new project in Rapidminer, the first thing to do is to make use of the „Read Excel“ operator. It will read the link spreadsheet line by line and submit the websites to the following operator. All operators can be searched in the operators section on the left side. In the parameters section on the right you only have to provide the path to your file and the information whether the first row contains headlines. The import wizard provided should be useful. Important: Make sure the attribute of the variable containing the links is set to „file path“.
  2. Next you have to add the „Get Pages“ operator to your process and connect it to the „Read Exel“ operator. The only thing to do here is to define the name of column wich contains the links in the spreadsheet.
  3. The third operator to use is „Data to Documents“. Connect it to the output of „Get Pages“.
  4. Connect the document output to the „Process Documents“ operator. It is important that the keep text option is checked. Otherwise there will be no text to extract the data from.
  5. Double click on the „Process Documents“ operator. You now are at a lower level where you can set the nested operations that will take place within the „Process Documents“ operator. The operators combined inside should look like this afterwards:
  6. First operator in here is „Extract Content“ which separates text and html tags. The minimum text block length defines how long the extracts (tokens) have to be at least. You should set the length depending on the the content you want to extract. If you set it to one, all text will be extracted.
  7. This step is optional. You can use the „Filter tokens“ operator to decide wich pieces of text you want to keep. You can determine tokens to keep by giving the operator a string by which it is filtered. The standard setting is that tokens containing the defined string are kept. But there is also the possibility to invert the filter by selecting the checkbox in the parameters section. I used this to exclude all social media text like „share on twitter“ etc. But this can be done later as well.
  8. The next step is optional too. With the „Cut Document“ operator you can cut your text in parts by selecting strings as starting and ending sequences. The use of this operator makes sense, if you are only interested in a particular part of the text. If a text is well structured, like the game sheets on Transfermarkt.de, every type of information will be found in it’s own section. For example all information of a match’s goals are available between its own header „Tore“ („goals“) and „Wechsel“ („substitutions“) as the header of the next block of information. If you apply this operator, only text between the matching strings will be kept. It is possible to define a great number of matching strings. In the resulting data set each extracted section can be identified by  the name you labeled it with.
  9. Now you can return to the main process. The final step here is to connect the output of the „Process Documents“ operator to the „Write Excel“ operator. Select a directory and a document type, and Rapidminer will write your dataset in an Excel file.

Data Jiu-Jiutsu

The rest of the work can be done in Excel again.

  1. Depending on whether you cut one or more sections from the text, your dataset will contain the number of cut section X the number of pages you scraped. By sorting the spreadsheet by the label (query key attribute) assigned to each different section, you can easily select the ones you want and copy them to another table.
  2. The last steps to create your data set is data jiu-jiutsu. Everybody has different ways to handle it. In my case, I had to think a while before I realised what might be a good solution to get my data in shape, because there where no separators in the text to distinguish goal events.  Finally I substituted all score information of goals by simply adding a leading comma. For example „0:1“ was converted to „,0:1“. By just adding a comma for every „digit-:“ combination. This was done within a minute. The rest is a lot of reshaping.

I hope this tutorial will be useful to somebody, If there are further questions, don’t hesitate to ask them in the comments section.

by Tobias Wolfanger

Das eigene Facebook-Netzwerk mit netvizz und Gephi

Heute möchte ich vorstellen, wie man mit Hilfe von netvizz und Gephi sein eigenes Facebook-Netzwerk erstellen und visualisieren kann. Das Ergebnis ist ein Netzwerk-Graph, der alle Freundschaften innerhalb des eigenen Facebook-Freundeskreises visualisiert. An diesem lassen sich einige interessante Dinge ablesen, z.B. welche Gemeinschaften es gibt und welche Personen Schlüsselpositionen im eigenen Freundeskreis einnehmen.

Netwerkdatensatz mit netvizz herunterladen

Aber Schritt für Schritt: Zu aller erst muss die Datengrundlage besorgt werden. Innerhalb von Facebook lässt sich dies mit Hilfe der App netvizz realisieren. Folgendes Schritte sind dafür notwendig.

  1. Wir loggen uns in den eigenen Facebook-Account ein.
  2. In das Suchfenster geben wir „netvizz“ ein, klicken darauf und stimmen der Anwendung zu.
  3. Unter dem Punkt „your personal friend network“ bei Step 2 klicken wir auf „here“.
  4. Nun hat netvizz einen Datensatz für unser persönliches Facebook-Netzwerk erstellt. Leider werden nicht alle Freunde in den Datensatz aufgenommen. Bei mir zeigt netvizz an, dass die Datei 188 „nodes“ („Knoten“), also Freunde, und 1373 „edges“ ,Freundschaften zwischen Freunden, abbildet. Das bedeutet, dass 26 meiner 214 Freunde nicht aufgenommen wurden, was in Zusammenhang mit deren Privacy-Einstellungen steht. Wir können Sie jedoch zu einem späteren Zeitpunkt manuell hinzufügen.
  5. Wir klicken mit der rechten Maustaste auf „gdf file“, gehen zu „speichern unter“, wählen „alle Dateien“ und fügen an das Ende des vorgeschlagenen Dateinamens „.gdf“ an. Nun haben wir unseren Netzwerkgraph bereits als Datensatz auf dem Rechner liegen.

Öffnen des Netzwerks in Gephi

Um unser Facebook-Netzwerk zu betrachten, benutzen wir die Open Source Software Gephi die hier heruntergeladen werden kann. Nach der Installation fahren wir mit folgenden Schritten fort:

  1. Wir öffnen Gephi auf unserem Desktop.
  2. Unter „Datei“ -> „Open“ wählen wir den mit netvizz heruntergeladenen Datensatz aus und öffnen ihn.
  3. Im nachfolgenden „Import report“ müssen wir den Graph Type von „Directed“ auf „Undirected“ umstellen und anschließend auf „OK“ klicken. Diese Einstellung gibt an, ob die Beziehung zwischen zwei Knoten symmetrisch oder asymmetrisch sein soll. Bei Facebook sind Freundschaften stets symmetrisch. Man kann mit niemandem befreundet sein, der nicht auch mit einem selbst befreundet sein möchte. Anders ist das etwa bei Twitter oder Google +, wo  asymmetrische Verbindungen der Regelfall sind.
  4. Anschließend benötigt Gephi eine kurze Ladezeit für das Netzwerk, von der wir uns nicht aus der Ruhe bringen lassen. Irgendwann erscheint dann ein verworrener Klumpen auf unserem Bildschirm, der eine erste, wenn auch ziemlich hässliche Visualisierung unseres Netzwerks darstellt. In dieser repräsentiert jeder Punkt einen Freund und jede Linie eine Freundschaft.

Visualisierung des Netzwerks

  1. Nun wollen wir Struktur in unser Netzwerk bringen. Zu diesem Zweck wählen wir ein Layout in der linken unteren Ecke des Bildschirms aus. Meine Erfahrung nach stellt Force Atlas eine gute Variante dar, um Facebook-Netzwerke ansehnlich aufzubereiten. (Natürlich lohnt es sich auch die anderen Layout-Algorhythmen einmal auszuprobieren.) Die angebotenen Einstellungsmöglichkeiten können wir vorerst ignorieren werden, stattdessen klicken wir auf „Run“. Die Netzwerkstruktur bildet sich nun durch Abstoßen und Anziehen zwischen den Knoten heraus. Ab einem gewissen Punkt driften die Komponenten des Netzwerks nur noch weiter auseinander und  wir können auf „Stop“ klicken.
  2. Im nächsten Schritt ist es sinnvoll, den Punkte im Netzwerk eine Identität zuzuorden. Durch das Klicken auf das große, schwarze T am unteren Rand des Programms werden die Knoten mit den (Facebook-)Namen unserer Freunde beschriftet.
  3. Leider überlagern sich die Namen und Punkte immernoch so stark, dass man kaum etwas erkennen kann. Wir wählen daher zwei weitere Layout-Funktionen aus. Wo wir zuvor Force Atlas ausgeführt haben, wählen wir nun Noverlap und führen es aus. Das Resultat ist, dass sich die Punkte in unserem Netzwerk nicht mehr überschneiden. Als nächstes wählen wir an gleicher Stelle LabelAdjust. Nach der Ausführung sollten alle Namen überschneidungsfrei sichtbar sein.
  4. Auf dem Bildschirm lassen sich bereits unterschiedliche Gruppen von Freunden räumlich abgrenzen, die wir aus unterschiedlichen Bezügen und Lebensabschnitten kennen. Nun wäre es schön, diese Gruppen farblich voneindander abzuheben. Dazu klicken wir auf der rechten Seite in der Mitte auf den Reiter „Statistics“ und wählen dort „Run“ neben dem Punkt „Modularity“. Der nachfolgende Report kann geschlossen werden. Damit haben wir eine Berechnung ausgeführt, die Gruppen unterscheidet, indem sie Gemeinschaften so einteilt, dass möglichst viele Verbindungen (Freundschaften) innerhalb und möglichst wenige zwischen diesen liegen. Ein Maß für die Qualität des Ergebnis liefert der bei „Modularity“ angezeigte Wert im Wertebereich zwischen -1 und 1, der durch den Algorhytmus möglichst nahe an 1 gebracht wird. Genaueres lässt sich bei den Autoren nachlesen.
  5. In der oberen linken Ecke des Bildschirms klicken wir nun unter „Partition“ und „Nodes“ auf die zwei grünen Pfeile, und wählen anschließend im Dropdown-Menü „Modularity Class“ aus. Nach einem Klick auf „Apply“ erscheinen die Gemeinschaften im Netzwerk farblich unterschieden. Die Farben können wir nach eigenem Geschmack modifizieren, indem wir auf die farbigen Quadrate klicken. Die Einteilung in Gemeinschaften kann in Richtung kleinerer oder größerer Gruppen durch eine Neuberechung verändert werden, indem die Resolution im Zwischenniveau modifiziert wird.
  6. Die farbliche Unterscheidung gibt unserem Netzwerk zusätzliche Struktur. Als nächstes wäre es doch schön zu wissen, welche unserer Freunde eine besondere Rolle in unserem Netzwerk spielen. Je nach Erkenntnisinteresse bieten sich dafür unterschiedliche Möglichkeiten der Visualisierung an. Für alle müssen wir unter „Statistics“ auf der rechten Seite „Network Diameter“ ausführen. Anschließend geht es wieder in die obere linke Ecke, diesmal unter den Reiter „Ranking“. Wir wählen wieder „Nodes“ aus sowie deren Größe als das zu gestaltende Element (Der rote Diamant). Im Dropdown-Menü stehen uns jetzt die soeben errechneten Maße zur Verfügung. Eine gute Variante ist, die größe eines Punktes in Abhängigkeit von dessen „Degree“ zu setzen, der Summe aller Verbindungen im Netzwerk. In der Visualierung des Netzwerks sind nun diejenigen die Knoten am größten, mit denen wir die meisten Facebook-Freunde teilen. Bei den meisten werden dies die besten Freunde sein, mit denen man Bekannte aus vielen verschiedenen Lebensbezügen gemein hat. Ebenfalls lohnt es sich, die sog. „Betweenness Centrality“ als Maß für die Größe der Punkte auszuwählen. Diese gibt an, wie, auf wie vielen kürzesten Verbindungen zwischen jeweils zwei Punkten ein Knoten liegt. So kommt es, dass bei dieser insbesondere Personen hohe Werte aufweisen, die unterschiedliche Gemeinschaften verbinden, wie zum Beispiel der Lebensgefährte oder die Lebensgefährtin, die mit vielen Freunden aus den unterschiedlichen persönlichen sozialen Kontexten bekannt sind.

Mein Netzwerk

Nachfolgend möchte ich kurz zwei Visualisierungen meines Facebook-Netzwerks vorstellen, damit ein optischer Eindruck des Resultats entsteht. Aus Datenschutzgründen habe ich auf die Beschriftung und die Nennung von Namen verzichtet und lediglich den sozialen Kontext angegeben, der mein Verhältnis zur jeweiligen Gruppe am besten beschreibt. Wer mich besser kennt, dem wird es jedoch relativ leicht fallen, das Netzwerk zu entschlüsseln.

Die erste Abbildung zeigt die Struktur meines Facebook-Netzwerks, welches sich sehr gut in Gemeinschaften mit unterschiedlichen Kontexten unterteilen lässt. In der unteren Rechten Ecke verbleibt ein Knäuel, der sehr viele Verbindungen zwischen den Punkten aufweist. Es handelt sich dabei vor allem um Facebook-Freunde aus Oldenburg und Umgebung. Die Einteilung in Gemeinschaften fällt hier sehr schwer, da die wechselseitigen Bindungen sehr stark sind. Grob lässt sich eine Farbe eher dem Kontext Schule, eine andere dem Sport oder dem Heimatort zuordnen, allerdings bestehen zu viele Querverbindungen für eine saubere Trennung. Oldenburg ist wohl mehr oder weniger ein großes Dorf 🙂 Besonders die zwei großen grünen Punkte fallen optisch aus dem Knäuel: zwei meiner besten Freunde mit denen ich nicht ohne Grund viele gemeinsame Freunde bei Facebook habe, da wir stets viel Zeit miteinander verbracht haben und immer noch verbringen, wenn die Gelegenheit besteht.

Persönliches Facebook-Netzwerk mit Skalierung der Freunde nach Degree

Abbildung1: Persönliches Facebook-Netzwerk mit Skalierung der Freunde nach Degree

Die zweite Abbildung zeigt das gleiche Netzwerk, aber mit der „Betweeness Centrality“ als Maß für die Größe eines Knotens. Die beiden großen grünen Punkte spielen hier nur eine untergeordnete Rolle, da ihnen in einem eng verbundenen Netzwerk keine Schlüsserolle bei der Verbindung von Knoten zukommt. Stattdessen bildet meine Freundin den größten Punkt im Netzwerk, da sie, wie bereits thematisiert, viele meiner Freunde aus unterschiedlichen Bezügen kennt.

Netzwerk mit Skalierung der Knoten nach "Betweeness Centrality"

Abbildung 2: Persönliches Facebook-Netzwerk mit Skalierung der Freunde nach „Betweeness Centrality“

Optional: Freunde und Verbindungen hinzufügen

Wir haben nun unser Facebook-Netzwerk mit Hilfe von gephi Visualisiert, einige Fragen dürften aber noch offen sein. Wie können etwa Freunde zum Netzwerk hinzugefügt werden, die aufgrund der Privacy-Einstellungen der Freunde nicht aufgenommen wurden? Die Möglichkeit dazu besteht in der Ansicht „Data Laboratory“ auf dem Reiter „Data Table“ . Über „Add node“ und „Add edge“ können Freunde und Facebook-Freundschaften hinzugefügt werden, am besten gleicht man dazu die Datentabelle mit seiner Freundesliste auf Facebook ab. Insbesondere letzteres kann etwas mühselig werden, daher gibt es die Möglichkeit in der Ansicht „Overview“ Verbindungen zwischen Punkten zu zeichnen, anstatt diese einzugeben. Am linken Rand des mittleren Fensters dient dazu der untere der beiden Bleistifte.

Zu guter Letzt könnte der eine oder andere noch eine Frage mit sich herumtragen: Wo bin ich? Das auf dem beschriebenen Wege visualisierte Facebook-Netzwerk hat keinen Eintrag für denjenigen, dessen Freundschaftsgeflecht abgebildet wird. Das hat ein paar gute Gründe, etwa die Vermeidung der zentralen Ausrichtung des Netzwerks auf nur eine Person. Eine Reihe interessanter Erkenntnisse würde so eher erschwert. So würde z.B. jede Verbindung zwischen zwei Personen im Netzwerk maximal aus zwei Schritten bestehen, da diese immer zumindest einen gemeinsamen Freund haben, nämlich denjenigen, dessen Netzwerk visualisiert wird. Wer sich selbst in das Netzwerk einfügen möchte, kann das ausprobieren, indem er einen Knoten für sich selbst erstellt und diesen mit allen anderen im Netzwerk verbindet.

Ich hoffe ich konnte zeigen, welche interessanten Einblicke durch die Visualisierung des eigenen Facebook-Netzwerks möglich sind. Vielleicht hat der eine oder andere Lust bekommen, es auch zu versuchen. Für Hilfestellungen und Nachfragen stehe ich gerne zur Verfügung und natürlich freue ich mich über Feedback in den Kommentaren.

von Tobias Wolfanger