# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     name: python3
# ---

# + [markdown] id="view-in-github" colab_type="text"
# <a href="https://colab.research.google.com/github/JasperLS/data_science_intros/blob/main/Data_Science_for_Customer_Insights_Python_Introduction_Course.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>

# + [markdown] id="5fCEDCU_qrC0"
# #Data Science for Customer Insights - Python Introduction Course
#
# Welcome to Data Science for Customer Insights. In the following tasks, you will learn how to do Data Science with Python. In the end, you will be able to: 
#
# - do basic coding and use Python loops, lists, functions and more
# - access and apply machine learning algorithms to data sets
# - understand fundamental machine learning concepts
#
# Please go trough all tasks and answer the questions carefully. **This is task-based learning - you will have to Google a lot**. You can use any credible source material, you like, e.g.: 
#
# - stackoverflow
# - SoloLearn
# - DataCamp
# - udemy
#
# Again - you will potentially have to Google everything, this is normal!
#
# Also, every time you see those signs "**...**" you have to change them to generate the correct code. 
#

# + [markdown] id="UQWo_jfy4H9s"
# **Before you start: Please provide your information**
#
# Name:
#
# Matr.:

# + [markdown] id="GJBs_flRovLc"
# ##First Steps
#  

# + [markdown] id="p4NFErGadias"
# **Print Function**
#
# By using the print statement, we're able to output text. 
#
# *Please run the following code*:

# + id="gJr_9dXGpJ05"
print ('Hello World')

# + [markdown] id="L3qFPIIqrc77"
# <img src="https://miro.medium.com/max/1250/1*iNw33pBEYZIAoE9oHdhLLw.jpeg" width=500 height=330>

# + [markdown] id="2fhs6GZ4qFMx"
# <strong>Basic Operations</strong>
#
# With Python, you can easily do some calculations. 
#
# *Tap around to perform an addition with a result of 5:*

# + id="c6i-78HEXGNu"
3 

# + [markdown] id="0DsykyJTXNao"
# *Try to print a substraction with 7 as a result:*
#
#

# + id="B3fhbNoMXLuf"
10

# + [markdown] id="8QlK460xXJqJ"
# *Use parantheses to determine which operations are performed first - try to get 30:*

# + id="-gE-Ez1qtyIA"
3*4+6

# + [markdown] id="bX2Xoej0WmJn"
# *Try to divide by 2 to get a result of 2.00*
#
# **<strong><font color='blue'> Side Note:** we call 2.00 a float variable, while 2 is called an integer variable. Despite seemingly being the same, Python sees them as different datatypes which for example leads to differnt memory needs.</font></strong>

# + id="4ty9qsqVWVq7"
4

# + [markdown] id="lSrWNr3MuFUS"
# The minus sign symbolizes a negative number which has no effect on how to perform an operation with them. 
#
# *Tap around and try to get a positive result of 48!*

# + id="WgHrAlz6ZTB-"
(-3+-1)*(12)

# + [markdown] id="Wt_Y_ZWA9miH"
# **Comments**
#
# You can comment your code, to explain something for later reference.
#
# *Please turn "This is just a comment" into a proper comment.*

# + id="ssxN9tka9-2o"
4 + 4
This is just a comment

# + [markdown] id="4i-XuhKW3owN"
# **Storing Values**
#
# You can store values in variables.
#
# *Please complete the code to generate 42 as an output.*

# + id="T29nLva63oG7"
... = 21

... = ... * ...

print(...)

# + [markdown] id="Jhy8suwbZtde"
# **ZeroDivisionError**
#
# Dividing by zero produces an error, as no answer can be calculated. 
#
# *You don't believe that? Tap around and divide 3 by zero.*

# + id="ghD_v1QJaWhM"


# + [markdown] id="8bPzVa96a-zX"
# **Other numerical Operations**
#
# You can also use Python for exponentiation or the quotient and remainder of a division.
#
# *Perform an exponentiation with a result of 32:*

# + id="vHWTZFAsbnrU"
2

# + [markdown] id="e0KghhEMdLLP"
# *Try to get the remainder of the division 1.25 by 0.5 (should be 0.25):*

# + id="cKOpQ-2ebvmM"


# + [markdown] id="OSqSFbg6jRw7"
# ##Data Types

# + [markdown] id="KA7WEmmTjbRl"
# If Python handles data, it has to somehow turn it into 1s and 0s. Depending on the type of data, Python uses different internal representations. It is therefore very important, to always make sure your data has the right data type.

# + [markdown] id="fxXZEWORXump"
# **Integers**
#
# Integers are whole numbers like: 
#
# - 5 
# - 3
#

