Diese Folie ist absichtlich leer

Data Science meets
Software Data

Markus Harrer

@feststelltaste

The Architecture Gathering, 17.10.2019

Über mich

Datenanalysen in der Softwareentwicklung?

Das (Tr|D)auerthema

Das (Tr|D)auerthema

Das (Tr|D)auerthema

Lösung:


Data Science meets Software Data?

Data Science

Was ist Data Science?

"Statistik auf nem Mac."

Nach https://twitter.com/cdixon/status/428914681911070720

Meine Definition

Was bedeutet "data"?

"Without data you‘re just another person with an opinion."

W. Edwards Deming

=> Belastbare Erkenntnisse mittels Fakten liefern

Was bedeutet "science"?

"The aim of science is to seek the simplest explanations of complex facts."

Albert Einstein

=> Neue Erkenntnisse verständlich herausarbeiten

Was hat das mit Softwareentwicklung zu tun?

Was ist ein Data Scientist?

"Jemand, der mehr Ahnung von Statistik
  hat als ein Softwareentwickler
  und mehr Ahnung von Softwareentwicklung
  als ein Statistiker."

Nach zu https://twitter.com/cdixon/status/428914681911070720

=> Wir sind gar nicht so weit weg!

Software Data

Welche Arten von Softwaredaten?

Alles was aus der Entwicklung und dem Betrieb der Softwaresysteme so anfällt:

  • Statische Daten
  • Laufzeitdaten
  • Historische Daten
  • Daten aus der Software-Community

=> Eine sehr große Auswahl!

Software Analytics

Definition "Software Analytics"

"Software Analytics is analytics on software data for managers and software engineers with the aim of empowering software development individuals and teams to gain and share insight from their data to make better decisions."

Tim Menzies and Thomas Zimmermann

Das (Tr|D)auerthema

Das (Tr|D)auerthema

Aber: Hier gibt es ein Problem!

Thomas Zimmermann in "One size does not fit all":

"Even if you find models that work for most, they will not work for everyone. There is much academic research into general models. In contrast, industrial practitioners are often fine with models that just work for their data if the model provides some insight or allows them to work more efficiently."

Beispiele für Analysen aus der Praxis

  • Vorhandenen Modularisierungsschnitt analysieren
  • Performance-Probleme in verteilten Systemen identifizieren
  • Potenzielle Wissensverluste ermitteln
  • Eingesetzte Open-Source-Projekte bewerten
  • ...

"Es kommt drauf an!" aka Kontext

Individuelle Systeme => individuelle Probleme => individuelle Analysen => individuelle Erkenntnisse!

Das (Tr|D)auerthema

Das (Tr|D)auerthema



Data Science mit Softwaredaten

Eine leichtgewichtige Umsetzung von Software Analytics

Best Practices

Bewährtes Vorgehen

Nach Roger Pengs "Stages of Data Analysis"
I. Fragestellung
II. Explorative Datenbeschaffung
III. Formale Modellierung
IV. Interpretation
V. Kommunikation

=> von der Frage über die Daten zur Erkenntnis!

Literate Statistical Programming

(Intent + Code + Data + Results)
* Logical Step
+ Automation
= Literate Statistical Programming


Implementierung: Computational notebooks

Computational Notebooks


Flexible Standardwerkzeuge (1/2)

Klassischer Data-Science-Werkzeugkasten

  • Jupyter (mit RISE)
  • Python 3
  • pandas
  • matplotlib

Flexible Standardwerkzeuge (2/2)

Jupyter funktioniert und integriert sich auch mit

  • jQAssistant / Cypher / Neo4j
  • JVM-Sprachen über beakerx / Tablesaw
  • bash
  • ...

Praktischer Teil

Erste Demo

Fallbeispiel

IntelliJ IDEA

  • IDE für die Java-Entwicklung
  • Vieles in Java geschrieben
  • Großes und lang entwickeltes Projekt

I. Fragestellung (1/3)

  • Offene Frage explizit niederschreiben
  • Analyseidee verständlich darstellen

I. Fragestellung (2/3)

Frage

  • Welche Quellcodedateien sind besonders komplex und änderten sich in letzter Zeit häufig?

I. Fragestellung (3/3)

Umsetzungsidee

  • Werkzeuge: Jupyter, Python, pandas, matplotlib
  • Heuristiken:
    • "komplex": Lines of Code
    • "letzter Zeit": Letzte 90 Tage
    • "häufig": Anzahl Git Commits

Meta-Ziel: Grundmechaniken kennenlernen.

II. Explorative Datenbeschaffung

  • Daten in Data-Science-Welt laden
  • Rohdaten bereinigen und filtern

