diff --git a/CRM/Increase customer satisfaction/1Notebook.ipynb b/CRM/Increase customer satisfaction/1Notebook.ipynb index f245c97c15bff6b25c83c22cb51ffb203aac7955..6dc6588c23451fac7bd30da61344bedb4a47a630 100644 --- a/CRM/Increase customer satisfaction/1Notebook.ipynb +++ b/CRM/Increase customer satisfaction/1Notebook.ipynb @@ -1,7 +1,6 @@ { "cells": [ { - "attachments": {}, "cell_type": "markdown", "metadata": { "editable": true, @@ -13,7 +12,6 @@ "tags": [] }, "source": [ - "# 1. Business Understanding\n", "\n", "Aufgrund der großen Auswahl, die Netflix zu bieten hat, ist es für die Nutzer schwierig, geeignete Filme für sich zu finden. Die Suche in der Bibliothek nimmt viel Zeit in Anspruch und schafft ein schlechtes Nutzererlebnis, was wiederum zu höheren Abbruchquoten führt.\n", "Um die Abbruchquoten zu senken, muss geprüft werden, ob die Kundenzufriedenheit durch die Anwendung von maschinellem Lernen in Bezug auf Filmempfehlungen erhöht werden kann.\n", @@ -27,7 +25,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": { "editable": true, @@ -39,11 +36,84 @@ "tags": [] }, "source": [ - "# 2. Daten und Datenverständnis\n", "\n", "Aus dem Datensatz ist ersichtlich, dass sowohl Zahlen als auch kategoriale Werte enthalten sind. Jede Kategorie bezieht sich auf den entsprechenden Film in der Zeile. So enthält beispielsweise die Spalte \"Crew\" mehrere Mitwirkende wie Autoren, Filmeditor usw., während \"Cast\" die Schauspieler enthält, die in den jeweiligen Filmen mitspielen. Außerdem hat jeder Film eine eindeutige ID, z. B. movie_id/id, die identisch ist und es ermöglicht, beide Datensätze zu kombinieren. Alle Daten sind sehr verständlich und selbsterklärend, und der Inhalt ist auf kaggle.com ausdrücklich beschrieben." ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "editable": true, + "include": true, + "paragraph": "Evaluation", + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "Die Analyse des Datensatzes aus dem tmdb-Dataset zur Verbesserung der Filmempfehlungen auf Netflix legt nahe, \n", + "dass eine Vielzahl von Faktoren die Beliebtheit oder Bewertungen der Filme beeinflussen können.\n", + "Dazu gehören sowohl numerische als auch kategoriale Daten wie Crewmitglieder, Besetzung und eindeutige IDs. \n", + "Durch die Anwendung von maschinellem Lernen auf diese Daten können Strategien entwickelt werden, \n", + "um die Kundenzufriedenheit zu erhöhen und Abbruchquoten zu senken. \n", + "Eine gründliche Analyse und Modellierung dieser Faktoren ermöglicht es, personalisierte Empfehlungen zu generieren \n", + "und das Nutzererlebnis zu verbessern. Das Fazit dieser Umsetzung ist, dass die Daten eine solide Grundlage bieten, \n", + "um innovative Lösungen zur Filmempfehlung zu entwickeln, die die Zufriedenheit der Netflix-Nutzer steigern können." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "editable": true, + "include": true, + "paragraph": "Umsetzung", + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "Um die Abbruchquoten bei Netflix zu senken und die Kundenzufriedenheit zu steigern, können maschinelles Lernen und Datenanalyse genutzt werden, um relevante Faktoren wie Crewmitglieder, Besetzung und Genre zu identifizieren und ein Modell zu trainieren, das die Beliebtheit oder Bewertungen von Filmen vorhersagt,\n", + "was zu personalisierten Empfehlungen führt." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "editable": true, + "include": true, + "paragraph": "Daten", + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# 2. Data Understanding " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "editable": true, + "include": true, + "paragraph": "Business", + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# 1. Business Understanding" + ] + }, { "attachments": {}, "cell_type": "markdown", @@ -1026,6 +1096,13 @@ "original_data.isnull().sum()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code entfernt alle Zeilen im DataFrame original_data, die mindestens einen fehlenden Wert (NaN) enthalten, und speichert das Ergebnis in df_wo_null." + ] + }, { "cell_type": "code", "execution_count": 9, @@ -1035,6 +1112,13 @@ "df_wo_null = original_data.dropna(axis=0)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code gibt für jeden Spaltennamen im DataFrame df_wo_null die Anzahl der fehlenden Werte (NaN) zurück." + ] + }, { "cell_type": "code", "execution_count": 10, @@ -1092,6 +1176,13 @@ "### Auf Duplikate prüfen" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code filtert den DataFrame df_wo_null und gibt alle Zeilen zurück, die Duplikate enthalten, wobei alle Vorkommen der Duplikate beibehalten werden." + ] + }, { "cell_type": "code", "execution_count": 11, @@ -1308,6 +1399,13 @@ "## 2.5 Deskriptive Analysise " ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code df_wo_null = df_wo_null.drop(['status', 'original_title', 'overview'], axis=1) entfernt die Spalten status, original_title und overview aus dem DataFrame df_wo_null." + ] + }, { "cell_type": "code", "execution_count": 15, @@ -1317,6 +1415,13 @@ "df_wo_null = df_wo_null.drop(['status', 'original_title', 'overview'], axis = 1)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code entfernt die Spalten production_countries, original_language, crew und spoken_languages aus dem DataFrame df_wo_null." + ] + }, { "cell_type": "code", "execution_count": 16, @@ -1326,6 +1431,13 @@ "df_wo_null = df_wo_null.drop(['production_countries', 'original_language', 'crew', 'spoken_languages'], axis = 1)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code entfernt die Spalten runtime, keywords, vote_average und budget aus dem DataFrame df_wo_null." + ] + }, { "cell_type": "code", "execution_count": 17, @@ -1512,6 +1624,13 @@ "## 3.1 Erfassung kategorialer Variablen" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code teilt die Zeichenfolgen in der Spalte genres von df_wo_null anhand des Kommas (,) auf und speichert das zweite Element (Index 1) der resultierenden Liste in der neuen Spalte genre1." + ] + }, { "cell_type": "code", "execution_count": 19, @@ -1521,6 +1640,13 @@ "df_wo_null['genre1'] = df_wo_null['genres'].str.split(',').str[1]" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code teilt die Zeichenfolgen in der Spalte genre1 von df_wo_null anhand des Doppelpunkts (:) auf und speichert das zweite Element (Index 1) der resultierenden Liste wieder in der Spalte genre1." + ] + }, { "cell_type": "code", "execution_count": 20, @@ -1530,6 +1656,13 @@ "df_wo_null['genre1'] = df_wo_null['genre1'].str.split(':').str[1]" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code nimmt den Inhalt der Spalte genre1 im DataFrame df_wo_null, teilt ihn anhand des Anführungszeichens (\") auf und speichert das zweite Element (Index 1) der resultierenden Liste zurück in der Spalte genre1." + ] + }, { "cell_type": "code", "execution_count": 21, @@ -1539,6 +1672,13 @@ "df_wo_null['genre1'] = df_wo_null['genre1'].str.split('\"').str[1]" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code extrahiert das vierte Element (Index 3) aus der durch Kommas getrennten Liste von Genres in der Spalte genres des DataFrames df_wo_null und speichert es in der neuen Spalte genre2." + ] + }, { "cell_type": "code", "execution_count": 22, @@ -1548,6 +1688,13 @@ "df_wo_null['genre2'] = df_wo_null['genres'].str.split(',').str[3]" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code teilt die Zeichenfolgen in der Spalte genre2 von df_wo_null anhand des Doppelpunkts (:) und speichert das zweite Element (Index 1) der resultierenden Liste wieder in der Spalte genre2." + ] + }, { "cell_type": "code", "execution_count": 23, @@ -1557,6 +1704,13 @@ "df_wo_null['genre2'] = df_wo_null['genre2'].str.split(':').str[1]" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code teilt die Zeichenfolgen in der Spalte genre2 von df_wo_null anhand des Anführungszeichens (\") und speichert das zweite Element (Index 1) der resultierenden Liste wieder in der Spalte genre2." + ] + }, { "cell_type": "code", "execution_count": 24, @@ -1566,6 +1720,13 @@ "df_wo_null['genre2'] = df_wo_null['genre2'].str.split('\"').str[1]" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code entfernt die Spalte genres aus dem DataFrame df_wo_null und speichert das Ergebnis in df_1." + ] + }, { "cell_type": "code", "execution_count": 25, @@ -1686,6 +1847,13 @@ "df_2.isnull().sum()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code entfernt alle Zeilen aus dem DataFrame df_2, die mindestens einen fehlenden Wert enthalten, und speichert das bereinigte DataFrame wieder in df_2." + ] + }, { "cell_type": "code", "execution_count": 30, @@ -1695,6 +1863,13 @@ "df_2 = df_2.dropna(axis=0)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code extrahiert das Jahr aus der Spalte release_date im DataFrame df_2, indem er die Zeichenfolge an den Bindestrichen trennt und das erste Element (Index 0) der resultierenden Liste in der neuen Spalte year speichert." + ] + }, { "cell_type": "code", "execution_count": 31, @@ -1705,20 +1880,20 @@ ] }, { - "cell_type": "code", - "execution_count": 32, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "df_2['year'] = df_2['year'].astype(int)" + "Der Code wandelt die Werte in der Spalte year des DataFrames df_2 in Ganzzahlen (Integer) um." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 32, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "df_2['year'] = df_2['year'].astype(int)" + ] }, { "cell_type": "code", @@ -1771,6 +1946,13 @@ "df_2.info()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code entfernt die Spalte release_date aus dem DataFrame df_2 und speichert das bereinigte DataFrame in df_3." + ] + }, { "cell_type": "code", "execution_count": 34, @@ -2026,6 +2208,13 @@ "df_3" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code extrahiert das sechste Element (Index 5) aus der durch Kommas getrennten Liste in der Spalte 'cast' des DataFrames df_3 und speichert es zurück in der Spalte 'cast'." + ] + }, { "cell_type": "code", "execution_count": 36, @@ -2035,6 +2224,13 @@ "df_3['cast'] = df_3['cast'].str.split(',').str[5]" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code teilt die Zeichenfolgen in der Spalte 'cast' des DataFrames df_3 anhand des Doppelpunkts (:) auf und speichert das zweite Element (Index 1) der resultierenden Liste zurück in der Spalte 'cast'." + ] + }, { "cell_type": "code", "execution_count": 37, @@ -2044,6 +2240,13 @@ "df_3['cast'] = df_3['cast'].str.split(':').str[1]" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code teilt die Zeichenfolgen in der Spalte 'cast' des DataFrames df_3 anhand des Anführungszeichens (\") auf und speichert das zweite Element (Index 1) der resultierenden Liste zurück in der Spalte 'cast'." + ] + }, { "cell_type": "code", "execution_count": 38, @@ -2053,6 +2256,13 @@ "df_3['cast'] = df_3['cast'].str.split('\"').str[1]" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code teilt die Zeichenfolgen in der Spalte 'production_companies' des DataFrames df_3 anhand des Kommas (') auf und speichert das erste Element (Index 0) der resultierenden Liste zurück in der Spalte 'production_companies'." + ] + }, { "cell_type": "code", "execution_count": 39, @@ -2062,6 +2272,13 @@ "df_3['production_companies'] = df_3['production_companies'].str.split(',').str[0]" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code teilt die Zeichenfolgen in der Spalte 'production_companies' des DataFrames df_3 anhand des Doppelpunkts (:) auf und speichert das zweite Element (Index 1) der resultierenden Liste zurück in der Spalte 'production_companies'." + ] + }, { "cell_type": "code", "execution_count": 40, @@ -2071,6 +2288,13 @@ "df_3['production_companies'] = df_3['production_companies'].str.split(':').str[1]" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code teilt die Zeichenfolgen in der Spalte 'production_companies' des DataFrames df_3 anhand des Anführungszeichens (\") auf und speichert das zweite Element (Index 1) der resultierenden Liste zurück in der Spalte 'production_companies'." + ] + }, { "cell_type": "code", "execution_count": 41, @@ -2309,6 +2533,13 @@ "df_5.head()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code benennt die Spalte 'cast' in 'star' im DataFrame df_5 um und speichert das Ergebnis in df_6." + ] + }, { "cell_type": "code", "execution_count": 45, @@ -2464,6 +2695,13 @@ "df_6.head()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code entfernt die Spalte 'year' aus dem DataFrame df_6 und speichert das bereinigte DataFrame in df_7." + ] + }, { "cell_type": "code", "execution_count": 47, @@ -2473,6 +2711,13 @@ "df_7 = df_6.drop(['year'], axis = 1)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code entfernt alle Zeilen aus dem DataFrame df_7, die mindestens einen fehlenden Wert enthalten, und speichert das bereinigte DataFrame in df_cleaned." + ] + }, { "cell_type": "code", "execution_count": 48, @@ -2589,6 +2834,13 @@ "sns.distplot(df_cleaned['popularity'])" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code berechnet das 99. Perzentil (Quantil) der Spalte 'popularity' im DataFrame df_cleaned und erstellt dann data_1, einen neuen DataFrame, der nur die Zeilen aus df_cleaned enthält, deren 'popularity' kleiner als dieses 99. Perzentil ist." + ] + }, { "cell_type": "code", "execution_count": 51, @@ -2656,6 +2908,13 @@ "sns.distplot(data_1['popularity'])" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code berechnet das 1. Perzentil (Quantil) der Spalte 'vote_count' im DataFrame data_1 und erstellt dann data_2, einen neuen DataFrame, der nur die Zeilen aus data_1 enthält, deren 'vote_count' größer als dieses 1. Perzentil ist." + ] + }, { "cell_type": "code", "execution_count": 53, @@ -2908,6 +3167,13 @@ "data_3.hist(figsize=(25,25), bins=50)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code setzt den Index des DataFrame data_3 zurück und speichert das Ergebnis in data_final, wobei der alte Index verworfen wird." + ] + }, { "cell_type": "code", "execution_count": 58, @@ -2917,6 +3183,13 @@ "data_final = data_3.reset_index(drop=True)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code wandelt die Werte in der Spalte revenue des DataFrames data_final in Fließkommazahlen (float) um." + ] + }, { "cell_type": "code", "execution_count": 59, @@ -3083,7 +3356,7 @@ "Die Tabelle gibt statistische Zusammenfassungen über die Merkmale \"Popularität\", \"Produktionsunternehmen\", \n", "\"Einnahmen\", \"Titel\", \"Stimmenanzahl\", \"Hauptdarsteller\" und \"Genres\" von Filmen an, \n", "einschließlich Anzahl der Datensätze, eindeutiger Werte, häufigster Wert, Mittelwerte, \n", - "Standardabweichungen, und Quartile.\n" + "Standardabweichungen, und Quartile." ] }, { @@ -3687,6 +3960,13 @@ "data_final.describe(include='all')" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code erstellt Dummy-Variablen für kategorische Variablen im DataFrame data_final, wobei die erste Kategorie jeder Variable entfernt wird, und speichert das Ergebnis in data_with_dummies." + ] + }, { "cell_type": "code", "execution_count": 69, @@ -3959,6 +4239,13 @@ "data_with_dummies.head()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Der Code teilt den DataFrame data_with_dummies in zwei Teile auf: target enthält die Spalte 'popularity', die als Zielvariable verwendet wird, während predictors den Rest des DataFrames umfasst, bei dem die Spalte 'popularity' entfernt wurde und daher als Vorhersagevariablen fungiert." + ] + }, { "cell_type": "code", "execution_count": 71, @@ -4115,13 +4402,6 @@ "und visualisiert die Ergebnisse durch Diagramme und Streudiagramme mit einer Regressionslinie.\n" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": 76, @@ -4176,30 +4456,6 @@ "# 5 Evaluation " ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "editable": true, - "include": true, - "paragraph": "Evaluation", - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "Die Analyse des Datensatzes aus dem tmdb-Dataset zur Verbesserung der Filmempfehlungen auf Netflix legt nahe, \n", - "dass eine Vielzahl von Faktoren die Beliebtheit oder Bewertungen der Filme beeinflussen können.\n", - "Dazu gehören sowohl numerische als auch kategoriale Daten wie Crewmitglieder, Besetzung und eindeutige IDs. \n", - "Durch die Anwendung von maschinellem Lernen auf diese Daten können Strategien entwickelt werden, \n", - "um die Kundenzufriedenheit zu erhöhen und Abbruchquoten zu senken. \n", - "Eine gründliche Analyse und Modellierung dieser Faktoren ermöglicht es, personalisierte Empfehlungen zu generieren \n", - "und das Nutzererlebnis zu verbessern. Das Fazit dieser Umsetzung ist, dass die Daten eine solide Grundlage bieten, \n", - "um innovative Lösungen zur Filmempfehlung zu entwickeln, die die Zufriedenheit der Netflix-Nutzer steigern können." - ] - }, { "cell_type": "code", "execution_count": null, @@ -4216,28 +4472,13 @@ "source": [ "# 6 Umsetzung " ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "editable": true, - "include": true, - "paragraph": "Umsetzung", - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "Um die Abbruchquoten bei Netflix zu senken und die Kundenzufriedenheit zu steigern, können maschinelles Lernen und Datenanalyse genutzt werden, um relevante Faktoren wie Crewmitglieder, Besetzung und Genre zu identifizieren und ein Modell zu trainieren, das die Beliebtheit oder Bewertungen von Filmen vorhersagt,\n", - "was zu personalisierten Empfehlungen führt." - ] } ], "metadata": { + "branche": "Medien", "category": "CRM", + "dataSource": "https://www.kaggle.com/tmdb/tmdb-movie-metadata", + "funktion": "Marketing", "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", @@ -4253,10 +4494,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.2" + "version": "3.9.2" }, + "repoLink": "https://gitlab.reutlingen-university.de/ki_lab/machine-learning-services/-/tree/main/CRM/Increase%20customer%20satisfaction?ref_type=heads", "skipNotebookInDeployment": false, - "title": "Increase customer satisfaction" + "teaser": "Entdecken Sie, wie maschinelles Lernen die Filmempfehlungen bei Netflix verbessern könnte. Wir analysieren Filmdaten aus dem tmdb Dataset, um herauszufinden, welche Faktoren die Beliebtheit und Bewertungen beeinflussen. Optimieren Sie mit uns die Nutzererfahrung und senken Sie die Abbruchquoten auf der Plattform.", + "title": "Erhöhung der Kundenzufriedenheit" }, "nbformat": 4, "nbformat_minor": 4