# import pandas, matplotlib, and scikit learn
import pandas as pd
import matplotlib.pyplot as plt
pd.set_option('display.width', 80)
pd.set_option('display.max_rows', 20)
pd.set_option('display.max_columns', 7)
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import IsolationForest
from mpl_toolkits.mplot3d import Axes3D
covidtotals = pd.read_csv("dane/covidtotals.csv")
covidtotals.set_index("iso_code", inplace=True)

# create a standardized analysis data frame
analysisvars = ['location','total_cases_pm','total_deaths_pm',
  'pop_density','median_age','gdp_per_capita']
standardizer = StandardScaler()
covidtotals.isnull().sum()
covidanalysis = covidtotals.loc[:, analysisvars].dropna()
covidanalysisstand = standardizer.fit_transform(covidanalysis.iloc[:, 1:])

# run an isolation forest model to detect outliers
clf=IsolationForest(n_estimators=100, max_samples='auto',
  contamination=.1, max_features=1.0)
clf.fit(covidanalysisstand)
covidanalysis['anomaly'] = clf.predict(covidanalysisstand)
covidanalysis['scores'] = clf.decision_function(covidanalysisstand)
covidanalysis.anomaly.value_counts()

# view the outliers
inlier, outlier = covidanalysis.loc[covidanalysis.anomaly==1],\
  covidanalysis.loc[covidanalysis.anomaly==-1]
outlier[['location','total_cases_pm','total_deaths_pm',\
  'median_age','gdp_per_capita','scores']].\
  sort_values(['scores']).\
  head(10)

# plot the inliers and outliers
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.set_title('Wykrywanie anomalii za pomocą algorytmu Isolation Forest')
ax.set_zlabel("Liczba przypadków na milion mieszkańców")
ax.set_xlabel("PKB per capita")
ax.set_ylabel("Mediana wieku")
ax.scatter3D(inlier.gdp_per_capita, inlier.median_age, inlier.total_cases_pm, label="Wartości nieodstające", c="blue")
ax.scatter3D(outlier.gdp_per_capita, outlier.median_age, outlier.total_cases_pm, label="Wartości odstające", c="red")
ax.legend()
plt.tight_layout()
plt.show()
