"""
<b>this one is made to try poisson regressor in scikit-learn which is there from version 0.23<br>
please check your version before trying by:<br></b>
    `import sklearn
print('The scikit-learn version is {}.'.format(sklearn.__version__))`
"""
"""
Welcome to day one of the 5-Day Regression Challenge! To get started, click the blue "fork notebook" button in the upper right hand corner. This will make a copy of this notebook that you can edit. To run cells once you've forked the notebook, click inside a code cell and then hit CTRL + ENTER (CMD + ENTER on a Mac).

![The button to fork this notebook](https://image.ibb.co/kNKUZ5/Screenshot_from_2017_08_30_16_47_40.png)

___ 
**What is regression?**

Regression is one way of modeling the strength and direction of the relationship between a dependent or output variable (usually represented by y) and one or more independent or input variables (usually represented by x). It differs from correlation analysis because it allows you to predict the outcome for new input or inputs you haven’t seen yet.

**What types of regression are there?**

There are many different types of regression. The specific family of regressions we’ll be learning are called “generalized linear models”. The important thing for you to know is that with this family of models, you need to pick a specific type of regression you’re interested in. The type of regression will depend on what type of data you’re trying to predict.

* **Linear**: When you’re predicting a continuous value. (What temperature will it be today?)
* **Logistic**: When you’re predicting which category your observation is in. (Is this is a cat or a dog?)
* **Poisson**: When you’re predicting a count value. (How many dogs will I see in the park?)

Today, we’re going to practice picking the right model for our dataset and plotting it. I will demonstrate first on one dataset, then you'll try your hand at another.

___

<center>
[**You can check out a video that goes with this notebook by clicking here.**](https://www.youtube.com/embed/UOj-GJAuvPM)
"""
"""
## Example: Recipes
____

For our example, I'm going be working with a dataset of information on various recipes. I want to predict whether or not a recipe is a dessert based on how many calories it has. 

First, let's read in the library & datasets we'll need.
"""
import pandas as pd
recipies = pd.read_csv("../input/epirecipes/epi_r.csv")
bikes = pd.read_csv("../input/nyc-east-river-bicycle-crossings/nyc-east-river-bicycle-counts.csv", index_col=0)
weather = pd.read_csv("../input/szeged-weather/weatherHistory.csv")
"""
I'm going to do a little bit of data cleaning. I know that this has some really outrageous outliers, so I want to ignore any recipe with more than ten thousand calories. I also know that there are a lot of missing values, so I'm going to remove them. (You shouldn't) need to do this with the other datasets. 
"""
# quickly clean our dataset
print('#rows in original recipies dataset: {}'.format(recipies.shape[0]))
recipies = recipies[recipies.calories < 10000]
print('#rows in recipies dataset without high calories: {}'.format(recipies.shape[0]))
recipies.dropna(inplace=True)
print('#rows in recipies dataset withouh high calories and NA rows: {}'.format(recipies.shape[0]))
"""
So I already have my question, "Can I predict whether or not a recipe is a dessert based on how many calories it has?". (With your dataset you'll need to come up with your question by picking one variable to predict and one to use to predict it).

In order to build a model, I need to know what type of variable whether or not a recipe is a dessert is. There are three choices:

* **Continuous**. These are numeric variables that can take any value, including decimals. Examples include temperatures or prices.
* **Count**. These are numeric variables that can only take positive integer values. Examples include the number of people at a party or the number of cars in a parking lot.
* **Categorical**. These are not numbers. Categorical variables tell you whether or not an observation is part of a specific group. Good examples include gender or whether someone owns more than ten hats.

The best way to figure out which one is a variable is is to use your knowledge of a dataset and the world in general. For example, I know that whether or not a recipie is a dessert is a *categorical* variable, while the number of calories in a dessert is probably a *count* variable (unless you have a very, very accurate measure of calories, in which case it might be continuous).

There are some quick tests you can do to double-check, though. For example, I might want to know if the ratings for a recipie are categorical, count, or continuous. First, I can check if they're numeric:
"""
# are the ratings all numeric?
recipies.rating.dtype
"""
So I know it's represented by a numeric variable in this dataframe. This means that ratings are probably not things like "very good" or "very bad".

Next, I can check if all the values are integers (whole numbers). If so, it's probably a count variable. If not, it's probably continuous.
"""
#we know it form float64 datatype,
#but let check if there are really some rating with decimal part
print('#rows with decimal part in rating: {}'.format(
    recipies[recipies.rating % 1 > 0].shape[0]))
