<jupyter_start><jupyter_text>SEMMA (Sample, Explore, Modify, Model,Assess)  En este libro de IPython encontraras la documentacion para la implementacion de la metodologia SEMMA con la descripcion de cada uno de los modulos, tomando como ejemplo el caso de estudio de calidad de aire.  SAMPLE En este modulo se accedera al dataset que sera un archivo csv, se observaran los atributos, el numero de registros y los valores que tienen.  El primer paso a seguir para la implementacion del codigo es aclarar los paquetes y funciones de cada paquete que necesitamos para el analisis estadistico, la visualizacion y establecer el acceso a los datos, por tanto, buscamos las comunmente utilizadas: Pandas, NumPy, SciPy, Matplotlib<jupyter_code>import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from scipy import stats
import math
import time
import scipy<jupyter_output><empty_output><jupyter_text>Extraemos el dataset con la funcion read_csv del paquete pandas<jupyter_code>datos= pd.read_csv("DatosAireCali.csv",header=0, sep=',')
datos<jupyter_output><empty_output><jupyter_text>Encontramos el numero de registros y la cantidad de atributos con la funcion shape<jupyter_code>dim=datos.shape
print dim<jupyter_output>(58325, 12)<jupyter_text>Vamos a extrar las variables que nos interesan del dataframe en el que almacenamos todos los datos del dataset<jupyter_code>ozono = datos["O3 (ug/m3)"]<jupyter_output><empty_output><jupyter_text>EXPLORE En este modulo se realizara la exploracion de los datos, se calculara las medias, quartiles, se definiran los valores atipicos, se descartaran para el calculo de valores finales de cada una de las variables.  Lo primero que vamos a aprender es la susceptibilidad de la media a valores atipicos y maximos o minimos relativos, lo que puede generar curvas extranas. A continuacion haremos el calculo de medias para las variables que tomamos en consideracion teniendo en cuenta los valores faltantes y valores atipicos<jupyter_code>media_ozono= np.mean(ozono)
#media_mono= np.mean(mono)
#media_benz= np.mean(benzeno)
#media_temp= np.mean(temp)
#media_hum= np.mean (humedad)<jupyter_output><empty_output><jupyter_text>Posteriormente, queremos observar el cambio al eliminar los valores atipicos, los valores faltantes, y finalmente reconociendo la media en el rango intercuartilico. Ahora vamos a reconocer los valores faltantes en cada uno de las variables  Con este comando devuelve una tabla booleana con True si el valor es un NaN o False si no lo es.<jupyter_code>valfal = pd.isnull(ozono)<jupyter_output><empty_output><jupyter_text>Ahora procedemos a eliminar los valores faltantes del dataframe creado para cada variable. Esto se realiza con el siguiente comando<jupyter_code>ozono_NoNan = ozono.dropna(how='any')
print ozono_NoNan
mean_ozonoNoNan = np.mean(ozono_NoNan)
print mean_ozonoNoNan<jupyter_output>24.4790858726<jupyter_text>Con esto nos damos cuenta que la funcion mean de numpy no tiene en cuenta los valores faltantes. Ahora para generacion de reportes posteriores hallamos la cantidad de valores faltantes en cada una de las variables<jupyter_code>tamano_ozono= len(ozono)
#print tamano_ozono
tamano_ozonoNoNan=len(ozono_NoNan)
#print tamano_ozonoNoNan
valFaltantes = tamano_ozono - tamano_ozonoNoNan
print "la cantidad de valores NaN eliminados fueron: ",valFaltantes<jupyter_output>la cantidad de valores NaN eliminados fueron:  44246<jupyter_text>Posteriormente iniciamos el analisis de valores atipicos. Ya que estamos en la fase de exploracion calculamos los percentiles 25 y 75 o en otras palabras los cuartiles 1 y 3 para posteriormente hallar el rango intercuartil, esto con el objetivo de analizar y entender la distribucion de los datos obtenidos en el dataset. Finalmente realizamos el diagrama de caja y un histograma para visualizar esto.<jupyter_code>Q1= np.percentile(ozono_NoNan,25)
#print Q1
Q3= np.percentile(ozono_NoNan,75)
#print Q3
IQR = Q3-Q1
plt.figure()
plt.subplot(1,2,1)
plt.boxplot([ozono_NoNan],whis=1.5)
plt.ylabel('Valor en(ug/m3)')
plt.xlabel('ozono')
plt.title('boxplot')
plt.subplot(1,2,2)
plt.hist(ozono_NoNan)
plt.ylabel('valor')
plt.xlabel('etiqueta')
plt.title('histograma ozono')
plt.show()<jupyter_output><empty_output><jupyter_text>Modify Continuando con la metodologia se inicia la fase de modificacion de los datos, donde dividimos en subconjuntos de valores atipicos y normales los datos de cada una de las variables. Contamos los valores iguales a 0 para finalmente determinar la fiabilidad de la muestra y evaluar el funcionamiento de los metodos de adquisicion de los datos.  Lo primero que debemos hacer es calcular el limite superior del diagrama de cajas, que equivale a sumar al valor del cuartil Q3 un cantidad de 1.5 veces el rango intercuartil (IQR), creamos los subconjuntos y segun la comparacion con el limite de consideracion se llenan los valores normales o atipicos segun corresponda<jupyter_code>def crearDatosOzono():
    archivo = open('datosNorOzono.txt','a')
    archivo.close()