Wir laden Git Log Daten eines Git Repos.


In [1]:
import pandas as pd

log = pd.read_csv("../dataset/git_log_intellij.csv.gz")
log.head()


Out[1]:
additions deletions filename sha timestamp author
0 4 0 java/java-impl/src/com/intellij/codeInsight/hi... be6247932aa9 2019-07-01 14:40:24 Roman.Ivanov
1 4 6 java/java-impl/src/com/intellij/codeInsight/hi... ee2032b77eca 2019-07-01 11:36:14 Roman.Ivanov
2 0 3 java/java-impl/src/META-INF/JavaPlugin.xml fbeb4d639dc1 2019-06-26 11:14:34 Roman.Ivanov
3 6 3 java/java-impl/src/com/intellij/codeInsight/hi... fbeb4d639dc1 2019-06-26 11:14:34 Roman.Ivanov
4 11 6 java/java-impl/src/com/intellij/codeInsight/hi... a3d5a9b855fe 2019-06-14 10:32:15 Roman.Ivanov

Wir erkunden die geladenen Daten.


In [2]:
log.info()


<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1128819 entries, 0 to 1128818
Data columns (total 6 columns):
additions    1128819 non-null object
deletions    1128819 non-null object
filename     1128819 non-null object
sha          1128819 non-null object
timestamp    1128819 non-null object
author       1128819 non-null object
dtypes: object(6)
memory usage: 51.7+ MB

1 DataFrame (~ programmierbares Excel-Arbeitsblatt), 6 Series (= Spalten), 1128819 Rows (= Einträge)

Wir wandeln die Zeitstempel von Texte in Objekte um.


In [3]:
log['timestamp'] = pd.to_datetime(log['timestamp'])
log.head()


Out[3]:
additions deletions filename sha timestamp author
0 4 0 java/java-impl/src/com/intellij/codeInsight/hi... be6247932aa9 2019-07-01 14:40:24 Roman.Ivanov
1 4 6 java/java-impl/src/com/intellij/codeInsight/hi... ee2032b77eca 2019-07-01 11:36:14 Roman.Ivanov
2 0 3 java/java-impl/src/META-INF/JavaPlugin.xml fbeb4d639dc1 2019-06-26 11:14:34 Roman.Ivanov
3 6 3 java/java-impl/src/com/intellij/codeInsight/hi... fbeb4d639dc1 2019-06-26 11:14:34 Roman.Ivanov
4 11 6 java/java-impl/src/com/intellij/codeInsight/hi... a3d5a9b855fe 2019-06-14 10:32:15 Roman.Ivanov

Wir sehen uns nur die jüngsten Änderungen an.


In [4]:
recent = log[log['timestamp'] > log['timestamp'].max() - pd.Timedelta('90 days')]
recent.head()


Out[4]:
additions deletions filename sha timestamp author
0 4 0 java/java-impl/src/com/intellij/codeInsight/hi... be6247932aa9 2019-07-01 14:40:24 Roman.Ivanov
1 4 6 java/java-impl/src/com/intellij/codeInsight/hi... ee2032b77eca 2019-07-01 11:36:14 Roman.Ivanov
2 0 3 java/java-impl/src/META-INF/JavaPlugin.xml fbeb4d639dc1 2019-06-26 11:14:34 Roman.Ivanov
3 6 3 java/java-impl/src/com/intellij/codeInsight/hi... fbeb4d639dc1 2019-06-26 11:14:34 Roman.Ivanov
4 11 6 java/java-impl/src/com/intellij/codeInsight/hi... a3d5a9b855fe 2019-06-14 10:32:15 Roman.Ivanov

Wir wollen nur Java-Code verwenden.


In [5]:
java = recent[recent['filename'].str.endswith(".java")]
java.head()


Out[5]:
additions deletions filename sha timestamp author
27 1 10 platform/smRunner/src/com/intellij/execution/t... f4ed78c8f574 2019-06-28 18:28:41 Ilya.Kazakevich
29 28 0 platform/smRunner/testSrc/com/intellij/executi... f4ed78c8f574 2019-06-28 18:28:41 Ilya.Kazakevich
30 6 3 plugins/InspectionGadgets/InspectionGadgetsAna... a724467ad1a5 2019-07-01 19:47:38 Roman Shevchenko
31 2 2 plugins/InspectionGadgets/test/com/siyeh/igfix... a724467ad1a5 2019-07-01 19:47:38 Roman Shevchenko
32 2 2 plugins/InspectionGadgets/test/com/siyeh/igfix... a724467ad1a5 2019-07-01 19:47:38 Roman Shevchenko