# + [markdown] id="SpL66XSAV3PW"
# **Floats**
#
# Numbers that aren't integers are represented as floats in Python ("a floating point number"). Some examples are: 
# - 0.8
# - -5.346
#
# How to create a float? 
# By entering a number with a decimal point, or by using operations such as division on integers as well as operations on a float and an integer.
#
# *Please build a float dividing 12 by 4 and try to convert it back into an integer (should be 3 not 3.0):*

# + id="pN81xZjUXB5Z"
# create float
print()
# turn it into an integer
print()

# + [markdown] id="VprZLg-EY5s-"
# **Strings**
#
# You have to use a string if you want to use text in Python. It's one of the basic things that store text like: 
#
# - Python is fun
# - I love Data Science
#
# How to create a string? By entering text between two single or double quotation marks.
#
# *Run the code to create a string:*

# + id="98w-iUSGZ6ko"
"Python is fun"

# + [markdown] id="JX8ScvvleqQO"
# *Try to print I love Data Science using single marks.*

# + id="lt-l5lUJaBfd"


# + [markdown] id="VeQ8nTgbbyur"
# *What's wrong with the following string? Please correct it so that the type is 'str' and there is no error message!*

# + id="zFxpt_tYaiPd"
type('Lisa's brother likes good food.')

# + [markdown] id="IgVEuFwsb2hE"
# *Please change the following sentences to bring the second sentence in the second line:*

# + id="_TdTOOA1cC7c"
print ('Lisa likes good food. In the future, he wants to open a restaurant.')

# + [markdown] id="We12AcbmdcPU"
# **Booleans&Comparisons**
#
# You've already learned about integers, floats and strings. In Python, another type is the Boolean type. It has two values: True and False. By comparing values (using the equal operator ==), you can create Booleans. 
#
# *Please define my_boolean as True:*  

# + id="S7bs7aEXgjML"
my_boolean = 
print(my_boolean)

# + [markdown] id="G-Uv7DJigzb9"
# *Please compare two numbers and see if you get the "True" statement:*

# + id="As8PeDsQnU3P"


# + [markdown] id="61liw4eOhy2i"
# *Is "hi" equal to "hello"? Try it out!*

# + id="0srfVv0vnmYr"
"hi" ... "hello"

# + [markdown] id="6c-qfGoloEBC"
# The not equal operator (!=) is another comparison operator. 
#
# *Please run the code:*

# + id="zFYUiLPWoLFX"
3!=3

# + [markdown] id="siEObqC2iNHa"
# *Please generate a True statement using the operator:*

# + id="owFd0uatoOFn"
... != ...

# + [markdown] id="crYwcDotoYtw"
# In Python, you can also use operators (> and <) to determine whether one number (float or integer) is smaller than or greater than another.
#
# *Tap around (change the ...) and generate one True as well as one False statement:*

# + id="RV-FHVego3uL"
24 ... 16

# + id="KPY852q_o9rJ"
6 ... 6.0

# + [markdown] id="agDDzvQlrHxO"
# **<strong><font color='blue'> Side Note: In the first lessons you've learned about the basic operations in Python. To be better prepared for the following steps, the table below provides a summary: </font></strong>**
#
# <img src="https://i1.wp.com/makemeanalyst.com/wp-content/uploads/2017/06/Assignment-Operator.png?resize=590%2C426" width=500 height=300>

# + [markdown] id="UdRyKR44dcNI"
# ##Control Structures
#

# + [markdown] id="AX8KEqV7d2jR"
# **if&else statement**

# + [markdown] id="hdtFz5UXptLZ"
# <img src="https://www.tutorialspoint.com/python/images/if_else_statement.jpg" width=300 height=300>
#
# *Now it's your turn! Change the following code (...) to generate "else":*

# + id="E6xzkR1ukfO0"
if 2 + ... == 4 ...
  if 3 * ... == 9 ...
    print ("if")
  else: 
    print ("else")

# + [markdown] id="datsEgDB4iXQ"
# **<strong><font color='blue'> Side Note:**  Indentations are very important in Python, as they structure your code. </font></strong>
#
# <img src="https://i.redd.it/wk843smkri441.jpg" width=500 height=300>

# + [markdown] id="40mdnbNieJTh"
# **Boolean Logic**
#
# Boolean Logic is used to make more complicated conditions for if statements that rely on more than one condition. The Boolean operators are **and, or and not**. 

# + [markdown] id="OdysNNSonWA0"
# *Tap around to get a false statement:*

# + id="7htGUSgym9KX"
print ( 2 < 3 and 2 ... 6 )

# + [markdown] id="dHpbmcEBn_34"
# *Change and correct the following code to print "Hi":*

# + id="XlAjNuIqoKgs"
age = ... 
money = 400 
if age > 20 ... money > 50 ...
  ...("Hi"...

# + [markdown] id="0JOau1ITeOBp"
# **Lists**
#
# Lists are used to store multiple items. By using square brackets with commas separating items, you can create a list. 
#
# *Try to print the first argument of the list ("Hello").*

# + id="zjovDwhNlYFn"
words =  ["Hello", "world", "!"]
print (words...)

# + [markdown] id="F8VgN4fgrdDZ"
# *Change the code to create a list and print its 3rd element:*

# + id="d5rWZJjOrgwC"
the_list = ... 33, 66, 99 ...
...(the_list[...])

# + [markdown] id="UEmilTRFecFV"
# **Loops**
#
# A for loop is used to repeat a block of code multiple times. It is common to use the for loop when the number of iterations is fixed (e.g. iterating over a fixed list of items in a shopping list), but there are other loops as well.
#
# *Change the code below to print all elements of your list:*

# + id="hrSVVOz2Uzm9"
your_list = ['a','b','c','d']

for ... ... ... :
  print (...)

# + [markdown] id="QOEUQc1SVzqh"
# *Please change the ... to correct the code so that the loop is broken after the loop reaches the 'c' in your list.*

# + id="kYHdF1AVlZYy"
for item ... your_list: 
  print(item)
  if item ... ...: 
    print ("Breaking")
    ... 

print("Finished")

# + [markdown] id="hDqpOb_IXfK0"
# What's wrong with the following code? 
# *Please find the correct code to count all the 't' letters in the string. ATTENTION, you have to correct multiple errors and may need to change pre-written code.*

# + id="if61RplmXxGC"
str = "testing for loops to count 't's"
count = 0 

for ... in str: 
  if ... == 't' :
    count ... = 1

print (count) 

# + [markdown] id="XBlj6_t8efo8"
# **Range**
#
# The range() function returns a sequence of numbers. By default, it starts from 0, increments by 1 and stops before the specified number. 
#
# *The code below should generate a list containing all of the integers, up to 10 (not incl.). Please change the following code (...):*

# + id="jeR4mJGUlad7"
numbers = list(...(10))

print(...)

# + [markdown] id="cLKi_bFvDN8K"
# *Now change the code below to print every even number from 10 to 19 using range:*

# + id="TjGtMu2hDOz6"
numbers = list(...)

print(...)


# + [markdown] id="OwuxHmxllTwN"
# ##Functions & Modules

# + [markdown] id="EMtDBH2Xe6kR"
# **Functions**
#
# In addition to using pre-defined functions like range() or print(), you can create your own functions by using the def statement. You have to define functions before they are called! This is especially useful, if you want to do similar operations again and again.
#
# *Try for yourself and build a function "quattro_hello" which prints "hello" four times.*
#

# + id="pHnpri3gHXV8"
def ...:
  # build a proper loop to print your output four times 
  print (...)



# + [markdown] id="aDR8mvcz-q1e"
# *Now call your function and see if it prints 'hello' three times:*

# + id="Z8N9zB0V8jq7"
quattro_hello()


# + [markdown] id="mzUjE-zrHiu6"
# It is also possible to define a function that takes an argument. 
#
# *Please change the following code to build a function that prints a given text and adds a question mark:*
#
#

# + id="3qJbedzsHyTE"
def hello_function ():
  print (... + "?")

hello_function("HI")
hello_function("...")


# + [markdown] id="K5e3PBnT9G0o"
# **<strong><font color='blue'> Side Note:**  Python can take any form of object as input to a function AND (almost) everything in Python is an object !! </font></strong>
#
#
#
#
#
# <img src="https://miro.medium.com/max/625/1*mPpNrH_b3DEd0HiljDqMkw.png" >
#
#

# + [markdown] id="V5kSE42tJNkw"
# *And 2 arguments (develop a code to get a result of 16):*

# + id="tNiEftMNJzDD"
def print_sum(...,...):
  print(... + ...)

print_sum(6,11)

# + [markdown] id="oMgTXZFfK94l"
# *Fill in the ... to define a function that takes two arguments and prints their multiplication:*

# + id="8xBfautGKOid"
... print_mult(x,y)...
  print(x * ... )
...(2,2)


# + [markdown] id="-caDGUcZLO9j"
# *Fill in the ... to define a function that prints whether the first given paramter is greater or equal than the second paramter - or not:*

# + id="OixS1ZvgAPJk"
def compare(x, y):
  if ...:
    print(...)
  else:
    print(...)

print(compare(...,...))

# + [markdown] id="lks5vCIQgFBR"
# **Modules & Libraries**
#
# Modules refer to a file containing Python functions. A file containing Python code, for example: example.py, is called a module, and its module name would be example. The basic way to use a mdule is to add import *some_module_name* at the top of your code, and then using *some_module_name*.var to access functions and values with the name var in the module. This allows you to access complex functions programmed by other people.
#  
#

# + [markdown] id="SV5FevBtl459"
# *Please import a fitting module and generate 5 random numbers from the interval [0,10):*

# + id="R1892agsAnxy"
import ...

for i in range(5): 
  value = ...
  print(value)

# + [markdown] id="pvTTfdOUm96f"
# *Please import only the pi constant from the respective module and print pi:*

# + id="Mfxt3G-Ym-wd"
from ... import ...

print(...)

# + [markdown] id="wFCVUGx_Bqef"
# <img src ="https://i.redd.it/37xqk9umycn31.jpg" width=500 height=400>

# + [markdown] id="SpnHNXNvUVUY"
# **Pip Install**
#
# pip is a package management program for Python packages from the Python Package Index (PyPI). It allows you to install and manage software packages written in Python. Basically, it lets you install different modules.
#
# Before you learn how to install and import packages, the first step would be to actually make sure you've the correct Python verison installed in your system. 
#
# *Fill in the ... to check this and the version installed:* 

# + id="UhimRI0A1QJ1"
# !python ... v

# + [markdown] id="LZsAOsGNt6t2"
# *Please correct the following code to install the scenedetect package:*

# + id="sezVDvVCA9HX"
import scenedetect # are you able to import the package?

# + id="ovmkymv7unbc"
... scenedetect

# + id="dzrXbT3YBGNV"
import scenedetect # you should be able to import it now!

# + [markdown] id="qs52gjw6uzY8"
# Uninstalling/removing a package is very easy with pip. 
#
# *Please uninstall scenedetect again:*

# + id="1G_MJA3_vNuN"
pip ...

# + [markdown] id="-Rh3-Vt9Nev9"
# ##Exceptions

# + [markdown] id="1RR8qzFXgkJh"
# **Exception and Exception Handling**

# + [markdown] id="qQamrW33vP7o"
# Exception is an event that occurs due to incorrect code or input. 
#
# *Please generate a zero devision error:*

# + id="Dr5Bfn-ev_FC"


# + [markdown] id="7EcpGATAv_-m"
# *Please create a NameError:* 

# + id="VDMdlsJcxItH"


# + [markdown] id="CjSKE_T4xJO-"
# *Please generate a TypeError:*

# + id="WNVtpN4mxSPV"


# + [markdown] id="4pz8WKMMxWZf"
# *Please create a ValueError:*

# + id="4PdQE07HCnBS"


# + [markdown] id="RjaaEpTMyB-y"
# To handle exceptions, and to execute further code despite occuring errors, you can use a try/except statement. 
#
# *Please change the following code to print "an error occured - but the interpreter continued":*

# + id="N7fSjbYFye3c"
try:
  num1 = 7
  num2 = 0
  print(...)
  print("calculation done")
except:
  print ("an error occured - but the interpreter continued")

# + [markdown] id="SSSAZzFFD3dW"
# <img src ="https://img.devrant.com/devrant/rant/r_1200037_6jt6c.jpg" width=500 height=300>

# + [markdown] id="KJxnVSYyVPOt"
# ##Data Science Modules

# + [markdown] id="8pFuDtAcVWWE"
# **Numpy**
#
# *Please fill in the ... to learn more about Numpy:*
#

# + [markdown] id="Q4KPTtl2OtfM"
# NumPy is a program library for the programming language Python. NumPy extends Python with **...** for scientific computing and **...** calculations. The library enables efficient computing with  vectors, **...** and multidimensional **...**.

# + [markdown] id="A1yba1TJbiNI"
# *Please import Numpy as np:* 

# + id="BENNc8B4T2rb"
import ... as ... 

# + [markdown] id="rRYIaE6Tb0WF"
# *Please define a list 'cvalues' with different temperatures:*

# + id="2eHWb-Dyb9b5"
 ... = [20.1, 20.8, 21.9, 22.5, 22.7, 
           21.8, 21.3, 20.9, 20.1]

# + [markdown] id="GB0td9p2w5Au"
# *From our list 'cvalues' we now create a one-dimensional NumPy array, so please change the following code:*

# + id="16eyb_-TcC1J"
C = np. ... (cvalues)
print (C, type(C))

# + [markdown] id="ti-xqhLVxUk9"
# *Now let us assume that we need the values in degrees Fahrenheit instead of degrees Celsius.
# This can be done very easily with a NumPy array. The solution of our problem are simple scalar operations. Let's do this:*

# + id="XR28FF30cWOL"
print(...)

# + [markdown] id="qFIvnXHOyEZC"
# *Please find out what the shape of 'C' is:*

# + id="5qqmqIrvdYWP"


# + [markdown] id="wL-SPKbVE9fD"
# *Try to create a numpy array with the shape 4x2 (4 rows, 2 columns), containing only zeros*

# + id="Ldf8EhxHE8v6"


# + [markdown] id="w_wm9FcxVd8T"
# **Pandas**
#
# pandas is a program library for the Python programming language that provides tools for data management and analysis. In particular, it contains data structures and operators for accessing tables and time series.
#
#

# + [markdown] id="cMs0xplyHutE"
# *Please import pandas as pd and check the version:*

# + id="EvlvkfJvH8NK"
import pandas as pd
print(pd.__ ... __)

# + [markdown] id="mRYZ8zxhIvMV"
# *Create a pandas series from a list with strings, a numpy array with integers and a dictionary with the combination of your list and your numpy array:*

# + id="pzGh2XV4oIAZ"
# Inputs
import pandas as pd
import numpy as np
mylist = ...
myarr = ...
mydict = ...(...(mylist, myarr))

# Solution
ser1 = pd.Series(mylist)
ser2 = pd.Series(myarr)
ser3 = pd.Series(mydict)
print(ser1.head())
print(ser2.head())
print(ser3.head())

# + [markdown] id="LJ3KXj28sUCS"
# **<strong><font color='blue'> Side Note:** Note that a Pandas Series consists of an index (left column) and values (right column). This is important for accessing values.</font></strong>

# + [markdown] id="4WXvLc8CJJ6O"
# *Now create a 4x4 DataFrame with random integer values:*
#
# ---
#
#

# + id="N8PIWzFpJoLI"
# create a numpy 4x4 numpy matrix with random integer values
myarr = (np. ... (4,4)*10). ... .astype(int)

df = ...(myarr)
print(df)

# + [markdown] id="ppVXphb1Le4l"
# Let's learn something about indexing and slicing. 
#
#  **.loc()** has multiple access methods like:
#
# - A single scalar label
# - A list of labels
# - A slice object
# - A Boolean array
#
# **loc** takes two single/ list/ range operator separated by ','. The first one indicates the row and the second one indicates columns.
#
# *Please complete all the tasks:*

# + id="JW58HwihvfSt"
#import the pandas library as pd
import pandas as pd
import numpy as np

# you may reuse myarr from above, otherwise please recreate a 4x4 numy array
df = ...(myarr,index = ['a','b','c','d'], columns = ['A', 'B', 'C', 'D'])

#select the value in row b, columnd C
print(...)

#select all values in row b
print(...)

#select all values in from row b to d, and column A to C
print(...)

# + [markdown] id="WiHop8xU_bLo"
# *You can use boolean logic to slice dataframes as well. This is extremely handy in many situations. Please complete the tasks given in the comments. **Do not manually select the correct column (by just stating column X and row y)**:*

# + id="wgmuagXd_bVw"
# select all rows with a positive value in the 'A' column
print (...)

# select all columns with a positive value in the 'b' row
print (...)

# + [markdown] id="VrxtswA2Mupp"
# Now we are working with **.iloc()**. Pandas provide various methods in order to get purely integer based indexing. Like python and numpy, these are 0-based indexing.
#
# The various access methods are as follows:
# - An Integer
# - A list of integers
# - A range of values
#
# *Tap around and change the ... to complete the tasks in the comments:*

# + id="GeSB-zAiMwGt"
# you may reuse df, otherwise, please create a new 4 by 4 dataframe

# print the first 3 columns using 'i' and the loop
for i in range(3):
  print(...)

# print every second row using range
...[range( ... ) ... ]

# + [markdown] id="l5yZGuq6RDy4"
# You can read existing tables with pandas, to work with them in Python. The most common table format is csv. 
#
# *Please download the following file (https://drive.google.com/file/d/1rabckY6MNXi3kGEDJ2KIXGB1rsmdwbEr/view?usp=sharing), upload it to your Colab environment and change the path to read it:*
#

# + id="5Ow2FxtgQers"
import pandas as pd
df = pd.read_csv ('...')
print(df) 

# + [markdown] id="7B-Izk3RMSk3"
# *Let's change the Data a bit:*

# + id="1nSbRxA1UetU"
# Delete the 'fuel consumption' column
df = 

# Delete all rows, where the price is not available 
df = 

# Let's only keep cars, with more than 100 PS
df = 

df # Let's see if the table looks good

# + [markdown] id="5cPeqmMgNs1r"
# *Now, please save the dataframe as a new csv file*

# + id="fS1ycn55NtFz"
name = 'cars_new.csv'

... 

# + [markdown] id="mjutWdU7VgJF"
# **Matplotlib**
#
# Matplotlib is a program library for the programming language Python, which allows to plot your data.
#
# <img src ="https://miro.medium.com/max/1000/1*WACiczYwdWTnJ94mnizS4Q.jpeg" width=500 height=300>
#
#

# + [markdown] id="yR-VrJyXpQnx"
#
# *Please generate a positive linear function and plot it using matplotlib:*

# + id="jvNbwu8_yEEe"
import numpy as np
import matplotlib.pyplot as plt 
a = np. ... # please create 10 evenly spaced numbes between 0 and 1 
b = np. ... # please create 10 evenly spaced numbes between 0 and 10 
plt.plot(a,b)
plt.show()

# + [markdown] id="DrJomQ5EREim"
# *Now, try to plot a scatter plot, where you see each individual point*

# + id="DsMTSObFQDNU"
...(a,b)
plt.show()

# + [markdown] id="pTAh3IpX6Fng"
# *Now, we want to build a histogram:* 

# + id="yIlOVSBBR1td"
# Let's start by creating a list of 100 random numbers between 0 and 90
import random
random_numbers=[]
for i in range(100):
  random_numbers. ...

# Now let's plot a histogram with 10 bins
import ... as plt
plt. ... ( ... )
plt.show()

# + [markdown] id="5F0JvOsjVogd"
# **Sklearn**
#
# scikit-learn is a open source library for data analysis in Python based on other Python libraries: NumPy, SciPy and Matplotlib. It contains a number of implementations for various common machine learning algorithms.
#
# *Let's start by creating some data:* 

# + id="xTiKJ44odfuQ"
import matplotlib.pyplot as plt
import numpy as np

# create 40 random float numbers
X = 10* ...  

y = 3 * X + np.random.randn(40)*5

# Take a look at your data with a scatter plot
...
plt.show()

# + [markdown] id="rFRG_YiVh6OM"
# In many cases, it can be useful or necessary to standardize your data, so that both your X and y have a mean of 0 and a standard deviation of 1.
#
# *Try to standardize X and y using sklearn methods. You should receive 2 True as a result:*

# + id="GXwazIichb9i"
from sklearn import ...
import numpy as np
X_scaled = ...
y_scaled = ...

print(X_scaled.mean().round(10) == 0 and y_scaled.mean().round(10) == 0)
print(X_scaled.std().round(10) == 1 and y_scaled.std().round(10) == 1)


# + [markdown] id="G2s_v9ZdjwVJ"
# **<strong><font color='blue'> Side Note:** We may have to add a 'round(10)' here as Python works numerically - instead of getting an exact 0, you may sometimes get something like 2.2204460492503132e-17, which is practically 0, once we round to the tenth decimal point.</font></strong>

# + [markdown] id="yW99dkVKkk3M"
# *Let's make sure standardization did not change any proportions, by again producing a scatter plot with the scaled data:*

# + id="dnbjxif3g1VK"
...(X_scaled, y_scaled)
plt.show()

# + [markdown] id="B4z-ea5EIfoC"
# <img src ="https://preview.redd.it/phfw135f17u41.jpg?width=960&crop=smart&auto=webp&s=0074296cef9eeeb7a40a03f19e618b847c756426" width=500 height=300>

# + [markdown] id="Ky94Fe9pVu8a"
# ##Regression with Sklearn

# + [markdown] id="_KADPUVuDC1w"
# There are **five basic steps** when you’re implementing linear regression:
#
# 1. Import the packages and classes you need.
# 2. Provide data to work with and eventually do appropriate transformations.
# 3. Create a regression model and fit it with existing data.
# 4. Check the results of model fitting to know whether the model is satisfactory.
# 5. Apply the model for predictions.

# + [markdown] id="3vxgqggvDgEG"
# **Step 1: Import packages and classes**
#

# + [markdown] id="-4w2k0VNDzkd"
# *Please import the package numpy and the class LinearRegression:*

# + id="QOXsjNrzDqTL"
import numpy as np
from ... import LinearRegression

# + [markdown] id="25zDeGGiEBUw"
# The fundamental data type of NumPy is the array type called numpy.ndarray. From now on, we're using the term array to refer to instances of the type numpy.ndarray.

# + [markdown] id="0qNh58vEEMWL"
# **Step 2: Provide data:**
#
# The second step is defining data to work with. The inputs (regressors, 𝑥) and output (predictor, 𝑦) should be arrays (the instances of the class numpy.ndarray) or similar objects. Please reuse X_scaled and y_scaled. If this did not work, use the alternative data provided. 
#
# *If necessary, change the following code to provide data for the regression:*

# + id="XfhGOPWEuI72"
# IF YOU DID NOT MANAGE TO CREATE X_scaled and y_scaled, uncomment and use the following lines
# X_scaled = np.array([-0.51,  0.67, -0.47,  0.6 ,  1.71, -0.16,  0.34, -1.02, -0.68,
#         2.43, -1.2 ,  0.51, -0.91,  0.66, -0.53, -2.31, -0.65,  1.34,
#         0.11,  1.1 ,  1.52, -0.96, -1.29, -0.71, -0.3 ,  1.46, -1.08,
#         0.24, -0.  ,  0.28,  0.9 ,  0.75, -0.62, -0.71,  1.56, -0.33,
#         0.14, -1.43, -0.66,  0.2 ])
# y_scaled = np.array([-0.46,  0.63, -0.3 ,  0.66,  1.62, -0.55,  0.27, -1.03, -0.68,
#         2.25, -1.25,  0.47, -0.51,  0.63, -0.62, -2.42, -0.76,  1.44,
#        -0.12,  1.38,  1.6 , -1.22, -1.21, -0.63, -0.37,  1.24, -1.18,
#         0.37,  0.17,  0.4 ,  0.88,  0.77, -0.49, -0.44,  1.63, -0.37,
#         0.02, -1.36, -0.51,  0.07])

# + [markdown] id="Sgdxd-cp4VBx"
# *Please print the variables X_scaled and y_scaled to check if they are correct:*

# + id="CpgJWagDE-x9"
...
...

# + [markdown] id="L6PcWKhwFML5"
# **Step 3: Create a model and fit it**
#
# The next step is to create a linear regression model and fit it using the existing data. 

# + [markdown] id="Hk6SGwfuFihF"
# *Please create and fit the model (fitting means, sklearn will estimate your parameters for a given Input using the specified model):*
# **Attention: Many times, sklearn needs input of a specific shape. If this is the case (as it will be here), you may be required to reshape data, even if is basically the same, e.g. reshaping a (n,) array to a (n,1) array.**

# + id="X5HYk7zYICma"
model = ...

# + [markdown] id="IYmtW_4dFwfi"
# **Step 4: Get results**
#
# Once you have your model fitted, you can get the results to check whether the model works satisfactorily and interpret it.
#
# *Please obtain the coefficient of determination (𝑅²):*

# + id="owg_cgsgF7Uf"
r_sq = model. ...
print('coefficient of determination:', r_sq)

# + [markdown] id="Q7IOBX0JGG9U"
# *Now, please also take a look at the estimated parameters for the intercept and the slope:*

# + id="2t08j85rGJiP"
print('intercept:', ...)

print('slope:', ...)

# + [markdown] id="hKQtcJTsGRSO"
# The code above illustrates how to get 𝑏₀ and 𝑏₁. You may notice that the intercept is a scalar, while the slope is an array, as you can have multiple independent variables (X).

# + [markdown] id="BQbgOa03Gcjq"
# **Step 5: Predict response**
#
# Once there is a satisfactory model, you can use it for predictions with either existing or new data.
#
# *To obtain the predicted response for X_scaled, change the following code:*

# + id="Yn_1GeBTI1xm"
y_pred = ...
print('predicted response:', y_pred , sep='\n')

# + [markdown] id="GmP1TirNI7UT"
# *Let's plot both original data and our predicted values as a line:*

# + id="X_zYLgzOJCCe"
import matplotlib.pyplot as plt
plt.scatter(...)
plt.plot(...)
plt.show()

# + [markdown] id="nj0pBvAEGyOU"
# In practice, regression models are often applied for forecasts. 
#
# *Try to use the model to forecast a y value for a single random X value:*
# **Attention: Make sure, you provide your data in the correct format expected by your model - this can not be an integer ;)**

# + id="g5epV7S-MZsF"
X = ...
y_new = ...
print(y_new)

# + [markdown] id="DmI6Szxaid4z"
# ## Machine Learning Pipeline
#
# We will now execute a Machine Learning pipeline including data preparation, model training and performance evaluation using a Random Forest and a Linear Regression as a baseline model. 
#
# We will use a dataset, where customers rated the quality of wine (For details, see: https://archive.ics.uci.edu/ml/datasets/Wine).
#

# + [markdown] id="VWmk2uMXYoRB"
# **Step 1: Data Perparation**
#
#
# *Please load the two datasets properly, and store them in two dataframes:*

# + id="COtKM6dDRd5u"
import pandas as pd
url_white = 'https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv'
url_red = 'https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv'

df_white = ...
df_red = ...

print(df_white.shape,df_red.shape) # does this look resonable? Make sure you have the correct number of columns. If necessary, take a look at your data!

# + [markdown] id="atoUpOnrMum_"
# *Now add a column "color" with the wine colors white = 0 or red = 1 respectively (to preserve this information) and combine both dataframes into one:*

# + id="MK9qxcwYMtuP"
... # add color column to df_white
... # add color column to df_red
df_wines = ... # combine the two dataframes in a single long table

print(df_wines.shape) # this should be (6497, 13)

# + [markdown] id="bsIP2kuhMA68"
# Remember, we want to understand **what drives customer's quality perception for wines**. To accomplish that, we want to predict the perceived quality of a wine (our dependent variable, y) using all other available variables (indepentend variables, X).
#
# *Let's take a brief look at your dependend variable - how many wines per quality rating are there?*

# + id="nv32nSUxVLTR"
... # create a table with the number of occurences per quality value (e.g., there should be 193 wines rated 8)

# + [markdown] id="ZGgViSRJjy1s"
# *Now split the data in dependent (y) - quality - and independent(X) variable:*

# + id="vOIyY8IkMg3R"
X,y = ...

print(y.head(3))
X.head(3) # Does this look good?

# + [markdown] id="NCcOLK-ZMkUI"
# **Step 2: Training**
#
# *Let's split the dataset so that 80% of the data is used to train the model and 20% is kept for future evaluation:*

# + id="i1LDvrZ5MorA"
from sklearn.model_selection import ...
X_train, X_test, y_train, y_test = ...

print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)

# + [markdown] id="9FVKFEvSMtzc"
# Now we can define and fit our model on the training dataset. Let's do this for both a random forest and a linear regression model. Using two model will allow us to better evaluate our model performance in the end.
#
# *Please fit a linear regression and a random forest model:*

# + id="Q31IBY8OMw7k"
from sklearn.ensemble import ... # take suitable random forest module
from sklearn.linear_model import LinearRegression

model_rfo = ... # initialize random rorest model
model_lin = ... # initialize linear regression model

model_rfo.fit(...)
model_lin.fit(...)

# + [markdown] id="pTwMheqMM0Kf"
# **Step 3: Performance Evaluation**
#
# *Now use the fitted model to evaluate performance on your 20% holdout test dataset, using the mean squared error (*MSE*) performance metric:*
# Note, that neither model had 'seen' this data before. This is crucial.

# + id="4E6JDqYOM7AR"
from sklearn.metrics import ... # please use MSE

y_hat_rfo = ... # make predictions using your random forest model
y_hat_lin = ... # make predictions using your linear regression model

mse_rfo = ... # calculate random forest prediction MSE
mse_lin = ... # calculate linear regression prediction MSE

print('MSE Random Forest: %.3f' % mse_rfo)
print('MSE Linear Regression: %.3f' % mse_lin)

# + [markdown] id="uHDkZUZMWP-B"
# <img src ="https://i.ibb.co/Yyk6PBP/laughing-men-testing.jpg" width=500 height=300>

# + [markdown] id="oyUb34dPpqdk"
# *It is always a good idea, to get a visual intuition as well, so let's quickly plot ground truth y_test against our predictions y_hat_rfo and y_hat_lin*: 

# + id="4FtycYu3cdE-"
import matplotlib.pyplot as plt

... # generate a scatter plot for your random forest predictions
plt.show()

... # generate a scatter plot for your linear regression predictions
plt.show()

# + [markdown] id="7CN3utEwql_5"
# Taking both the MSE and the visual representation - which model performs better?

# + id="WK9El9w1qv1v"
# write your answer

# + [markdown] id="QED3CFGxq1Wi"
# **Step 4: Generating Insights**
#
# Let's use our model to find out what is the most important variable for quality. 
#
# *Please create a dataframe which has all the X variables and their respective performance and sort the dataframe by importance:*

# + id="Pacpzzrhd1fe"
insights = pd.DataFrame(columns=['variable','importance'])

insights['variable'] = ...
insights['importance'] = ...

insights. ... # please print the sorted table - what is most imporant?

# + [markdown] id="tClVksnmXsNn"
# ## Save & Submit
#
# Please make sure you included your name and matrikel at the top of this notebook, save your work **with your name in the file name**, and send **two** files to jasper dot schwenzow at uni dash hamburg dot de:
# - Ipynb *(Go to File -> Download .ipynb)*
# - PDF *(Go to File -> Print -> Save as PDF)* (optional)
#
#

StarcoderdataJupyterScriptsDedupFiltered