crearDatosOzono()


bigsup = Q3 + 1.5*IQR
i=0
contaNor=0
contaAti=0
normal = np.zeros(tamano_ozonoNoNan)
atipico = np.zeros(tamano_ozonoNoNan)
ozonofinal=ozono_NoNan.as_matrix() #Se convierte de tipo series a tipo array 
compa=len(ozonofinal)

while i<compa: 
    valor=ozonofinal[i]
    if valor<bigsup:
        normal[contaNor]=valor
        contaNor=contaNor+1   
    else:
        atipico[contaAti]=valor
        contaAti=contaAti+1
    i=i+1<jupyter_output><empty_output><jupyter_text>Como paso siguiente debemos eliminar los valores 0 del arreglo que se introdujo en el paso anterior para que los calculos estadisticos que se deseen realizar a los subconjuntos no se vean afectados por los valores 0 que restaron del vector que se creo segun el tamano de la muestra que se traia desde la fase anterior. Para esto necesitamos contar la cantidad de posiciones con valor igual a 0 que se encuentra en cada uno de los arreglos o subconjuntos que se crearon<jupyter_code>tamanoNormal=len(normal)
j=0
ceros=0

while j<tamanoNormal:
    valr=normal[j]
    if valr ==0:
        ceros=ceros+1
    j=j+1

tamanoFinalNormal=tamanoNormal-ceros

tamanoAti=len(atipico)
k=0
cerosat=0 

while k<tamanoAti:
    valrat=atipico[k]
    if valrat==0:
        cerosat=cerosat+1
    k=k+1

tamanoFinalAtip=tamanoAti-cerosat<jupyter_output><empty_output><jupyter_text>Una vez contados los ceros introducidos o valores outliers se crean los vectores finales con el numero de posiciones exacto que permita llenar de manera definitiva los subconjuntos y de esta manera realizar un analisis descriptivo final para establecer posibles ajustes de las fases anteriores antes de continuar con la fase de modelado<jupyter_code>normalFinal=np.zeros(tamanoFinalNormal)
atipicoFinal=np.zeros(tamanoFinalAtip)
archivo = open('datosNorOzono.txt', 'w')
archivo.write(str('--VALORES NORMALES DE OZONO--\n'))
conta1=0
contNor=0
conta2=0
contAt=0
suma=0

while conta1<tamanoNormal:
    valcomp=normal[conta1]
    if valcomp!=0:
        normalFinal[contNor]=valcomp
        archivo.write(str(valcomp))
        archivo.write(str('\n'))
        suma = suma + valcomp
        contNor=contNor+1
    conta1=conta1 +1

media = suma/contNor  
archivo.close()

while conta2<tamanoAti:
    valcomp2=atipico[conta2]
    if valcomp2!=0:
        atipicoFinal[contAt]=valcomp2
        contAt=contAt+1
    conta2=conta2+1<jupyter_output><empty_output><jupyter_text>Una vez obtenidos los conjuntos finales con los valores normales, atípicos superiores e inferiores (teniendo en cuenta que los datos de los conjuntos representarán los valores de ozono obtenidos por el sensor en un día) Vamos a identificar cual es el dato que se enviara para ser almacenado finalmente. Para ello sacamos la Media aritmética de nuestro conjunto de datos normales, posteriormente verificamos que esta se encuentre dentro del intervalo de confianza para que sea un dato valido, puesto que; de no pertenecer al intervalo de confianza la media no representa un dato de relevancia y se debe optar por sacar la mediana aritmética del conjunto de valores normales como dato final del día.<jupyter_code>s = np.array(normalFinal)
n, min_max, mean, var, skew, kurt = stats.describe(s)
std=math.sqrt(var)

R = stats.norm.interval(0.95,loc=mean,scale=std / math.sqrt (len (s)))

