Análisis de regresión simple.Python

logo python

En este post realizaré un análisis de regresión, en el que tomaremos una set de datos preparado previamente.

El problema real al que nos enfrentamos, es determinar la relación que pueda existir entre la cantidad de ventas de la empresa “El Dorado”, y el numero de vendedores que la han integrado durante el periodo que se estudia, que son 36 meses o sea los últimos 3 años.

El departamento ha cambiado de responsable en varias ocasiones, y cada uno ha aplicado políticas diferentes de ventas, algunas intensivas, buscando mayor productividad en las ventas, a bases de estímulos como bonos, primas, ascensos,  etc; y en otras ocasiones, en cambio,  se han aplicado medidas extensivas incrementando el numero de vendedores, en una afán por ampliar la cobertura de ventas.

Lo que vamos a hacer es implementar un análisis de regresión lineal.

La regresion lineal es una técnica estadística, que el machine learning adoptó y que incluye como uno de los algoritmos supervisados.

He escrito hace unos meses algún articulo sobre regresion lineal y resumiendo lo que hara este análisis es obtener una recta que se acerque lo mas posible a todos los puntos de datos representados en un plano.

En nuestro caso es una regresion simple (participan dos variables ) y la recta que buscamos obtener es, la mejor posible.

Esto quiere decir que de todas las rectas esta sea la que mejor se adapte al conjunto de puntos, lo que le permitirá tendencialmente  estimar o predecir valores, dentro del contexto de datos estudiados.

La recta tiene forma esta forma Y = mX + b;  donde Y es el resultado obtenido, X es la variable, m la pendiente (o coeficiente) de la recta y b el valor constante, que gráficamente expresa el “punto donde cuando X tiene valor cero, se produce la intercepción o corte con el eje Y.

 Su optimización o ajuste se logra aplicándole una función llamada de mínimos cuadráticos, o también conocida de error cuadrático.

Su nombre obedece a que esa funcion intenta minimizar el error existente entre los puntos o dados y los obtenidos, elevendo al cuadrado sus valores para evitar que se anulen.

De este modo el algoritmo, se centra en minimizar el coste de dicha función

Recordemos que los algoritmos de Machine Learning Supervisados, aprenden por sí mismos.

Utilizaremos un archivo de datos que ya tenemos, y que muestra el número de  ventas y vendedores por meses; o sea tendremos dos columnas: vendedores y ventas.

Y nuestro en nuestro análisis de regresión, lo que vamos a intentar  es determinar a partir de los vendedores que tenemos,  que valor podemos esperar en la ventas de acuerdo, a la relación dada entre ambas variables.

Trabajaremos con Jupiter Notebook,utilizaremos las librerías Pandas, SkLearn, Seaborn, Numpy, de modo que comenzaremos por ahí.

Importamos las librerías

Cargamos nuestro archivo en un dataset de pandas después de leerlo, definiendo el separador de columnas.

Adquirimos  la información de nuestro dataset, con el método info(). Observamos que tenemos dos tipos de datos : enteros en columna vendedores y decimales en la columna ventas.

Comprobamos la estructura del dataset, con el método shape, que nos dice que tenemos efectivamente dos columnas y 36 registros en cada una.

Con head(), visualizamos las 6 primeras filas de nuestro dataset

Convertimos por comodidad la columna venta a tipo entero, empleando el método astype() y guardamos esa transformación en un nuevo dataset, que es con el que continuaremos trabajando.

Definimos con columns(), los encabezados de las columnas

Obtenemos los valores estadísticos de nuestro dataset con el método describe()

Observamos entre otros valores,  que la media de vendedores es 23, con una desviación de 4,63; mientras que la de ventas es 42 millones y su desviación es de 7.12.

Visualizamos los datos, en gráficos, mostrando las columnas por separados

Empleando scatter mostramos  los puntos coloreados, separando los colores a partir de la media de vendedores (23)

En este punto creamos nuestra recta de regresion y visualizamos los coeficientes que la componen nuestra recta.

Nuestro error cuadrático no es elevado pero es alto y nuestra varianza esta más cerca de 0 que de 1, por lo que este modelo tal vez podría mejorarse.

La intersección (b), tiene un valor de 9,67…. donde se corta la recta cuando el valor en X es 0

En función de observar el comportamiento del modelo, asignamos valores diferentes para ver su comportamiento

Ahora visualicemos la recta dentro de nuestro gráfico

Podemos observar nuestros datos de diferentes formas, en este caso con la librería seaborn, vemos el comportamiento de los datos en los diferentes periodos y su relación.

