"""
# Contents:
1. [Load Libraries](#libraries)
2. [Read and split data](#read-and-split)
3. [Data preprocessing pipeline](#pipeline)
4. [Desicion Tree Classifier](#tree)
    1. [Accuracy](#tree-acc)
    2. [Visualizing the Decision Tree](#visual-tree)
5. [Support Vector Machine](#svm)
    1. [Accuracy](#svm-acc)
6. [Summary](#summary)
"""
"""
# Load libraries<a name='libraries'>
"""
%matplotlib inline
import numpy as np
import pandas as pd 
import matplotlib.pyplot as plt

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.impute import SimpleImputer
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import LinearSVC
from sklearn.metrics import accuracy_score, confusion_matrix
import matplotlib.image as mpimg
"""
### Let's see how these iris species look.
"""
img = mpimg.imread('../input/irisfiles/iris.jpeg')

plt.figure(figsize = (12,8))
plt.imshow(img)
"""
[Image Source](https://www.pngkey.com/png/detail/82-826789_iris-iris-sepal-and-petal.png)
> Visually it is much easier to tell the difference between Setosa and other spicies than between Versicolor and Virginica. 
"""
"""
# Read and split data<a name="read-and-split">
"""
import os

iris = pd.read_csv('../input/iris/Iris.csv')
iris.drop('Id',axis=1,inplace=True)

from sklearn.model_selection import train_test_split
train_set, test_set = train_test_split(iris, test_size=0.2, random_state=42)
train_X, train_y = train_set.drop('Species', axis=1), train_set['Species']
test_X, test_y   = test_set.drop('Species', axis=1), test_set['Species']
iris.info()
"""
# Pipeline of data preprocessing<a name="pipeline">

> Although this data has no missing values, I still like to use `imputer` because it makes the code friendly for new data which could have missing values. Feature Scaling is not necessary for **Decision Tree Classifier**, but it is necessary for **SVM** which is sensitive to the feature scaling. 
"""
prep_pipeline = Pipeline([
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler', StandardScaler()),
])

train_X_prep = prep_pipeline.fit_transform(train_X)
"""
# Decision Tree Classifier<a name='tree'>
> Since Decision Tree is not sensitive to the feature scaling I will not use `prep_pipeline` and `train_X_prep` yet.
"""
tree_clf = DecisionTreeClassifier(max_depth=2)

tree_clf.fit(train_X, train_y)
predictions = tree_clf.predict(train_X)
target = train_y
"""
# Accuracy and confusion matrix<a name='tree-acc'>
"""
acc = accuracy_score(predictions, target)
acc
conf_mx = confusion_matrix(target, predictions)
conf_mx
"""
# Visualizing the Decision Tree<a name='visual-tree'>
"""
from sklearn.tree import export_graphviz

export_graphviz( tree_clf,
                out_file="iris_tree_train.dot", 
                feature_names=iris.columns[:-1], 
                class_names=iris['Species'].unique(), rounded=True,
                filled=True
        )
img = mpimg.imread('../input/irisfiles/tree-train.png')

plt.figure(figsize = (8,8))
plt.imshow(img)
"""
# Support Vector Machine<a name='svm'>
> **Note**: If you do not know what `C` parameter means, I would recommend reading answers on [this](https://stats.stackexchange.com/questions/31066/what-is-the-influence-of-c-in-svms-with-linear-kernel) page. 
"""
lin_svm = LinearSVC(C=1, loss='hinge')
lin_svm.fit(train_X_prep, train_y)
test_X_prep = prep_pipeline.fit_transform(test_X)
target = test_y 

predictions = lin_svm.predict(test_X_prep)
"""
# Accuracy and confusion matrix<a name='svm-acc'>

"""
acc = accuracy_score(predictions, target)
acc
print(confusion_matrix(target, predictions))
target.unique()
iris.columns
plt.figure(figsize=(12,2.7))

plt.subplot(121)
plt.scatter(iris['SepalLengthCm'][iris['Species']=='Iris-setosa'], iris['SepalWidthCm'][iris['Species']=='Iris-setosa'] , color='r', label="Iris-setosa")
plt.scatter(iris['SepalLengthCm'][iris['Species']=='Iris-versicolor'], iris['SepalWidthCm'][iris['Species']=='Iris-versicolor'], color='b', label="Iris-versicolor")
plt.scatter(iris['SepalLengthCm'][iris['Species']=='Iris-virginica'], iris['SepalWidthCm'][iris['Species']=='Iris-virginica'], color='y', label="Iris-virginica")
plt.xlabel("Sepal length", fontsize=14)
plt.ylabel("Sepal width", fontsize=14)


plt.subplot(122)
plt.scatter(iris['PetalLengthCm'][iris['Species']=='Iris-setosa'], iris['PetalWidthCm'][iris['Species']=='Iris-setosa'] , color='r', label="Iris-setosa")
plt.scatter(iris['PetalLengthCm'][iris['Species']=='Iris-versicolor'], iris['PetalWidthCm'][iris['Species']=='Iris-versicolor'], color='b', label="Iris-versicolor")
plt.scatter(iris['PetalLengthCm'][iris['Species']=='Iris-virginica'], iris['PetalWidthCm'][iris['Species']=='Iris-virginica'], color='y', label="Iris-virginica")
plt.xlabel("Petal length", fontsize=14)
plt.ylabel("Petal width", fontsize=14)
plt.legend(loc="best")




plt.show()
"""
# Summary<a name="summary">
> To sum up, both algorithms achieved very similar results and probably it happened because of the simple nature of our data. Also, if you look at the plots above you can notice that <span style="color:red"> Iris-setosa</span> stands out from other species and theoretically it must have been easier for both algorithms to distuingish <span style="color:red"> Iris-setosa</span> from <span style="color:blue"> Iris-versicolor</span> and <span style="color:yellow"> Iris-virginica</span>. In contrast, distuingishing <span style="color:blue"> Iris-versicolor</span> and <span style="color:yellow"> Iris-virginica</span> could be not that trivial. You also can see it on the visualization of the Decision Tree. Anyways, achieved accuracy of almost 97% tells us that our algorithms were effective.<br/>
This notebook could be useful for someone who is just getting started with Machine Learning and wants to see simple flow of solving simple Machine Learning problem. 
"""