print("el intervalo de confianza es: ",R) 
print("La media es: ", media)<jupyter_output>('el intervalo de confianza es: ', (16.53342734790634, 17.139701717213946))
('La media es: ', 16.836564532560104)<jupyter_text>En este bloque realizamos la comparacion de forma automatica para determinar si el valor final diario que almacenaremos  sera producto de la media o la mediana de nuestro conjunto de datos normales, una vez identificado generamos un documento de texto en el que se almacena el valor final diario de ozono, junto con su fecha y hora de registro.<jupyter_code>archivoFinal = open('datoFinalOzono.txt', 'a')
archivoFinal.write(str('--VALORES FINALES DIARIOS DE OZONO--\n'))
#media2=6.4
if (media > R[0]) & (media < R[1]):
    print ('la media si pertenece al intervalo')
    fecha = time.strftime("%x")
    hora = time.strftime("%X")
    archivoFinal.write(str(media))
    archivoFinal.write(str(' - '))
    archivoFinal.write(str(fecha))
    archivoFinal.write(str(' - '))
    archivoFinal.write(str(hora))
    archivoFinal.write(str('\n'))
    archivoFinal.close()
else:
    
    print('la media no pertenece al intervalo de confianza')
    datosOrdenados =  s
    datosOrdenados.sort()                                                                                
    #print normalFinal                                                                                  
                                                                                         
    if len(datosOrdenados) % 2 == 0:                                                                      
        n = len(datosOrdenados)                                                                           
        mediana = (datosOrdenados[n/2-1]+ datosOrdenados[n/2] )/2  
        print ('mediana:',mediana)
        fecha = time.strftime("%x")
        hora = time.strftime("%X")
        archivoFinal.write(str(mediana))
        archivoFinal.write(str(' - '))
        archivoFinal.write(str(fecha))
        archivoFinal.write(str(' - '))
        archivoFinal.write(str(hora))
        archivoFinal.write(str('\n'))
        archivoFinal.close()                                                    
    else:                                                                                    
        mediana =datosOrdenados[len(datosOrdenados)/2]                                                                 
        print ('mediana:',mediana)
        fecha = time.strftime("%x")
        hora = time.strftime("%X")
        archivoFinal.write(str(mediana))
        archivoFinal.write(str(' - '))
        archivoFinal.write(str(fecha))
        archivoFinal.write(str(' - '))
        archivoFinal.write(str(hora))
        archivoFinal.write(str('\n'))
        archivoFinal.close()
        
print ("Conjunto de valores Normales. ",normalFinal)
print ("Conjunto de valores atipicos superiores. ",atipicoFinal)    
#-------------------------------------------------------

biginf = Q1 - 1.5*IQR
i=0
contaNor=0
contaAti=0
normal = np.zeros(tamano_ozonoNoNan)
atipico = np.zeros(tamano_ozonoNoNan)
ozonofinal=ozono_NoNan.as_matrix() #Se convierte de tipo series a tipo array 
compa=len(ozonofinal)

while i<compa: 
    valor=ozonofinal[i]
    if valor>biginf:
        normal[contaNor]=valor
        contaNor=contaNor+1   
    else:
        atipico[contaAti]=valor
        contaAti=contaAti+1
    i=i+1
    

#-------------------------------------------------------
tamanoNormal=len(normal)
j=0
ceros=0

while j<tamanoNormal:
    valr=normal[j]
    if valr ==0:
        ceros=ceros+1
    j=j+1

tamanoFinalNormal=tamanoNormal-ceros
tamanoAti=len(atipico)  
cerosat=0 

while k<tamanoAti:
    valrat=atipico[k]
    if valrat==0:
        cerosat=cerosat+1
    k=k+1

tamanoFinalAtip=tamanoAti-cerosat
normalFinal2=np.zeros(tamanoFinalNormal)
atipicoFinal2=np.zeros(tamanoFinalAtip)

conta1=0
contNor=0
conta2=0
contAt=0

while conta1<tamanoNormal:
    valcomp=normal[conta1]
    if valcomp!=0:
        normalFinal2[contNor]=valcomp
        contNor=contNor+1
    conta1=conta1 +1

while conta2<tamanoAti:
    valcomp2=atipico[conta2]
    if valcomp2!=0:
        atipicoFinal[contAt]=valcomp2
        contAt=contAt+1
    conta2=conta2+1
    
    
#-------------------------------------------------------
print ("Conjunto de valores atipicos inferiores. ",atipicoFinal2)<jupyter_output>('Conjunto de valores atipicos inferiores. ', array([ 0.,  0.,  0., ...,  0.,  0.,  0.]))
{'fraction_non_alphanumeric': 0.09034634069895, 'fraction_numerical': 0.01708196207490989, 'mean_word_length': 3.4454893765238594, 'pattern_counts': {'":': 0, '<': 64, '<?xml version=': 0, '>': 54, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '212977', 'license': 'MIT', 'n_tokens_mistral': 4483, 'n_tokens_neox': 4367, 'n_words': 1237, 'path': 'SEMMA.ipynb', 'repo_name': 'fabian182gold/SEMMA-Sample-Explore-Modify-Model-Assess-', 'size': '12762'}