Analista de Dados Cientista de Dados
Análise Exploratória de dados de um seguro de saúde extraídos da plataforma Kaggle, um conjunto com 1338 registros limpos que apresenta informações de beneficiários de seguro de saúde como idade, gênero, IMC, região em que vive, quantidade de filhos, se é fumante e o custo. Além da análise, foi feita uma predição utilizando os dados com o objetivo de predir o custo de uma pessoa com base em seus dados fornecidos.
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import os
import seaborn as sns
df = pd.read_csv("insurance.csv")
df.head()
numRows, numColumns = df.shape
columns_names = list(df.columns)
print("Número de linhas: ", numRows, "\nNúmero de colunas: ", numColumns)
print("Nome das colunas: ", columns_names)
# Informações de cada coluna do Dataset: Nome da coluna; Número de células nulas na coluna
df.isna().sum()
pd.isna(df).any(axis=1).sum() # soma as linhas que apresentam uma ou mais células vazias
df.dtypes
age_values = (df.age.value_counts(sort = False)).index
age_min = df.age.min()
age_max = df.age.max()
print("Idades presentes na coluna age: ", list(age_values))
print("Menor Idade: ", age_min)
print("Maior Idade: ", age_max)
sex_values = (df.sex.value_counts(sort = False)).index
print("Valores presentes na coluna sex: ", list(sex_values))
bmi_values = (df.bmi.value_counts(sort = False)).index
bmi_min = df.bmi.min()
bmi_max = df.bmi.max()
print("Menor IMC: ", bmi_min)
print("Maior IMC: ", bmi_max)
children_values = (df.children.value_counts(sort = False)).index
children_min = df.children.min()
children_max = df.children.max()
print("Quantidades de filhos presentes na coluna children: ", list(children_values))
print("Menor quantidade de filhos: ", children_min)
print("Maior quantidade de filhos: ", children_max)
smoker_values = (df.smoker.value_counts(sort = False)).index
print("Valores presentes na coluna smoker: ", list(smoker_values))
region_values = (df.region.value_counts(sort = False)).index
print("Valores presentes na coluna region: ", list(region_values))
charges_values = (df.charges.value_counts(sort = False)).index
charges_min = df.charges.min()
charges_max = df.charges.max()
charges_mean = df.charges.mean()
print("Média custo: ", charges_mean)
print("Menor custo: ", charges_min)
print("Maior custo: ", charges_max)
Base de dados: insurance.csv
O conjunto de dados possui 1338 entradas sem dados faltantes e possui as seguintes 7 instâncias:
age (idade) - a idade do indivíduo
sex (genêro) - a genêro do indivíduo
bmi (IMC) - IMC (Índice de Massa Corpória) do indíviduo
children (filhos) - número de filhos do indíviduo
smolker (fumante) - indica se o indívidio é fumante ou não
region (região) - região em que mora o indíviduo
charges (custo) - custo médico do indíviduo
num_features = list(df.select_dtypes(include=np.number).columns) # Retorna os nomes das colunas numéricas do dataset
cat_features = list(np.setdiff1d(columns_names,num_features)) # Retorna a lista columns_names - num_features
print("Atributos Numéricos: ", num_features, "\nAtributos Categóricos: ", cat_features)
df.describe()
df.describe(include=['object'])
for cat_feature in cat_features:
plt.figure(figsize=(8,8))
sns.set_style("whitegrid")
ax = sns.countplot(x = df[cat_feature],label="Count", palette = "muted")
for rect in ax.patches:
ax.text (rect.get_x() + rect.get_width() / 2.4,rect.get_height()+2,"%.1f%%"% (rect.get_height()/ numRows *100),
weight='bold', fontsize = 12 )
plt.title("Número de amostras por '" + str(cat_feature) + "'", fontsize = 15)
for num_feature in num_features:
plt.rcParams['figure.figsize'] = [20, 20]
sns.set(style = 'whitegrid')
sns.displot(df[num_feature], bins = 90, color = '#1f77b4')
plt.ylabel("Número de amostras", fontsize = 15)
plt.xlabel(str(num_feature), fontsize = 15)
plt.margins(x = 0.1)
plt.title("Distribuição de amostras da coluna '" + str(num_feature) + "'", fontsize = 15)
plt.rcParams['figure.figsize'] = [10, 10]
sns_grad = sns.barplot(x = df['region'], y = df['charges'], data = df)
plt.setp(sns_grad.get_xticklabels(), rotation=0)
plt.title("'region' vs '" + num_feature + "'", fontsize = 15)
plt.rcParams['figure.figsize'] = [13, 10]
sns.set(style="whitegrid")
sns.kdeplot(data=df, x="charges", hue="region", cut=0, fill=True, common_norm=False, alpha=0.4)
plt.show()
A região em que a pessoa mora não tem influência no custo com a pessoa já que as 4 regiões possuem uma distribuição/densidade em relação aos custo(charges) muito próximas. Uma observção que pode ser feita é que morar na região "southeast" tem um pouco de impacto.
plt.rcParams['figure.figsize'] = [10, 10]
sns_grad = sns.barplot(x = df['sex'], y = df['charges'], data = df)
plt.setp(sns_grad.get_xticklabels(), rotation=0)
plt.title("'sex' vs '" + num_feature + "'", fontsize = 15)
plt.rcParams['figure.figsize'] = [13, 10]
sns.set(style="whitegrid")
sns.kdeplot(data=df, x="charges", hue="sex", cut=0, fill=True, common_norm=False, alpha=0.5)
plt.show()
O gênero não tem influência no custo com a pessoa já que homens e mulheres possuem uma distribuição/densidade em relação aos custo(charges) muito próximas.
plt.rcParams['figure.figsize'] = [10, 10]
sns_grad = sns.barplot(x = df['smoker'], y = df['charges'], data = df)
plt.setp(sns_grad.get_xticklabels(), rotation=0)
plt.title("'smoker' vs '" + num_feature + "'", fontsize = 15)
plt.rcParams['figure.figsize'] = [13, 10]
sns.set(style="whitegrid")
sns.kdeplot(data=df, x="charges", hue="smoker", cut=0, fill=True, common_norm=False, alpha=0.5)
plt.show()
Ser fumante tem impacto no custo com a pessoa como esperado já que a distribuição / densidade tem uma grande diferença.
plt.rcParams['figure.figsize'] = [10, 10]
sns_grad = sns.barplot(x = df['children'], y = df['charges'], data = df)
plt.setp(sns_grad.get_xticklabels(), rotation=0)
plt.title("'children' vs '" + num_feature + "'", fontsize = 15)
plt.rcParams['figure.figsize'] = [13, 10]
sns.set(style="whitegrid")
sns.kdeplot(data=df, x="charges", hue="children", cut=0, fill=True, common_norm=False, alpha=0.5)
plt.show()
A quantidade de filhos em sua maioria não tem impacto no custo com a pessoa o já que a distribuição / densidade são bem próximos, exceto pelo número de filhos igual à 5.
numerical_df = df[num_features]
categorical_df = df[cat_features]
plt.rcParams['figure.figsize'] = [10, 10]
sns.set_theme(style="white")
plt.matshow(numerical_df.corr())
plt.colorbar()
plt.xticks(np.arange(len(numerical_df.corr().columns)), numerical_df.corr().columns.values, rotation = 45)
plt.yticks(np.arange(len(numerical_df.corr().columns)), numerical_df.corr().columns.values)
for (i, j), corr in np.ndenumerate(numerical_df.corr()):
plt.text(j, i, '{:0.1f}'.format(corr), ha='center', va='center', color='white', fontsize=12)
sns.pairplot(df, vars= numerical_df, hue='smoker')
plt.rcParams['figure.figsize'] = [10, 10]
df.plot(kind = 'scatter', x = 'bmi', y = 'charges', color = "#00b8e6")
plt.show()
df.plot(kind = 'scatter', x = 'age', y = 'charges', color = "#00b8e6")
plt.show()
Esta nova coluna classificará o iníviduo de acordo com seu bmi (IMC) seguindo a tabela abaixo:
conditions = [
(df['bmi'] < 18.5),
(df['bmi'] >= 18.5) & (df['bmi'] < 25),
(df['bmi'] >= 25) & (df['bmi'] < 30),
(df['bmi'] >= 30) & (df['bmi'] < 35),
(df['bmi'] >= 35) & (df['bmi'] < 40),
(df['bmi'] >= 40)]
choices = ['Abaixo', 'Normal', 'Acima', 'Obesidade','Extrema Obesidade', 'Obesidade Mórbida']
df["bmi_classif"] = np.select(conditions, choices, default='Normal')
df.head()
plt.rcParams['figure.figsize'] = [10, 10]
sns.lmplot(x='age',y='charges',hue='smoker', col='bmi_classif',data=df)
plt.rcParams['figure.figsize'] = [10, 10]
sns.lmplot(x='age',y='charges',hue='bmi_classif', col='smoker',data=df)
%matplotlib inline
from IPython.display import Image
import statsmodels.api as sm
teste = df.copy()
teste.smoker = teste.smoker.map(dict(yes=1, no=0))
conditions = [
(teste['bmi'] < 30) & (teste['smoker'] == 1),
(teste['bmi'] >= 18.5) & (teste['bmi'] < 25) & (teste['smoker'] == 1),
(teste['bmi'] >= 25) & (teste['bmi'] < 30) & (teste['smoker'] == 1),
(teste['bmi'] >= 30) & (teste['bmi'] < 35) & (teste['smoker'] == 1),
(teste['bmi'] >= 35) & (teste['smoker'] == 1)]
choices = [1, 2, 3, 4,5]
teste["bmi_smoker_classif"] = np.select(conditions, choices, default = 0)
conditions = [
(df['bmi'] < 18.5),
(df['bmi'] >= 18.5) & (df['bmi'] < 25),
(df['bmi'] >= 25) & (df['bmi'] < 30),
(df['bmi'] >= 30) & (df['bmi'] < 35),
(df['bmi'] >= 35)]
choices = [1, 2, 3, 4, 5]
teste["bmi_classif"] = np.select(conditions, choices, default='Normal')
teste
teste2 = pd.get_dummies(teste[['region', 'sex', 'smoker']])
teste = pd.concat([teste2, teste[['age','bmi','charges','bmi_classif','bmi_smoker_classif']]], axis=1, join="inner")
teste.corr(method='pearson')
df_regres = df.copy()
df_regres.drop("bmi_classif", axis = 1, inplace = True)
conditions = [
(teste['bmi'] < 30) & (teste['smoker'] == 1),
(teste['bmi'] >= 30) & (teste['bmi'] < 35) & (teste['smoker'] == 1),
(teste['bmi'] >= 35) & (teste['smoker'] == 1)]
choices = [1, 2, 3]
# conditions = [
# (teste['bmi'] < 30) & (teste['smoker'] == 1),
# (teste['bmi'] >= 18.5) & (teste['bmi'] < 25) & (teste['smoker'] == 1),
# (teste['bmi'] >= 25) & (teste['bmi'] < 30) & (teste['smoker'] == 1),
# (teste['bmi'] >= 30) & (teste['bmi'] < 35) & (teste['smoker'] == 1),
# (teste['bmi'] >= 35) & (teste['smoker'] == 1)]
# choices = [1, 2, 3, 4,5]
# conditions = [
# (teste['bmi'] < 30) & (teste['smoker'] == 1),
# (teste['bmi'] >= 30) & (teste['bmi'] < 35) & (teste['smoker'] == 1),
# (teste['bmi'] >= 35) & (teste['bmi'] < 40) & (teste['smoker'] == 1),
# (teste['bmi'] >= 40) & (teste['smoker'] == 1)]
# choices = [1, 2, 3,4]
# conditions = [
# (teste['bmi'] < 30) & (teste['smoker'] == 1),
# (teste['bmi'] >= 30) & (teste['bmi'] < 35) & (teste['smoker'] == 1),
# (teste['bmi'] >= 35) & (teste['smoker'] == 1),
# (teste['bmi'] >= 30) & (teste['smoker'] == 0)]
# choices = [1,2,3,4]
df_regres["bmi_smoker_classif"] = np.select(conditions, choices, default = 0)
df_regres.smoker = df_regres.smoker.map(dict(yes=1, no=0))
df_regres.sex = df_regres.sex.map(dict(female=1, male=0))
df_regres.region = df_regres.region.map(dict(southwest=0, southeast=1,northwest=2,northeast=3))
#df_regres.head()
df_regres.head()
X = np.column_stack((df_regres['age'],df_regres['bmi_smoker_classif'],df_regres['region']))
y = df_regres['charges']
X2 = sm.add_constant(X)
est = sm.OLS(y, X2)
est2 = est.fit()
print(est2.summary())