Para mejorarla tenemos varios caminos, podemos aplicar métodos como el gradiente, podemos hurgar en los datos y añadir más variables predictivas, referidas por ejemplo a la competencia, la innovación o la aceptación de los productos, pasando de una regresión simple a una regresión múltiple, podríamos también ampliar la cantidad de registros buscando mas años, desechar los valores extremos, etc.

En otros artículos iré aplicando algunos de estos métodos, haciendo referencia a estos mismos datos.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias

“El amor es la guerra perdida, entre el sexo y la risa”

R.Arjona

TypeError: ‘Index’ object is not callable

logo python

Si ante recibes este error al escribir esto en Pandas:

data_df.columns()

Se debe a que están intentado llamar el método de modo incorrecto.

Es un error común de principiante, porque intentas obligar a Pandas a que use cómo índice el propio índice que el establece.

El objeto index no puede llamarse , porque no es un atributo del dataframe, entonces no puede llamarlas de ese modo, según el concepto de la librería.

Por la misma causa podrías recibir el error SyntaxError: invalid syntax

Solución

data_df.columns

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias

“Sin   herramientas para imaginar tu secreto…..”

Y

Matplotlib. Gráficos de dispersión y línea.

logo python

Matplotlib es una biblioteca completa para crear visualizaciones estáticas, animadas e interactivas en Python.

Esta capacidad la hace especialmente importante, para la visualización de datos en estudios de inteligencia artificial.