"""
So, in this dataset, ratings are a continuous variable. It's a number that can have decimal values. 

However, I'm not interested in predicting ratings. I'm interested in predicting if something is a dessert or not based on how many calories it has. To do this, I can plot the number of calories by whether or not the recipe is for a dessert. 
"""
import seaborn as sns
# plot calories by whether or not it's a dessert
sns.scatterplot(x='calories', y='dessert', data=recipies)
"""
Since whether or not something is a dessert is a categorical variable, we want to use logistic regression to answer this question. As you can see in the chart below, the link function for logistic regression is "binomial".
___
![Regression guide](https://image.ibb.co/ducqSw/regression_guide.png)
___

We can fit and plot a regression line to our data using the geom_smooth() layer. To make sure we do logistic regression, we need to make sure that we tell geom_smooth to fit a regression model from the binomial family, like so:
    
    geom_smooth(method = "glm", method.args = list(family = "binomial"))
 
 If we were fitting a linear regression model instead, for example, we'd ask geom_smooth() to fit a model from the gaussian family, like so:
    
    geom_smooth(method = "glm", method.args = list(family = "gaussian"))
    
geom_smooth() relies on the x and y arguments that you pass to ggplot (in the aes() argument), so you want to make sure you put the value you're interested in predicting in the y argument slot. (Here, that's "dessert".)
"""
from sklearn.linear_model import LogisticRegression
import numpy as np
import matplotlib.pyplot as plt

%matplotlib inline
model = LogisticRegression()
X =recipies.calories.values.reshape(recipies.calories.count(),1)

model.fit(X, recipies.dessert)
proba = model.predict_proba(X)
plt.figure(figsize=(10,4))
sns.scatterplot(x='calories', y='dessert', data=recipies)
plt.plot(X, proba[:,1])
"""
That blue line we've plotted is actually a regression model! Looking at the regression line, we can tell that as the number of calories in a recipe increases, it's more likely that that recipe is a dessert. (We can tell this because the line moves towards 1, which means "is a dessert" and away from 0, which means "isn't a dessert"). 

The grey shape behind it is the standard error. Looking at the error, we can tell that we're pretty sure about our prediction when there's fewer calories (towards the left side of the graph), but as we move to the right we get less certain and our error increases.

We'll learn more about fitting and interpreting models tomorrow, but for now it's time for you to try your own hand at picking the right type of model and fitting it.
"""
"""
## Your turn!
___
![Regression guide](https://image.ibb.co/ducqSw/regression_guide.png)

A quick guide to the three types of regression we've talked about.
___

Now it's your turn to come up with a question, pick the right model for your data and plot it.
"""
"""
1. Pick one of the two datasets ("weather" or "bikes", your choice! You can find out more about these datasets by expanding the "Input" section at the very top of this notebook.)
"""
"""
2. Identify which variables are continuous, categorical and count using the dataset documentation. (You can also check out a summary of the dataset using summary() or str())

"""
bikes.head(5)
"""
<b>continuous</b>: Date, Day, High Temp (°F), Low Temp (°F), Precipitation<br>
<b>count</b>: Brooklyn Bridge, Manhattan Bridge, Williamsburg Bridge, Queensboro Bridge, Total<br>
<b>category</b>: none of them
"""
"""
3. Pick a variable to predict and one varaible to use to predict it
    * For this challange, if you're picking a categorical value, I'd recommend choosing one with only two possible categories (like dessert or not dessert)
"""
df = bikes[['Precipitation', 'Total']].copy()
X = bikes.Precipitation
y = bikes.Total

def print_bad_values(df):
    print(df[df.Precipitation.map(lambda x : x.replace('.', '', 1).isdigit() == False)].Precipitation)
    
print_bad_values(df)
"""
little bit of gooolefu tells us:<br>
    <i>In meteorology, the word "trace" is used to describe a very small amount of precipitation that results in no measurable accumulation</i><br>
So we replace those values with 0    
"""
df.Precipitation = df.Precipitation.map(lambda x : '0.0' if x == 'T' else x)
df.Precipitation = df.Precipitation.map(lambda x : x.split()[0] if 'S' in x  else x)
print_bad_values(df)
"""
finaly convert whole column to float values
"""
df.Precipitation = df.Precipitation.map(lambda x : float(x))
print('min {}, max {}'.format(df.Precipitation.min(), df.Precipitation.max()))
df.info()
"""
4. Plot your two variables
"""
import sklearn
print('The scikit-learn version is {}.'.format(sklearn.__version__))
sns.scatterplot(x=df.Precipitation, y=df.Total)
"""
5. Use "geom_smooth" and the appropriate family to fit and plot a model
"""
from sklearn.linear_model import PoissonRegressor #for sklearn from version 0.23 #
#I would actualy use plotting of model prediction as I play around with Python not R
X = df.Precipitation.values.reshape(df.Precipitation.count(), 1)
y = df.Total

model = PoissonRegressor()
model.fit(X, y)
df['Preds'] = model.predict(X)
df.Preds = df.Preds.map(lambda x : int(x))
df.head()
plt.figure(figsize=(10, 6))
sns.scatterplot(x='Precipitation', y='Total', data=df)# fit_reg=False)
sns.lineplot(x='Precipitation', y='Preds', data=df)
"""
6. Optional: If you want to share your analysis with friends or to ask for help, you’ll need to make it public so that other people can see it.
  * Publish your kernel by hitting the big blue “publish” button. (This may take a second.)
  * Change the visibility to “public” by clicking on the blue “Make Public” text (right above the “Fork Notebook” button).
  * Tag your notebook with 5daychallenge
"""
"""
Want more? Ready for a different dataset? [This notebook](https://www.kaggle.com/rtatman/datasets-for-regression-analysis/) has additional dataset suggestions for you to practice regression with. 
"""