# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

# Input data files are available in the read-only "../input/" directory
# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory

import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using "Save & Run All" 
# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session
"""
* It can be used as a dimensionality reduction method, which can help to minimize the number of the variables (or columns of a data frame) without losing much of the original information. This is useful especially when you are building machine learning models based on the data with many variables like 100s or 1000s.
"""
"""
* It is an unsupervised stastical technique used to examine the interrelations among a set of variables in order to identify the underlying structure of those variables

* It is also known as general factor analysis

* While regression determines a line of best fit to a dataset, factor analysis or principal component analysis determines several orthogonal lines of best fit to the dataset.Orthogonal means at right angles. The lines are perpendicular to each other in n dimensional space where n dimensional space is the variable sample space. There as many dimensions as there are variables,i.e., a dataset with 4 variables the sample space is 4 dimensional.

* If we use this technique on a dataset with large numbers of variables, we can compress the amount of explained variation to just a few components.


"""
"""
* PCA is just a transformation of our data and attempts to find out what features excplain the most variance in our data

* We try to get rid of the components that do not explain enough the variance in our data.
"""
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
from sklearn.datasets import load_breast_cancer
cancer=load_breast_cancer()
cancer.keys()
#This is a special type of dataset of sklearn
print(cancer["DESCR"])
"""
* The data contains 569 rows and 30 variables or columns

* What we are going to do is to figure out what compenents are important to explain the variance of the data.
"""
cancer["data"]
# This is the data
cancer["feature_names"]
#This is the feature names of the data
"""
* Now we are going to combine the feature names with the data and make a dataframes
"""
df=pd.DataFrame(cancer["data"],columns=cancer["feature_names"])
df.head()
"""
* In this dataset, there are 30 dimensions or variables, thus it is difficult to visualize all of them. We can utilize PCA to learn the two most important components of the data and visualize the data in this new two dimensional space. 
"""
"""
* Before we use PCA in the data, we need to standartize the variables by using standart scaler of sklearn
"""
from sklearn.preprocessing import StandardScaler
scaler=StandardScaler()
scaler.fit(df)
scaled_data=scaler.transform(df)
scaled_data 
"""
* Standart Scaler transformed our data into a numpy array and standartized all of the variables of the data 
"""
from sklearn.decomposition import PCA
pca=PCA(n_components=2) # we make an instance of PCA and decide how many components we want to have

pca.fit(scaled_data) # We make PCA fit to our scaled data
transformed_data=pca.transform(scaled_data)
scaled_data.shape
#This is the original shape of the data with 569 rows and 30 columns
transformed_data.shape
#Here we see 569 rows but 2 columns or components after PCA implementation
transformed_data
"""
* The data has been reduced to the two most important components via PCA that we can easily plot out.
"""
plt.figure(figsize=(15,10))
plt.scatter(transformed_data[:,0],transformed_data[:,1])
plt.xlabel("The First Principal Component")
plt.ylabel("The Second Principal Component")
#Here we plot all the rows of columns 1 and column 2 in a scatterplot.
"""
* This plot does not explain much, we can add some paramaters to the same plot in order to show the positions of the components according the target variable of the data
"""
plt.figure(figsize=(15,10))
plt.scatter(transformed_data[:,0],transformed_data[:,1],c=cancer["target"],cmap="plasma")
plt.xlabel("The First Principal Component")
plt.ylabel("The Second Principal Component")
#Here we plot all the rows of columns 1 and column 2 in a scatterplot.
"""
* This plot shows the power of PCA because based on just two principal components, we can see very clear separation of the target variable, which shows how benign and malignant tumors look like.

* We utilize PCA as compression algorithm to get a clear information about the data instead of analyzing 30 columns or variables as it is case in this dataset.

* However the components that has been decided by PCA do not correspond to a specific column or variable in the dataset.These two components are the combinations of the original variables of the data.
"""
pca.components_
"""
* Each row represents actual componnents and each column relates back original features.

* We can see the relationship better via a heatmap.

* But first we need to transfor it into a dataframe in order to use the visualization libraries.
"""
df_comp=pd.DataFrame(pca.components_,columns=cancer["feature_names"])
df_comp
plt.figure(figsize=(15,10))
sns.heatmap(df_comp,cmap="magma")
"""
* In this heatmap above, we see the relation between the principal components and actual features

* The ligh color in the heatmap shows strong correlation between the principal components and actual features while dark colors show the opposite or negative correlation.

* Actually the principal components are the combinations of all these features of the data.
"""
"""
* After we get the principal components of the data, we can feed them into a machine learning algorithm because we have clear and separated components of the data instead of the complex variables.

* For this data we do a logistic regression on tranformed_data instead of doing regression with the entire data.

* Support vector machines can also be a good alternative for this data.
"""
X=transformed_data
y=cancer["target"]
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.3,random_state=101)
from sklearn.linear_model import LogisticRegression
log_regression=LogisticRegression()
log_regression.fit(X_train,y_train)
#Now our model is ready to predict the test data
predictions=log_regression.predict(X_test)
predictions
#Now it is time to evaluate how good the predictions are
from sklearn.metrics import classification_report
print(classification_report(y_test,predictions))
#The precision and accuracy precentages are over %90, it is very good
"""
* It is obvious that we can get pretty good prediction by using just the two principal components of the data instead of using all of the dataset.

* PCA can be very useful tool big data with many features.
"""
"""
* Now we will also use Support Vector Machines Algorithm with the PCA
"""
"""
* Because we have already siplitted data in the previous algorithm, we just skip this stage
"""
from sklearn.svm import SVC
svm_model=SVC()
svm_model.fit(X_train,y_train)
predictions=svm_model.predict(X_test)
predictions
from sklearn.metrics import classification_report,confusion_matrix
print(classification_report(y_test,predictions))
#here we get the classification report to learn how accurate our model is
"""
* The precision and accuracy precentages are over %90, it is very good although it is not as good as logistic regression
"""
"""
It is obvious that we can get pretty good prediction by using just the two principal components of the data instead of using all of the dataset.
"""