"""
**I am very new with Data Analysis, so please bare with me. Any and every feedback is appreciated.**

A few points to note:
1. I need help to know which ML model is the best to select and use for such kind of a prediction.
2. I have placed a few doubts in the comments (it's in the PREDICTIVE ANALYSIS section).
3. Please do state if there are better ways to plot certain correlations.
"""
#Import Libraries
import pandas as pd
import seaborn as sns
import matplotlib 
import matplotlib.pyplot as plt
%matplotlib inline 
#read csv
data = pd.read_csv("../input/body-performance-data/bodyPerformance.csv")
#create dataframe
df = pd.DataFrame(data)
"""
# DATA PREPROCESSING
"""
df.shape
#check for missing values
df.isna().sum()
#Rename columns
df = df.rename(columns={"body fat_%":"body_fat", "height_cm":"height", "weight_kg":"weight", "sit and bend forward_cm":"bend_forward", "gripForce":"grip_force","sit-ups counts":"sit_ups", "broad jump_cm":"broad_jump"})
df.sample(5)
"""
# DATA VISUALIZATION
"""
#Gender and height / weight
plt.figure(figsize=(10,5))
ax = plt.subplot(1,2,1)
sns.boxplot(x="gender", y="height", data=df, ax=ax)
ax = plt.subplot(1,2,2)
sns.boxplot(x="gender", y="weight", data=df, ax=ax)
"""
Insight 1: Males tend to be taller and heavier than females.
"""
#Gender and body fat
plt.figure(figsize=(10,5))
ax = plt.subplot(1,1,1)
sns.boxplot(x="gender", y="body_fat", data=df, ax=ax)
"""
Insight 2: Females, on average, have a slightly higher body fat % than males.
"""
#Gender and gripforce
plt.figure(figsize=(10,5))
ax = plt.subplot(1,1,1)
sns.boxplot(x="gender", y="grip_force", data=df, ax=ax)
df.groupby("gender").mean()
"""
Insight 3: Males tend to have a higher grip force on average compared to females.
"""
#Age and body fat
plt.figure(figsize=(10,5))
ax = plt.subplot(1,1,1)
sns.scatterplot(x="age", y="body_fat", data=df, ax=ax)
"""
Insight 4: There seems to be no correlation between age and body fat %
"""
#Diastolic with bodyfat
#Diastolic with age
#Diastolic with gender
plt.figure(figsize=(15,5))
ax = plt.subplot(1,3,1)
sns.scatterplot(x="diastolic", y="body_fat", data=df, ax=ax)
ax = plt.subplot(1,3,2)
sns.scatterplot(x="diastolic", y="age", data=df, ax=ax)
ax = plt.subplot(1,3,3)
sns.boxplot(x="gender", y="diastolic", data=df, ax=ax)
ax.set(ylim=(25,130))
"""
Insight 5: There seems to be no correlation between diastolic blood pressure and body fat % as well as no correlation between diastolic blood pressure and age.
However, males tend to have higher diastolic blood pressure compared to females.
"""
#Systolic with bodyfat
#Systolic with age
#Systolic with gender
plt.figure(figsize=(10,5))
ax = plt.subplot(1,3,1)
sns.scatterplot(x="systolic", y="body_fat", data=df, ax=ax)
ax = plt.subplot(1,3,2)
sns.scatterplot(x="systolic", y="age", data=df, ax=ax)
ax = plt.subplot(1,3,3)
sns.scatterplot(x="gender", y="systolic", data=df, ax=ax)
"""
Insight 6: There seems to be no correlation between systolic blood pressure and body fat % as well as no correlation between systolic blood pressure and age. However, males tend to have higher systolic blood pressure compared to females.
"""
#Body fat and gripfore
#Body fat and bend forward
plt.figure(figsize=(10,5))
ax = plt.subplot(1,2,1)
sns.scatterplot(x="body_fat", y="grip_force", data=df, ax=ax)
ax = plt.subplot(1,2,2)
sns.scatterplot(x="body_fat", y="bend_forward", data=df, ax=ax)
"""
Insight 7: People with a lower body fat % have a higher grip force.
There seems to be no correlation between body fat % and ability to bendforward.
"""
#Body fat and sit ups
#Body fat and broadjump
plt.figure(figsize=(10,5))
ax = plt.subplot(1,2,1)
sns.scatterplot(x="body_fat", y="sit_ups", data=df, ax=ax)
ax = plt.subplot(1,2,2)
sns.scatterplot(x="body_fat", y="broad_jump", data=df, ax=ax)
"""
Insight 8: People with a lower body fat % tend to be able to do a higher amount of sit ups. Moreover, people with a lower body fat % tend to be able to able to have a higher broad jump distance. 
"""
#Class and gender
#Class and age
plt.figure(figsize=(10,5))
ax = plt.subplot(1,2,1)
sns.countplot(x="class", hue="gender", data=df, ax=ax)
ax = plt.subplot(1,2,2)
sns.boxplot(x="class", y="age", data=df, ax=ax)
df.groupby("class")["age"].mean()
"""
Insight 9: It is difficult to state whether averagely more males fall under a certain class than females, because in the dataset, there are 8467 males compared to 4926 females.
However, from the 2nd plot, we can infer that the average age for class A seems to be considerably lower than the other classes.
"""
#Class and body fat
plt.figure(figsize=(10,5))
ax = plt.subplot(1,2,1)
sns.boxplot(x="class", y="body_fat", data=df, ax=ax)
ax.set(ylim=(0,60))
df.groupby("class")["body_fat"].mean()
"""
Insight 10: On average, people in Class A tend to have a lower body fat %.
"""
#Class and sit ups, bendforward, broad jump
plt.figure(figsize=(15,5))
ax = plt.subplot(1,3,1)
sns.boxplot(x="class", y="sit_ups", data=df, ax=ax)
ax = plt.subplot(1,3,2)
sns.boxplot(x="class", y="bend_forward", data=df, ax=ax)
ax.set(ylim=(-30,50))
ax = plt.subplot(1,3,3)
sns.boxplot(x="class", y="broad_jump", data=df, ax=ax)
df.groupby("class")["sit_ups", "bend_forward", "broad_jump"].mean()
"""
Insight 11: On average, people in Class A tend to be able to do more sit ups, bend more forward and able to jump further than the people in other classes.
"""
"""
# DATA MODELING AND PREDICTIVE ANALYSIS
"""
#import libraries
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.metrics import accuracy_score
from xgboost import XGBRegressor
import numpy as np
tempdf=df
tempdf.sample()
#Changing gender and class column to numerical values
from sklearn import preprocessing
le = preprocessing.LabelEncoder()
label = le.fit_transform(tempdf["gender"])
tempdf.drop("gender", axis=1)
tempdf["gender"] = label
label = le.fit_transform(tempdf["class"])
tempdf.drop("class", axis=1)
tempdf["class"] = label
tempdf.sample()
#split data into train and test data
train_x,test_x,train_y,test_y = train_test_split(tempdf.iloc[:,:-1],tempdf.iloc[:,-1],test_size = 0.2)
#XGBoost model
model = XGBRegressor(max_depth = 6)
model.fit(train_x, train_y)
#Set target object value
target = model.predict(test_x)
target = target.round(0)
target = np.array(target)
target = target.astype(int)
#Calculate MSE
mean_squared_error(target, test_y)
target[:5]
test_y[:5].values
#NEED HELP WITH THIS: How to make the predicted values into whole numbers like the CLASS column i.e., (0,1,2,3)? 
#{The method I used was to first round all the numbers to the 0th decimal place, then I converted the array to integer values.}
#Calculate accuracy of model
accuracy = accuracy_score(test_y, target)
print("Accuracy: %.2f%%" % (accuracy*100))
#NEED HELP WITH THIS: Is this a good accuracy score? (I'm assuming not)
#What is a better model here to use to obtain a higher accuracy score?