En esta publicación estaré explorando un dataset público con caracterÃsticas de casas de la ciudad de Boston, USA. Comenzaré realizando un análisis exploratorio y luego aplicaré un PCA para reducir la dimensionalidad y ver las relaciones existentes entre las variables y las observaciones
Importando LibrerÃas
import pandas as pd
import numpy as np
from pydataset import data
import warnings
warnings.filterwarnings("ignore")
pd.set_option('display.max_columns',None)
import matplotlib as plt
import matplotlib.pyplot as plt
import seaborn as sns
import tabulate
from tabulate import tabulate
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.decomposition import PCA
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import scale
import IPython
import mpl_axes_aligner
%matplotlib inline
Importando Dataset
Este dataset se encuentra dentro de la librerÃa pydataset
df = data('Boston')
df.head()
Dimensiones
print("El dataset contiene",df.shape[0],"filas y ",df.shape[1],"columnas")
Revisión nombre de columnas y posición
for i in df.columns:
print("columna",df.columns.get_loc(i),":",i)
Revisión de tipo de datos
df.info()
EstadÃsticos Descriptivos
df.describe()
Gráfico de Promedios por variable
df.mean(axis=0).sort_values(ascending=False).plot.bar()
df.std(axis=0).sort_values(ascending=False).plot.bar(color = "red")
Por medio de estos gráficos podemos ver que la variable tax es una de las que tiene mayor promedio y varianza
Chequeo de valores nulos
df.isnull().any()
df.isnull().sum()
Chequeo valores NA
df.isna().sum()
Chequeo valores duplicados
if df.duplicated().any() == False:
print("No hay filas duplicados")
Loop para graficar variables
Gráfico histograma + density
for i, col in enumerate(df.columns):
plt.figure(i)
sns.distplot(df[col])
Correlación entre variables
correlacion = df.corr().round(2)
correlacion.style.background_gradient(cmap='coolwarm')
Creación de Pipeline para realizar la estandarización Z y aplicar el modelo PCA con 3 componentes:
Estandarización depca_pipe = make_pipeline(StandardScaler(), PCA(n_components=3)) pca_pipe.fit(df) variables
$$Z = \frac{x-\overline{x}}{\sigma}$$
df_x = StandardScaler().fit_transform(df)
df_x
df_scaled = pd.DataFrame(data = df_x,
columns = df.columns)
df_scaled.head()
modelo_pca = PCA()
scores = modelo_pca.fit_transform(df_x)
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(10, 7))
componentes = modelo_pca.components_
plt.imshow(componentes.T, cmap='viridis', aspect='auto')
plt.yticks(range(len(df.columns)), df.columns)
plt.xticks(range(len(df.columns[:14])), np.arange(modelo_pca.n_components_) + 1)
plt.grid(False)
plt.colorbar()
plt.show()
Por medio de este gráfico podemos por cada componente que relación tiene con cada variable
Varianza Explicada por Componente
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(10, 4))
ax.bar(
x = np.arange(modelo_pca.n_components_) + 1,
height = modelo_pca.explained_variance_ratio_
)
for x, y in zip(np.arange(len(df.columns)) + 1, modelo_pca.explained_variance_ratio_):
label = round(y, 2)
ax.annotate(
label,
(x,y),
textcoords="offset points",
xytext=(0,10),
ha='center'
)
ax.set_xticks(np.arange(modelo_pca.n_components_) + 1)
ax.set_ylim(0, 1.1)
ax.set_title('Porcentaje de varianza explicada por cada componente')
ax.set_xlabel('Componente principal')
ax.set_ylabel('Por. varianza explicada')
plt.show()
Varianza explicada Acumulada
prop_varianza_acum = modelo_pca.explained_variance_ratio_.cumsum()
print(prop_varianza_acum)
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(7, 4))
ax.plot(
np.arange(len(df.columns[:14])) + 1,
prop_varianza_acum,
marker = 'o'
)
for x, y in zip(np.arange(len(df.columns[:14])) + 1, prop_varianza_acum):
label = round(y, 2)
ax.annotate(
label,
(x,y),
textcoords="offset points",
xytext=(0,10),
ha='center'
)
ax.set_ylim(0, 1.1)
ax.set_xticks(np.arange(modelo_pca.n_components_) + 1)
ax.set_title('Porcentaje de varianza explicada acumulada')
ax.set_xlabel('Componente principal')
ax.set_ylabel('Por. varianza acumulada')
plt.show()
Resultados del PCA
resultados = modelo_pca.transform(df_x)
lista = []
for i in range(1,15,1):
n = "PC"+str(i)
lista.append(n)
df_resultados = pd.DataFrame(
data = resultados,
columns = lista)
df_resultados.head()
Scatterplot PC1 & PC2
plt.figure(figsize=(12,8))
plt.scatter(df_resultados['PC1'],df_resultados['PC2'],cmap='plasma')
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.show()
Scatterplot PC1 & PC2 con Ãndices
plt.figure(figsize=(12,8))
plt.scatter(df_resultados['PC1'],df_resultados['PC2'],cmap='plasma',color="white")
plt.xlabel('PC 1')
plt.ylabel('PC 2')
for i, label in enumerate(range(0,df_resultados.shape[0],1)):
plt.annotate(label, (df_resultados['PC1'][i], df_resultados['PC2'][i]))
plt.show()
Scatterplot en 3D
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(10,10))
# choose projection 3d for creating a 3d graph
axis = fig.add_subplot(111, projection='3d')
# x[:,0]is pc1,x[:,1] is pc2 while x[:,2] is pc3
axis.scatter(df_resultados['PC1'],df_resultados['PC2'],df_resultados['PC3'],c = 'r',marker = 'o',cmap='plasma')
axis.set_xlabel("PC1", fontsize=10)
axis.set_ylabel("PC2", fontsize=10)
axis.set_zlabel("PC3", fontsize=10)
plt.show()
Loadings
df_Loadings = pd.DataFrame(modelo_pca.components_,columns=df.columns,index=df_Scores.columns)
df_Loadings.head()
font1 = {'family':'serif','color':'black','size':35}
def biplot(dfScores: pd.DataFrame, dfLoadings: pd.DataFrame) -> None:
#create figure and axis objects
fig,ax = plt.subplots(figsize=(15,8))
#make a scores plot
ax.scatter(dfScores.PC1.values,dfScores.PC2.values, color='y')
#set x-axis label
ax.set_xlabel("PC1",fontsize=10)
#set y-axis label
ax.set_ylabel("PC2",fontsize=10)
#create a second set of axes
ax2 = ax.twinx().twiny()
#setup font dictionary
font = {'color': 'g',
'weight': 'bold',
'size': 12,
}
#make a loadings plot
for col in dfLoadings.columns.values:
#where do our loading vectors end?
tipx = dfLoadings.loc['PC1',col]
tipy = dfLoadings.loc['PC2',col]
#draw the vector, and write label text for col
ax2.arrow(0, 0, tipx, tipy, color = 'r', alpha = 0.5)
ax2.text(tipx*1.05, tipy*1.05, col, fontdict = font, ha = 'center', va = 'center')
#align x = 0 of ax and ax2 with the center of figure
mpl_axes_aligner.align.xaxes(ax, 0, ax2, 0, 0.5)
#align y = 0 of ax and ax2 with the center of figure
mpl_axes_aligner.align.yaxes(ax, 0, ax2, 0, 0.5)
plt.axhline(0,color="black",linestyle = 'dashed')
plt.axvline(0,color="black",linestyle = 'dashed')
plt.title("BIPLOT PCA - BOSTON HOUSES",fontdict = font1)
#show plot
plt.show()
Biplot
biplot(df_resultados, df_Loadings)