III. Formale Modellierung

  • Neue Sichten auf das Vorhandene schaffen
  • Zusätzliche Informationen hinzuziehen

Wir aggregieren die Zeilen sowie die Anzahl der Änderungen pro Datei.


In [6]:
changes = java.groupby('filename')[['sha']].count()
changes.head()


Out[6]:
sha
filename
RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java 1
RegExpSupport/src/org/intellij/lang/regexp/RegExpCapability.java 1
RegExpSupport/src/org/intellij/lang/regexp/RegExpFileType.java 5
RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHost.java 16
RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java 15

Wir holen Infos über die Code-Zeilen hinzu...


In [7]:
loc = pd.read_csv("../dataset/cloc_intellij.csv.gz", index_col=1)
loc.head()


Out[7]:
language blank comment code
filename
java/java-tests/testData/psi/resolve/ThinletBig.java Java 299 1140 20125
java/java-tests/testData/psi/parser-full/declarationParsing/class/LongClass.java Java 10121 10164 10166
python/gen/com/jetbrains/python/console/protocol/PythonConsoleBackendService.java Java 1971 591 10086
jps/jps-builders/src/org/jetbrains/jps/api/CmdlineRemoteProto.java Java 502 3066 8605
plugins/java-decompiler/engine/testData/obfuscated/aj.java Java 551 1 8043

...und verschneiden diese mit den vorhandenen Daten.


In [8]:
hotspots = changes.join(loc[['code']]).dropna(subset=["code"])
hotspots.head()


Out[8]:
sha code
filename
RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java 1 1190.0
RegExpSupport/src/org/intellij/lang/regexp/RegExpCapability.java 1 34.0
RegExpSupport/src/org/intellij/lang/regexp/RegExpFileType.java 5 40.0
RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHost.java 16 92.0
RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHosts.java 15 168.0

VI. Interpretation

  • Ergebnismenge reduzieren
  • Kernaussagen klar herausarbeiten

Wir zeigen die TOP 10 Hotspots an.


In [9]:
top10 = hotspots.sort_values(by="sha", ascending=False).head(10)
top10


Out[9]:
sha code
filename
platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/StructuralSearchDialog.java 83 1097.0
platform/platform-impl/src/com/intellij/idea/IdeaApplication.java 71 366.0
platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java 67 1425.0
platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java 65 810.0
platform/lang-impl/src/com/intellij/build/BuildTreeConsoleView.java 63 936.0
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingRunner.java 63 1300.0
platform/platform-impl/src/com/intellij/idea/StartupUtil.java 62 551.0
platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerConfigurableNewLayout.java 60 1284.0
platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java 59 606.0
platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java 57 299.0

V. Kommunikation

  • Ergebnisse managementtauglich darstellen
  • Nächste Schritte lostreten

Wir plotten die TOP 10 Liste als XY-Diagramm.


In [10]:
# %load ugly_plotting_code.py
ax = top10.plot.scatter('sha', 'code');

for k, v in top10.iterrows():
    ax.annotate(k.split("/")[-1], v)


Ende der Demo

Weitere Analysebeispiele

  • Analyse der CPU-Auslastung mit Hilfe von vmstat
  • Abhängigkeitsanalyse mit jdeps und D3
  • Analyse der Änderungskohäsion mit Git
  • Call-Graph-basierte Analyse von Performance-Hotspots mit jQAssistant / Neo4j
  • Prüfung der Architektur-Governance-Vorgaben mit jQAssistant

Einstieg in das Thema

  • Adam Tornhill: Software Design X-Ray
  • Wes McKinney: Python For Data Analysis
  • Jeff Leek: The Elements of Data Analytic Style
  • Tim Menzies, Laurie Williams, Thomas Zimmermann: Perspectives on Data Science for Software Engineering
  • Mini-Tutorial: binder.softwareanalytics.de

Schnelleinstieg

Meine TOP 5's*

https://www.feststelltaste.de/category/top5/

Kurse, Videos, Blogs, Bücher und mehr...

*einige Seiten befinden sich noch in der Entwicklung

Zusammenfassung

1. Softwareanalysen mit Data-Science-Werkzeugen sind möglich
2. Wer mehr will bekommt auch mehr!
3. Es gibt unglaublich viele Quellen für Daten in der Softwareentwicklung

=> von der Frage über die Daten zur Erkenntnis!

Vielen Dank! Fragen?

Markus Harrer
innoQ Deutschland GmbH

markus.harrer@innoq.com

@feststelltaste