-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
289 lines (252 loc) · 16.9 KB
/
Copy pathindex.html
File metadata and controls
289 lines (252 loc) · 16.9 KB
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
---
title: Community Learning
keywords: fastai
sidebar: home_sidebar
summary: "In diesem PoC wird anhand von Beispiel Daten der Federated Learning Ansatz aufgezeigt. Die Beispieldaten stammen von der Kaggle [Santander Product Recommendation](https://www.kaggle.com/c/santander-product-recommendation/data) Competition."
description: "In diesem PoC wird anhand von Beispiel Daten der Federated Learning Ansatz aufgezeigt. Die Beispieldaten stammen von der Kaggle [Santander Product Recommendation](https://www.kaggle.com/c/santander-product-recommendation/data) Competition."
---
<!--
#################################################
### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
#################################################
# file to edit: index.ipynb
# command to build the docs after a change: nbdev_build_docs
-->
<div class="container" id="notebook-container">
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Hier ein Auszug von der Kaggle Website</p>
<blockquote><p>In this competition, you are provided with 1.5 years of customers behavior data from Santander bank to predict what new products customers will purchase. The data starts at 2015-01-28 and has monthly records of products a customer has, such as "credit card", "savings account", etc. You will predict what additional products a customer will get in the last month, 2016-06-28, in addition to what they already have at 2016-05-28. These products are the columns named:ind_(xyz)_ult1, which are the columns #25 - #48 in the training data. You will predict what a customer will buy in addition to what they already had at 2016-05-28.</p>
</blockquote>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="Federated-Learning-(Theorie)">Federated Learning (Theorie)<a class="anchor-link" href="#Federated-Learning-(Theorie)"> </a></h2><p><strong>Was ist Federated Learning?</strong></p>
<blockquote><p>Define $N$ data owners ${F1, ...FN }$, all of whom wish to train a machine learning model by consolidating their respective data ${D1, ...DN }$. A conventional method is to put all data together and use $D = D1 ∪ ... ∪ DN$ to train a model $M_{SUM}$ . A federated learning system is a learning process in which the data owners collaboratively train a model $M_{FED}$ , in which process any data owner $F_i$ does not expose its data $D_i$ to others. In addition, the accuracy of $M_{FED}$ , denoted as $V_{FED}$ should be very close to the performance of $M_{SUM}$ , $V_{SUM}$ . Formally, let $\delta$ be a non-negative real number, if
$$| V_{FED} − V_{SUM} | < \delta$$
we say the federated learning algorithm has $\delta$-accuracy loss. <a href="https://arxiv.org/abs/1902.04885">Yang, Federated Machine Learning:Concept and Applications (2019)</a></p>
</blockquote>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Grundsätzlich gibt es 3 Arten von Federated Learning.</p>
<p><strong>Horizontal Federated Learning</strong>
<img src="/community_learning/data/images/horizontal_federated_learning_graph.png" alt="Vertical Federated Learning" title="Vertical Federated Learning"></p>
<p><strong>Vertical Federated Learning</strong>
<img src="/community_learning/data/images/vertical_federated_learning.png" alt="Vertical Federated Learning" title="Vertical Federated Learning"></p>
<p><strong>Transfer Learning</strong>
<img src="/community_learning/data/images/transfer_learning.png" alt="Transfer Learning" title="Transfer Learning"></p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Ein Produktion Ready Federated Learning System müsste wie folgt aussehen. Doch das vorrangige Ziel ist es zu beweisen, dass wir bessere Ergebnisse erzielen, wenn Modelle gemeinsam trainiert werden, ohne dass ein Daten Austausch kommt. Deshalb wird in diesem PoC Federated Learning wie Distributed Maschine Learning Problem behandelt mit unterschiedlichen Data Owner.
<img src="/community_learning/data/images/horizontal_federated_learning.png" alt="federated learning" title="federated learning"></p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="Gradient-Boosting-Tree-(Bsp.-XGBoost)">Gradient Boosting Tree (Bsp. XGBoost)<a class="anchor-link" href="#Gradient-Boosting-Tree-(Bsp.-XGBoost)"> </a></h2>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Für die Umsetzung von Federated Learning verwenden wir XGBoost bzw. LightGBM. Beide sind Gradient Boosting Trees. Für all jene die einen refresher benötigen findet ihr <a href="https://www.youtube.com/watch?v=OtD8wVaFm6E">hier</a> ein paar sehr informative Youtube Videos. Im Wesentlichen besteht XGBoost aus einer Serie von Decision Trees. Dabei ist jeder Tree in Reihe geschaltet und versucht die Residuen vom vorherigen Tree zu minimieren. Stark vereinfacht funktioniert XGBoost wie folgt:</p>
<ul>
<li>berechne den Weighted Quantile Sketch: <ul>
<li>Hierzu wird lokal (in unserem Fall) die Distribution von jedem Feature berechnet und an den Parameterserver gesendet. </li>
<li>Dieser wiederum approximiert die globale Distribution von jedem Feature und gibt, vor welche Splits geprüft werden müssen. </li>
</ul>
</li>
<li>berechnen der Splits: Loakal werden nun die verschiedenen Splits berechnet für die verschiedenen Features. Die Resultate werden an den Parameterserver gesendet</li>
<li>globales Modell: Nun wird anhand der Resultate ein globales Model aufgebaut und an die lokalen Nodes verteilt.</li>
<li>nun wird mit Schritt 1 wieder begonnen.</li>
</ul>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="Machine-Learning-Problem">Machine Learning Problem<a class="anchor-link" href="#Machine-Learning-Problem"> </a></h2><p>Wie weiter oben beschrieben ist das Ziel die zusätzlich gekauften Produkte im Monat vom 2016-06-28 zu bestimmen. Die Daten beinhalten Monatsdaten von 2015-01-28 - 2016-05-28 (ca. 1.5 Jahre). Nun gäbe es mehrere Möglichkeiten das ML Problem zu formulieren:</p>
<ul>
<li>wir versuchen immer die gekauften Produkte des nächsten Monats zu bestimmen</li>
<li>wir versuchen immer die gekauften Produkte für den Juni jeweils anhand des Vormonats zu bestimmen (ignorieren alle anderen Monate). </li>
<li>wir trainieren ein Recommender System mit allen Daten der Produkte und versuchen den letzten Monat vorherzusagen.</li>
</ul>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Notebooks">Notebooks<a class="anchor-link" href="#Notebooks"> </a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="Notebooks-01_data_preprocess.ipynb-und-02_data_Cleaning.ipynb">Notebooks 01_data_preprocess.ipynb und 02_data_Cleaning.ipynb<a class="anchor-link" href="#Notebooks-01_data_preprocess.ipynb-und-02_data_Cleaning.ipynb"> </a></h2><p>In den Notebooks <strong>01_data_preprocess.ipynb</strong> und <strong>02_data_Cleaning.ipynb</strong> werden die Daten aufbereitet. Da dieses Datenset recht gross ist, werden zuerst alle Daten in integer umgewandelt. Das Ziel ist es Floats- und Character Daten möglichst zu vermeiden, da diese den DataFrame unnötig aufblähen. Im Notebook 02 wird noch bei einzelnen Features die Nans ein wenig "smarter" bereinigt.</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="Notebook-03_features.ipynb">Notebook 03_features.ipynb<a class="anchor-link" href="#Notebook-03_features.ipynb"> </a></h2><p>Das Notebook <strong>03_features.ipynb</strong> macht mehrere Dinge.</p>
<ul>
<li><strong>Zielvariablen:</strong> Das ML Problem lautet vorherzusagen, welche Produkte von einem Kunden im nächsten Monat zusätzlich erworben werden. Um dies festzustellen muss der aktuelle Monat mit dem Vormonat verglichen werden, um zu sehen ob ein neues Produkt erworben wurd.</li>
<li><strong>Produkt Features:</strong> Neben den vorhandenen Features, macht es natürlich Sinn auch die Produkte selbst als Features zu definieren. Z.B. Kreditkarte Vormonat: hatte der Kunde im Vormonat eine Kreditkarte ist das eine wichtige Info. </li>
<li><strong>reverse Dummy Variable:</strong> Es ist natürlich möglich, für jedes Produkt einen Boosting Tree zu trainieren. Allerdings ist das nicht effizient. Im Prinzip handelt es sich um eine Classification-Problem. Wir wollen die Top 7 Produkte vorhersagen, wenn wir für jedes Produkt einen Boosting Tree entwerfen fehlt die Vergleichbarkeit und wir können keine Rangordnung festlegen. Darum wurden alle Produkte in einer Zielvariable <code>y</code> gespeichert. Wenn nun ein Kunde 2 Produkte erworben hat in einem Monat, so hat dieser zwei Zeilen in diesem Monat anstatt vorher eine Zeile.</li>
<li><strong>entfernen der Daten ohne neuem Produkt:</strong> Ziel ist es die Top 7 Produkte vorzuschlagen. Daher macht es aus meiner Sicht keinen Sinn Einträge, ohne neuen Produkten, zu berücksichtigen zumal unsere Erfolg auch mit APK gemessen wird. </li>
<li><strong>Train Test Split:</strong>
Das Ziel dieser Kaggle Challenge ist es die neuen Produkte für die Periode 2016-06-28 vorherzusagen. Dazu haben sie das Datenset in ein Testset (Grunddaten von der Periode 2016-06-28) und Trainingset (Daten von 2015-01-28 bis 2016-05-28) aufgeteilt. Leider kennen wir die wahren Werte von dem Testset der Periode 2016-06-28 nicht, weshalb wir diesen Datenpunkt ignorieren werden und Train und Testset wie folgt aufteilen werden.
<img src="/community_learning/docs/images/train_test.png" alt="image.png"></li>
</ul>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="Notebook-04_base_model.ipynb">Notebook 04_base_model.ipynb<a class="anchor-link" href="#Notebook-04_base_model.ipynb"> </a></h2><p>In diesem Notebook wird ein Basismodel bestimmt und evaluiert.</p>
<ul>
<li><p><strong>Trainieren:</strong>
Hierzu wird ein Standard XGBoost Model hergenommen und trainiert. Die erzielten Resultate lassen sich mit denen auf Kaggle vergleichen.</p>
</li>
<li><p><strong>Evaluierung vom Testset:</strong></p>
<p>Für die <a href="https://www.kaggle.com/c/santander-product-recommendation/overview/evaluation">Evaluierung</a> wird der Mean Average Precision @ 7 (MAP@7) hergenommen. Die untenstehenden Formel haben wir uns von <a href="https://github.com/jturkewitz/SideProjects/blob/4c437b02d5e017636c84cc22eb3ff71f8eea1308/Kaggle/Santander_Prod/santander_prod.py#L272">jturkewitz</a> ausgeliehen. <a href="http://sdsawtelle.github.io/blog/output/mean-average-precision-MAP-for-recommender-systems.html">Hier</a> noch eine gute Erklärung.</p>
</li>
</ul>
$$
MAP@7 = \dfrac{1} {\vert U \vert} \sum^{\vert U \vert}_{u=1} \dfrac {1} {min(m,7)} \sum^{min(n,7)}_{k=1} P(k)
$$
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="Notebook-05_xgboost_simple_ensemble.ipynb">Notebook 05_xgboost_simple_ensemble.ipynb<a class="anchor-link" href="#Notebook-05_xgboost_simple_ensemble.ipynb"> </a></h2><ul>
<li><p><strong>Aufteilen der Daten</strong>
Um die Daten möglichst konsistent zu teilen, werden wir für jede Kundenid den ursprünglichen Wohnort ermitteln. Wenn nun ein Kunde die Region in dem Untersuchungszeitraum wechselt, so wird nur der ursprüngliche Wohnort ausgewertet. So können wir sicherstellen, dass wir keine Daten durch die Aufteilung verlieren. In dem Bild weiter unten sind die verschiedenen Regionen zu sehen. Wir werden versuchen Spanien in nördliche und südliche Regionen aufzuteilen.
<img src="/community_learning/data/images/spain.png" alt="image.png"></p>
</li>
<li><p><strong>Berechnung von einem Ensemble:</strong>
Nachdem wir die Daten in einen Region-Süd und in eine Region-Nord aufgeteilt haben. Trainieren wir jeweils ein Model mit den jeweiligen Daten.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h2 id="06_Distributed_ML.ipynb">06_Distributed_ML.ipynb<a class="anchor-link" href="#06_Distributed_ML.ipynb"> </a></h2><p>Hierfür baute ich einen Cluster aus drei Cotnainern welche mittels OpenMPI (Message Passing Library) miteinander kommunzieren. Hierfür musste LightGBM (MPI Version kompiliert werden). Der Cluster besteht aus 1 Head Node und 2 Compute Nodes. Der eine Node bekam die Daten von Region Süd und der andere von der Region Nord.</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Summary">Summary<a class="anchor-link" href="#Summary"> </a></h1>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Wir konnten feststellen, dass moderne Algorithmen wie XGBoost und LightGBM geeignet sind für Federated Learning. In der einfachsten Umstzung als Distributed Learning Algorithmen ergab sich jedoch kein eindeutiger Mehrwert. Dennoch bin ich überzeugt, das bei gewissen ML Modellen es durchaus Sinn macht die Daten zu teilen und einen Federated Learning Ansatz (Distributet Learning) zu wählen.</p>
<p>Obwohl in diesem Beispiel der Mehrwert nicht eindeutig ist, könnte ich mir einen Mehrwert bei Customer Churn vorstellen. Hierzu wäre z.B. <a href="https://www.kaggle.com/c/kkbox-churn-prediction-challenge/data">https://www.kaggle.com/c/kkbox-churn-prediction-challenge/data</a> oder <a href="https://www.kaggle.com/blastchar/telco-customer-churn">https://www.kaggle.com/blastchar/telco-customer-churn</a>.</p>
</div>
</div>
</div>
{% raw %}
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
<span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s1">'data/final/results_df.csv'</span><span class="p">,</span> <span class="n">index_col</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="n">df</span>
</pre></div>
</div>
</div>
</div>
<div class="output_wrapper">
<div class="output">
<div class="output_area">
<div class="output_html rendered_html output_subarea output_execute_result">
<div>
<style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>model_south</th>
<th>model_north</th>
<th>model_all</th>
<th>model_south_north_combine</th>
<th>distributed_lgbm_training</th>
</tr>
</thead>
<tbody>
<tr>
<th>test_south</th>
<td>0.026727</td>
<td>0.026502</td>
<td>0.026690</td>
<td>0.026649</td>
<td>0.026444</td>
</tr>
<tr>
<th>test_north</th>
<td>0.017951</td>
<td>0.018017</td>
<td>0.017983</td>
<td>0.018006</td>
<td>0.017836</td>
</tr>
<tr>
<th>test</th>
<td>0.023006</td>
<td>0.022904</td>
<td>0.022998</td>
<td>0.022984</td>
<td>0.022794</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="Offene-Fragen">Offene Fragen<a class="anchor-link" href="#Offene-Fragen"> </a></h1><p>-</p>
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<h1 id="How-to-use">How to use<a class="anchor-link" href="#How-to-use"> </a></h1>
</div>
</div>
</div>
</div>