Su amplia capacidad le permite trazar diferentes tipos de gráficos en Python (gráficos  : de dispersión,    circulares,   de líneas, histogramas, gráficos 3-D y muchos más.

Veremos en este articulo el uso de algunos de   ellos: los de dispersión y los de línea.

En lo adelante, escribiré otros artículos sobre los otros tipos.

Gráficos de dispersión  

Los gráficos de dispersión se utilizan para observar la relación entre variables y utiliza puntos para representar la relación entre ellas y cómo el cambio en una, afecta a la otra.

Gráficos de dispersión empleando el método plot()

El método plot(), acepta cuatro parámetros básicos, el eje de la x, el eje de la y, el tipo de marcador y el color de los puntos en el gráfico; e incluso estos dos últimos pueden obviarse.

De hacerlo plot(), colocará una línea por defecto, si no establecemos otro marcador, y el color azul.

La sintaxis es:

plt.plot(x, y, 'o', color='blue')

Gráficos de dipersión o scatter con el método pyplot()

El método se utiliza con la sintaxis siguiente:

matplotlib.pyplot.scatter()

El método scatter() en la biblioteca matplotlib se usa para dibujar un diagrama de dispersión.

Sintaxis

La sintaxis del método scatter() es:

matplotlib.pyplot.scatter(x_axis_data, y_axis_data, s = None, c = None, marker = None, cmap = None, vmin = None, vmax = None, alpha = None, linewidths = None, edgecolors = None)

El método scatter() toma los siguientes parámetros:

x_axis_data: una matriz que contiene datos del eje x
y_axis_data: una matriz que contiene datos del eje y
s: tamaño del marcador (puede ser escalar o una matriz de tamaño igual al tamaño de x o y)
c: color de secuencia de colores para rotuladores
marcador(marker): estilo del marcador
cmap- nombre de cmap
linewidths- ancho del borde del marcador
edgecolor- color del borde del marcador
alfa(opacidad): valor de mezcla, entre 0 (transparente) y 1 (opaco)

Excepto x_axis_data e y_axis_data, todos los demás parámetros son opcionales y su valor predeterminado es none.  

Metodo plot() versus pyplot()

Los métodos plot() y pyplot() difieren sobre todo, en su capacidad para adaptarse a las características de que necesitamos dotar a los gráficos, para expresar mejor nuestros datos.

La diferencia entre ellos, estriba en el volumen del dataset, sobre todo.

pyplot() ofrece una configuración más avanzada, que le permite dibujar con colores y tamaños diferentes cada punto, lo cual le obliga a renderizar una y otra vez, mientras plot(), solo dibuja de un solo color y tamaño todo el set.

En unos cientos de datos puede no notarse la diferencia, pero en grandes datasets, el uso de memoria puede hacerse sentir.

Este artículo mostraré algunos ejemplos de visualizar nuestros datos utilizando la librería matplotlib y ambos métodos.

Utilizaremos los datos que tenemos ya preparados en un archivo csv, en principio con solo dos columnas, ventas en millones de euros y vendedores.  

Comenzaremos importando las librerías y nuestro archivo

Examinamos la estructura del archivo y lo convertimos a int()

Para todas las gráficas de Matplotlib, se comienza creando una figura y un eje.

En su forma más simple, se pueden crear una figura y ejes de la siguiente manera:

figure(), es una instancia de la clase plt.figure(); la cual constituye un contenedor único que contiene todos los objetos que representan ejes, gráficos, texto y etiquetas.

Los ejes (axes), son a su vez una instancia de la clase plt.axes(),  que se ve como  el cuadro delimitador con marcas y etiquetas, que contendrá los elementos de la trama que componen nuestra visualización.

Normalmente utilizaré fig(); como la variable que contiene la instancia de figure, y ax() como la que contiene la instancia de la clase axes

Visualizamos con el uso de plt.plot().

El tercer argumento que le pasamos a la función, indica el tipo de símbolo que emplearemos.

En la primera figura mostramos nuestros datos y en la segunda los unimos con una línea, utilizando '–

Los marcadores que usamos, pueden ser diseñados a medida, como se ve debajo

Podemos hacer lo mismo con plot.scatter()

Emplearemos una función para trabajar nuestros gráficos. Veamos por ejemplo como mostrarlos en una gama de colores, que indican el peso de cada variable.

Podemos usar la función subplot()  de pyplot(), para mostrarlos de diferentes formas. Importaremos primero un dataset, con cuatro columnas para trabajar con más datos.

La instancia de pyplot(), permite establecer el  tamaño de la figura.

Usando el objeto ax devuelto, que se obtiene desde la función subplots(), y  llamamos  a la función scatter().

 

Mostremos varios gráficos en una sola visualización

Podemos también crear un grafico tridimensional

Gráficos de línea

El más sencillo de todos los gráficos es la visualización de una sola función del tipo  y = f(x).  

Veamos como crearlos

Creemos ahora varias líneas en un solo espacio

Podemos colorear las líneas con cualquier color, y pasándolo en diferentes formatos a través del parámetro color()

Podemos combinar emplear símbolos y  denominaciones para escoger el tipo de línea con el parámetro linestyle()

Ahora combinemos pasándolo directamente como un parámetro más, color y estilo de línea sin emplear linestyle()

Matplotlib, nos permite ajustar los limites de nuestro gráfico con el uso de los métodos plt.xlim()  y plt.ylim()

Su sintaxis es:

plt.xlim(10, 100)
plt.ylim(10, 90);

Podemos invertir los ejes, para ello bastara invertir su orden dentro del parámetro.

Axis

plt.axis()

Este método permite en una sola  llamada,  mezclar los diferentes parámetros del gráfico.

No debe confundirse axes con axis; plt.axis(), tiene una sintaxis asi

[xmin, xmax, ymin, ymax]:

Tight

Con tight podemos envolver los limites de nuestros puntos

Equal

Con equal garantizamos una relación de aspectos entre ambos ejes.

Etiquetar, nombrar e identificar el gráfico

También podemos por supuesto colocar los títulos del grafico, las leyendas etc.

Matplotlib, nos permite eso de un modo fácil.

En la imagen siguientes podemos ver ejemplos de como añadir etiquetas

Traducir de plt.plot() a ax.plot()

Si bien la mayoría de las funciones plt se traducen directamente a métodos ax (como plt.plot () → ax.plot (), plt.legend () → ax.legend (), etc.), este no es el caso para todos los comandos. En particular, las funciones para establecer límites, etiquetas y títulos se modifican ligeramente. Para realizar la transición entre funciones de estilo MATLAB y métodos orientados a objetos, realice los siguientes cambios:

plt.xlabel () → ax.set_xlabel ()

plt.ylabel () → ax.set_ylabel ()
plt.xlim () → ax.set_xlim ()
plt.ylim () → ax.set_ylim ()
plt.title () → ax.set_title ()

En la interfaz orientada a objetos para graficar, en lugar de llamar a estas funciones individualmente, a menudo es más conveniente usar el método ax.set () para establecer todas estas propiedades a la vez:

ax = plt.axes()
ax.plot(z, y)
ax.set(xlim=(0, 100), ylim=(10, 100),
    xlabel='quejas', ylabel='vendedores',
    title='Grafico simple');

Hasta aquí por hoy, en otros artículos hablaré de como trabajar con otros gráficos

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias

“…… justo todo lo que nos hace diferentes y superiores, nos hace peor y débiles: el oxigeno, la mente, la palabra, el amor, las creencias; y así un largo e inútil etc”

Y

Error UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xe1 in position …….

logo python

 La solución más rápida a este error, es emplear Sublime Text .

Abrimos nuestro archivo con sublime text y en la opción guardar con encoding guardarlo como UTF 8

Existen otras opciones, veamoslas

Codificar al leer el archivo

Hacer el encoding a UTF-8 al hacer el csv_read(), pasando en el parámetro encoding() la codificación que esperamos.

Importar   chardet y  codificar en la lectura del archivo.

import chardet
with open('data/atp-tour/data.csv', 'rb') as f: result = chardet.detect(f.read())
result['encoding']
Output: 'Windows-1252'

Si lanza un warning de LOW MEMORY se deberá principalmente a los tipos de adivinación por columna, están empleando mucha memoria.

Esto sucede en esencia, porque Pandas solo puede determinar qué tipo de dato tiene cada columna, solamente una vez que lee todo el archivo.

Puede ayudar especificar el tipo de archivo, indicándolo en el parámetro dtype , con la sintaxis.

dtype = {'user_id': int}

Esto es solo recomendable, si sabemos que no encontraremos otro tipo de dato en esa columna, si no cumplimos este precepto, complicaremos la situación , porque se bloqueará la carga.

Hay un poco mas sobre esto en este link

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias

Puedo absorber tus pecados, pero no vivir tu vida.

Y

Error. cannot convert non-finite values (NA or inf) to integer. Pandas

logo python

Si recibes este error, lo más probable es que en tu dataset, existan datos vacíos que no ves.

Sobre todo si has estado convirtiendo valores en Excel y posees un archivo de datos grandes, puede aparecer este error, al intentar convertir tus datos a enteros.

Solución:

Aplica al dataframe el método fillna(0), estarás llenando esos valores con valor 0, con esta sintáxis

data_df= data_df.fillna(0)

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias

“El amor es dos en uno que al final no son ninguno y se acostumbran a mentir”

R.Arjona

Programación lineal. Conceptos básicos.

Haciendo un ligero esbozo histórico, diré que la programación lineal, es una técnica que surgió en el primer tercio del siglo XX, y fue desarrollada, aplicándola a situaciones reales  para resolver problemas relacionados, con la programación, el transporte, y logística en los años, de la segunda guerra mundial.

Su creador fue el matemático ruso L. Kantorovich, y su aplicación inicial tuvo que ver con una optimización de los programas de  fabricación.

Sin embargo su aceptación, se extendió rápidamente a la economía y para 1950  el matemático estadounidense George Dantzig creó el primer algoritmo.

La programación lineal en esencia, es una función compleja que intenta determinar a partir de un conjunto de variables conocida, su influencia optima en determinados resultados.

Componentes de un problema de programación lineal

Las variables de decisión:

Son las cantidades, volúmenes o comportamientos, que se intentan estimar, como resultado.

La función objetivo:

Es la expresión matemática que intenta optimizar (maximizar o minimizar), algún valor numérico que representa ganancias, costos, cantidad de producción, volumen de inversión, etc;

Su razón de ser es evaluar, en qué medida cada variable de decisión contribuye al valor neto de una actividad económica especifica.

Coeficiente de la función:

Expresa la cantidad en la que el valor de la función objetivo cambiaría cuando se modifica una unidad de una variable de decisión, viene dada por el coeficiente de función objetivo correspondiente.

Restricciones:

Las restricciones son ecuaciones que limitan o definen la cantidad total de un recurso particular, que es necesario o requerido para llevar a cabo las actividades que decidirían el nivel de optimización de las variables de decisión.

Restricciones no negativas.

Una condición obligatoria de este tipo de restricciones, es que tienen que ser positivas con independencia, de que el objetivo de la función sea maximizar o minimizar el valor.

La solución óptima de un problema de programación lineal, es aquella que satisfaga mejor las restricciones.

Esto quiere decir que de todas las soluciones factibles, será óptima aquella que en el caso de una necesidad de maximización, el valor de la función objetivo sea el mayor posible, o sea el máximo.

Por el contrario, si nos encontramos ante un problema de minímización , la solución más adecuada será aquella donde la función objetivo ofrezca el mínimo.

Recursos disponibles

Constituyen los materiales, recursos, o elementos que participan en la ecuación y sobre los que se aplica la misma

Coeficientes tecnológicos

Cuando intentamos prever el futuro a través de la programación lineal, es importante considerar las limitaciones técnicas que nos impone la realidad objetiva y el entorno.

Los coeficientes tecnológicos, son elementos de referencia que conocemos y sobre los que se mueve el fenómeno que necesitamos estimar.  

La estructura de un problema de programación lineal debería ser algo como esto

Maximize  20* vd1 + 18*vd2; subject to
0.25*vd1 + 1*vd2  ≤60
1.40*vd1  + 0.5*vd2 ≤ 90 where vd1 & vd2 ≥ 0

Aquí podemos identificar los diferentes componentes:

vd1 y vd2 son las variables de decisión

Maximize  20* vd1 + 18*vd2 es la función objetivo

20* vd1  y  18*vd2 son los coeficientes de la función

0.25*vd1 + 1*vd2  ≤  60 es la primera restricción

1.40*vd1  + 0.5*vd2  ≤  90 es la segunda restricción

vd1 & vd2  ≥ 0 es la restricción negativa

0.25, 1, 1.40, 0.5 son los coeficientes tecnológicos

65, 90 es la disponibilidad de recursos

Elementos importantes

Potenciación

Partimos de considerar que las variables de decisión, siempre tienen una potencia de uno.

La condición critica

Para poder aplicar un problema  de programación lineal, es necesario tener definidas: la función objetivo, la disponibilidad de recursos y las variables de decisión positivas relacionadas entre sí.

Dualidad

Todo problema de programación lineal, puede convertirse a  su par correspondiente,  capaz de dar la misma solución factible de la función objetivo.

Esto lo puede hacer de modo automático el programa con el que trabajemos, pero conocer su esencia es importante.

Cuando se trata, por ejemplo de un problema de maximización, por lógica todas las restricciones asociadas con su función objetivo serán del tipo “menor que igual a” la disponibilidad de recursos dada, (podría ser solo “igual a”, en el caso de una   restricción en particular restringida)

Si eso no sucediese y alguna restricción fuera del tipo “mayor que igual a” lo recomendable es convertir la solución a una forma canónica (multiplicar por un “menos”) para que la restricción del problema de maximización se transforme en “menor que igual a” .

Por oposición si fuera un problema de minimización, entonces todas las restricciones asociadas con la función objetivo deben tener restricciones “mayor que igual a” a la disponibilidad de recursos considerada, a menos que exista alguna restricción que particularmente no esté restringida (tipo “igual a”), lo adecuado es multiplicar por -1, para convertirlas. 

Antes de la dualidad

Antes de proceder con un ejercicio de dualidad es necesario que las variables de decisión sean igual  mayor que cero, de no ser asi necesitan ser transformadas de forma canonical.

En Python podemos trabajar los problemas de programación lineal con Ipsolve.

Por ultimo, decir que la programación lineal, se basa en la creación de modelos cuando el problema que necesitamos resolver tiene solo funciones lineales, esto es :

Tenemos variables de decisión conocidas y queremos saber que influyen en un problema dado.

Dicho de otro modo: el concepto programación lineal  no se enmarca dentro de la programación de computadoras, sino que se refiere a escoger una vía de solución cuando el modelo matemático del problema contiene solo funciones lineales

Este articulo, pretende solo ser un esbozo de los conceptos más básicos de la solución a problemas de programación lineal.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias

“… y yo tenia respuesta a todas sus preguntas, incluso a las que aún no se ha hecho.”

Y

Indicar el separador en archivo csv en Mac, con Python(sep).

logo python

Ante todo, esta es una solución para personas que trabajen con Python y la librería Pandas, para no programadores, la solución es otra.

Un problema común, es que al crear un archivo csv, cometamos una equivocación y nuestro archivo no se visualice correctamente, lo que nos traerá problemas, sí como es mi caso quiero emplearlo como dataset en Python.

Digamos que tengo un archivo del tipo  Excel, con dos columnas “vendedores” y “ventas”.

La columna “vendedores” tiene valores enteros, y la columna “ventas”, valores decimales.

La dificultad a la que nos enfrentamos es que en Mac, para cambiar el separador hay que ir hasta el propio registro que establece los separadores decimales, de todo el sistema, ya sea directamente o mediante comandos(solución para no programadores).

Siendo como soy, enemigo de tocar lo que no debo tocar, para evitar errores futuros de los cuales olvidaré la causa, busqué una solución más sencilla, que ya existe en el “abc” de Pandas. El argumento sep().

Cuando creaba un csv, ya sea en formato UTF 8, o csv para Mac,  lo que hacia era separarme las filas por , coma y no punto y coma.

Pandas resuelve esto fácilmente, con él parámetro sep(), que permite escoger el separador en una cadena dada.

Veremos la salida del mismo archivo dos veces, sin utilizar sep y dándole uso.

Sin usar sep

 Utilizando sep

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias

Y yo tenia respuesta a todas sus preguntas, incluso a las que aún no se ha hecho.

Y