Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

PC01

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 43

UNIVERSIDAD NACIONAL DE INGENIERÍA

FACULTAD DE INGENIERÍA INDUSTRIAL Y DE SISTEMAS

ANALÍTICA DE DATOS

Practica Nº1: Ventas Telsur Comunicaciones S.A.C

Integrantes:
Lescano Avalos Miguel Angel 20161212D
Pazce Alama Patricia Elena 20162612F
Timana Mendoza Abelardo 20152582G
Obregon Zavaleta Harold André 20161081G

Docente:

ARADIEL CASTAÑEDA, HILARIO

2020
ÍNDICE

1.Descripción del negocio 3


1.1 Modelo de negocio 3
1.2 Proceso del negocio 4
1.3 Actores del negocio 4
1.4 Productos 5

2. Base de datos de Ventas 6

3. Solución de la práctica 8
3.1 Manejo de filas y columnas: visualización y filtrado 8
3.2 Valores perdidos de cada columnas y filas duplicadas 9
3.3 Outliers 10
3.4 Recta lineal y su correlación R 10
3.5 Gráficos Estadísticos: tablas de frecuencia, diagrama de Pareto, mapa de calor, pie,
etc 13
3.6 Análisis de Componentes Principales 21
3.7 Nube de palabras 29
3.8 Pre Procesamiento de Datos: Variables Dummy (One Hot Encoding) 34
3.9 Algoritmo Apriori 35

1.Descripción del negocio


Telsur Comunicaciones S.A.C es una pequeña empresa peruana distribuidor de Claro
que tiene como objetivo brindar los servicios ventas de Claro en las provincias de Cañete,
distribuye productos como celulares, Internet, Accesorios para celulares, etc.

Misión
Distribuir los productos y servicios de Claro a las personas del sur de lima, en el menor
tiempo posible, cumpliendo con los estándares de calidad y brindándole una buena
atención y generando confianza al cliente.

Visión
Ser la empresa líder de distribución telefónica en la provincia de Cañete y Lima, brindando
la mejor atención y confianza en sus productos. Además de ofrecer servicios de atención
al cliente para atender consultas y reclamos de los clientes.

1.1 Modelo de negocio


La empresa Telsur comunicaciones es una empresa que distribuye productos de claro al
por mayor y menor actualmente se encuentra distribuyendo delivery contactandose con
sus clientes por whatsapp o llamada y también realizando ventas en sus 2 locales.
A continuación se muestra la siguiente figura 1 con las áreas de la empresa:

Figura 1 : Áreas de la Empresa Telsur Comunicaciones S.A.C

1.2 Proceso del negocio


Posteriormente vemos en la siguiente figura 2 algunos procesos que realiza la empresa
de los cuales poseen un sistema para los procesos de facturación, control de inventario y
control de personal. Por lo que se trabajará solo los procesos de venta y entrega delivery.
Figura 2 : Diagrama de Caso Uso de Negocio de la Empresa Telsur Comunicaciones
S.A.C

1.3 Actores del negocio


Cliente Son las personas que compran los productos de Telsur comunicaciones.

Usuario Son las personas que trabajan para telsur comunicaciones entre
ellas tenemos: vendedor, administrador, contador y gerente.
● Vendedor : Brinda información sobre los productos y realiza la
venta de dicho producto.
● Administrador: Solicita los recursos logísticos a Claro para la
venta y gestiona el recurso humano.
● Contador : Encargado de realizar informes financieros y
tributarios de la empresa.
● Gerente : Encargado de tomar decisión como inversión,
nuevos eventos y establecer relaciones con Claro.

1.4 Productos
Los productos se dividen en tres categorías principales: Claro Hogar, Equipos Postpago
e Internet fijo inalámbrico.
Figura 3 : Productos de la Empresa Telsur Comunicaciones S.A.C

1. Claro Hogar: Venta de planes telefónicos y de internet

2. Equipos Postpago: Venta de equipos celulares. La empresa comercializa con una


alta variedad de productos como: Huawei, LG, Motorola, entre otros.

Figura 4 : Equipos Postpago de la Empresa Telsur Comunicaciones S.A.C

3. Internet fijo inalámbrico: Vendo modem para internet para el hogar

4. Accesorios: Cargadores, Mica, Protectores, Micas, Memoria

2. Base de datos de Ventas


Actualmente los datos son extraídos del software denominado TIWI que es un software para
la venta, facturacion e inventarios de los productos que ofrece Telsur comunicaciones. La
empresa tiene actualmente una licencia de administrador y 2 de operarios ( vendedores
para las dos tiendas que posee).

Figura 5 : Interfaz Principal del Software Tiwi

A continuación presentamos en la Tabla 1 los campos que son almacenados por el sistema
TIWI para la empresa Telsur Comunicaciones S.A.C.

TABLA 1: Descripción de los campos de la base de datos de ventas de Telsur


Comunicaciones S.A.C
Campos Descripción

Tipo de Existen 2 tipos de distribución: Punto de venta y Delivery .


Distribución Actualmente el sistema solo almacena punto de venta.

Lugar de Entrega Indica el lugar de entrega del producto al cliente. Los puntos de
ventas actualmente son 2: Tienda 1 y Tienda 2.

FECHA Indica la fecha de registro del inicio de la venta del producto


(sistema).

FECHA Indica la fecha de registro final de la venta del producto(sistema).


REGISTRO

COMPROBANTE Indica el tipo de comprobante. Actualmente el sistema solo entrega


ticket. Sin embargo se entregan boletas, facturas, etc.
SERIE Indica el número de serie y actualmente solo usan el 0001 debido a
que solo tienen un sistema de facturación.

NÚMERO Indica el número de ticket entregado.

CLIENTE Indica el nombre y el apellido de la persona que ha realizado la


compra.

TELÉFONO Indica el teléfono de los clientes.

DOCUMENTO Indica el DNI de los clientes.

DIRECCIÓN Indica la dirección del cliente.

PRODUCTO Indica el bien o servicio que ha sido vendido.

AREA Indica el grupo (familia) de producto que pertenece

TIPO Indica el tipo de producto correspondiente

IMEI Indica el identificador único del equipo celular vendido

NUMERO Indica el numero de telefono del celular vendido.


TELEFONO

PLAN Indica el plan del celular o chip vendido. Puede ser planes postpago,
prepago,Recuperación, Renovación.

MONTO PLAN Indica la cantidad de pago mensual o efectivo deacuerdo al plan

MÉTODO PAGO Indica el método de pago. La empresa actualmente trabaja solo con
efectivo.

VENDEDOR Indica el nombre del vendedor

CLASE Indica el tipo de producto: Bien o servicio

OBSERVACIÓN Especifica características del Plan

CANTIDAD Cantidad de productos adquiridos por el cliente

FACTURADO Monto total de vental al cliente

NETO Diferencia entre facturado - impuestos por IGV

IGV Indica el porcentaje de impuesto por venta

ESTADO Indica el estado de la venta.


3. Solución de la práctica
3.1 Manejo de filas y columnas: visualización y filtrado
a) Cambiando a formato Fecha

TS["FECHA"]= pd.to_datetime(TS["FECHA"])
TS["Dia"]= TS["FECHA"].dt.day
TS["Año"]= TS["FECHA"].dt.year
TS["Mes"]= TS["FECHA"].dt.month
TS["Año"].astype(int)
TS["Mes"].astype(int)
TS["Dia"].astype(int)

TS["FECHA REGISTRO"]= pd.to_datetime(TS["FECHA REGISTRO"])


TS["Dia REGISTRO"]= TS["FECHA REGISTRO"].dt.day
TS["Año REGISTRO"]= TS["FECHA REGISTRO"].dt.year
TS["Mes REGISTRO"]= TS["FECHA REGISTRO"].dt.month
TS["Año REGISTRO"].astype(int)
TS["Mes REGISTRO"].astype(int)
TS["Dia REGISTRO"].astype(int)
TS.head()

b) Mostrando las filas con algún NULL / NaN / NaT


Las siguientes líneas de código muestran la cantidad de valores NULL / NaN / NaT, las filas
que son nulas (1610 filas x 29columnas) y las 5 últimas filas filtradas.
df2.size
print(df2)
df2.tail()

3.2 Valores perdidos de cada columnas y filas duplicadas

a) Eliminando filas con algun elemento Vacios o nulo (NULL / NaN / NaT)
TS = TS.dropna(subset=['NETO'])
Actualizando Indices
TS = TS.reset_index(drop=True)

b) Mostrando las filas duplicadas


Las siguientes líneas de código muestran las filas duplicados
duplicate = TS[TS.duplicated()]
duplicate.head()
3.3 Outliers
a) Eliminando las filas cuyos montos facturados no están dentro de las 3 desviaciones
estándar
#Eliminando Filas con montos facturados no están dentro de las 3
desviaciones estándar
TS=TS[np.abs(TS.FACTURADO_SOLES-TS.FACTURADO_SOLES.mean()) <=
(3*TS.FACTURADO_SOLES.std())]
#Actualizando Índices
TS = TS.reset_index(drop=True)
TS.tail()

3.4 Recta lineal y su correlación R


a) Determinando Tabla de facturación mensual para formar la recta.
import matplotlib.pyplot as plt
total_recaudado = TS.groupby(['Mes'])
['FACTURADO_SOLES'].sum().reset_index()
plt.plot(total_recaudado["Mes"],total_recaudado["FACTURADO_SOLES"])
plt.title("Promedio de Dinero Recaudado por Mes")
plt.xlabel("Meses")
plt.ylabel("Promedio de Dinero Recaudado" )
plt.show()
total_recaudado.head()

b) Generando la recta

#Generando los parámetros de la ecuación de la recta


denominador= total_recaudado['Mes'].dot(total_recaudado['Mes'])-
total_recaudado['Mes'].mean()*total_recaudado['Mes'].sum()
m = (total_recaudado['Mes'].dot(total_recaudado['FACTURADO_SOLES'])-
total_recaudado['FACTURADO_SOLES'].mean()*total_recaudado['Mes'].sum())
/denominador
b =
(total_recaudado['FACTURADO_SOLES'].mean()*total_recaudado['Mes'].dot(t
otal_recaudado['Mes'])-
total_recaudado['Mes'].mean()*total_recaudado['Mes'].dot(total_recaudad
o['FACTURADO_SOLES']))/denominador
Y=m*total_recaudado['Mes']+b
#Generando la recta
plt.scatter(total_recaudado['Mes'],Y)
plt.plot(total_recaudado['Mes'],Y,'r')

c) Determinando el valor del coeficiente de determinación

RES= total_recaudado['FACTURADO_SOLES']-Y
TOT=total_recaudado['FACTURADO_SOLES']-
total_recaudado['FACTURADO_SOLES'].mean()
R2=1-(RES.dot(RES)/TOT.dot(TOT))
print(R2)

El resultado del coeficiente de determinación es:

El R² resultó 0.04, tal como se indicó líneas arriba, el valor al


ser bajo demuestra que la recta lineal no es el mejor modelo de proyección para
estos datos.
3.5 Gráficos Estadísticos: tablas de frecuencia, diagrama de
Pareto, mapa de calor, pie, etc
a) Grafico comparativo entre facturacion mensual de tiendas
import seaborn as sns
total_recaudado = TS.groupby(['Mes','Lugar de Entrega'])
['FACTURADO_SOLES'].sum().reset_index()
sns.lineplot(data=total_recaudado,x="Mes",
y="FACTURADO_SOLES",hue='Lugar de Entrega');

El gráfico muestra el monto total facturado en soles por cada tienda. Al igual que el
gráfico anterior, el mes de Septiembre es en el que se realizaron mayor cantidad de
ventas en ambas tiendas.Por otra parte, en el Mes de octubre, se nota una diferencia
de mas de 5 000 soles en ingresos entre las tiendas.

import seaborn as sns


sns.regplot(x="Mes", y="FACTURADO_SOLES", data=total_recaudado);

b) Creando Histograma
El histograma muestra la cantidad de ventas de cada mes en todo el negocio
(ambas tiendas). Comparándolo con los gráficos anteriores, en el mes de noviembre
se nota que se realizaron más transacciones que en octubre, sin embargo el monto
facturado de éste es superior al de noviembre. El mes de Diciembre se reportaron
pocas transacciones debido a que la data se recolectó los primeros días de dicho
mes.
plt.hist(TS['Mes'])
plt.show

Este histograma fue hecho usando la librería seaborn. A comparación del anterior, que se
realizó usando Matplotlib, este tiene un diseño más claro debido a la separación de cada
barra.
sns.displot(TS['Mes'])
plt.show
Gráfico que muestra el top 20 de los productos más vendidos. Como se puede
observar, los chips y las recargas son los que abarcan un gran porcentaje de las
transacciones.

df3=TS.copy()
df3=df3.groupby(["PRODUCTO"])["FACTURADO_SOLES"].count().reset_index()
df3=df3.sort_values("FACTURADO_SOLES",ascending=False)
sns.barplot(x="FACTURADO_SOLES",y="PRODUCTO",data=df3[0:20])
plt.xlabel("Top Productos Vendidos")
plt.show()

d) Diagrama de pareto

Se muestra el diagrama de pareto de todos los productos del negocio. Debido a la


concentración de datos, se realizará otro diagrama con los 10 principales productos.

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter
fig, ax = plt.subplots()
ax.bar(df3["PRODUCTO"], df3["FACTURADO_SOLES"], color="C0")
ax2 = ax.twinx()
ax2.plot(df3["PRODUCTO"], df3["porcentajes"], color="C1", marker="D",
ms=7)
ax2.yaxis.set_major_formatter(PercentFormatter())

ax.tick_params(axis="y", colors="C0")
ax2.tick_params(axis="y", colors="C1")
plt.setp(ax.get_xticklabels(), rotation=90,
horizontalalignment='right')
plt.show()
Tomando los 10 productos principales aplicamos pareto
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter
fig, ax = plt.subplots()
ax.bar(df3["PRODUCTO"], df3["FACTURADO_SOLES"], color="C0")
ax2 = ax.twinx()
ax2.plot(df3["PRODUCTO"], df3["porcentajes"], color="C1", marker="D",
ms=7)
ax2.yaxis.set_major_formatter(PercentFormatter())
ax.tick_params(axis="y", colors="C0")
ax2.tick_params(axis="y", colors="C1")
plt.setp(ax.get_xticklabels(), rotation=60,
horizontalalignment='right')
plt.show()
Más del 80% de los ingresos proviene de celulares de la marca motorola, samsung A1,
Xiaomi y LG K20 mientras que el resto es de A10S y APP IPHXS

e) PIE

Data=df9['CANTIDAD'].reset_index()
Data.head()

my_data=Data['CANTI DAD']
my_labels=Data['VENDEDOR']
plt.pie (my_data, labels = my_labels, autopct = '% 1.1f %%')
plt.title ('Mi título')
plt.axis ('equal')
plt.show ()

El siguiente gráfico muestra los porcentajes de la cantidad de productos vendidos de cada


vendedor.

my_data=Data['CANTIDAD']
my_labels=Data['VENDEDOR']
my_explode = (0, 0.1, 0)
my_colors = ['lightblue','lightsteelblue','silver']
plt.pie(my_data, labels=my_labels, autopct='%1.1f%%', startangle=15,
shadow = True, colors=my_colors, explode=my_explode)
plt.title('% DE TRANSACCIONES POR CADA VENDEDOR')
plt.axis('equal')
plt.show()
Se observa que la vendedora con más productos vendidos es Sheyla Flores, con
más del 53%. Por otro lado, Julia Chavez es la vendedora con menor rendimiento.
Esto se puede explicar, ya que esta vendedora trabaja por las mañanas, y como se
vió en el mapa de calor, las ventas en esas horas son muy bajas.

3.6 Análisis de Componentes Principales


Componentes Principales:
● ÁREA: Campo que agrupa a los productos en familias.
● TIPO: Engloba los tipos de productos por cada área

ÁREA TIPO

PREPAGO
CHIPS
RECARGA

CLARO

EQUIPOS CELULARES

OTROS

ACCESORIOS

... ...

AUDIFONO

CARGADOR

ACCESORIOS TECLITAS

MICA

PROTECTOR

OTROS

Análisis Campo ÁREA


#Histograma General AREA de productos
import matplotlib.pyplot as plt
plt.hist(T2['AREA'])
plt.show

#Conteo de cada TIPO por AREA de producto


T2['TIPO'].value_counts(dropna=False)

Análisis Segmentado por Área: CHIP


#histograma segmentado del area chip
versichip = T2[T2['AREA'] == 'CHIP']
num_bins = 10
histo_tipo = plt.hist(versichip['TIPO'],num_bins)
#Mes donde se vendieron mas productos de la familia chip
sns.distplot(versichip['Mes'],num_bins,color = 'red')

#Tienda donde se vendieron más productos de la familia chip


histo_tienda = plt.hist(versichip['Lugar de Entrega'])
#Total recaudado por la venta productos de la familia chip en los meses
total_recaudado3 = versichip.groupby(['Mes'])
['FACTURADO_SOLES'].sum().reset_index()
plt.plot(total_recaudado3["Mes"],total_recaudado3["FACTURADO_SOLES"])
plt.title("Promedio de Dinero Recaudado de Chips por Mes")
plt.xlabel("Meses")
plt.ylabel("Promedio de Dinero Recaudado" )
plt.show()

Análisis Segmentado por Área: ACCESORIOS


#histograma segmentado del área accesorios
versiacc = T2[T2['AREA'] == 'ACCESORIOS']
num_bins = 10
plt.hist(versiacc['TIPO'],num_bins)

#Mes donde se vendieron más productos de la familia accesorios


sns.distplot(versiacc['Mes'],num_bins,color = 'green')

#Tienda donde se vendieron más productos de la familia accesorios


histo_tienda = plt.hist(versiacc['Lugar de Entrega'])
#Total recaudado por la venta productos de la familia accesorios en los
meses
total_recaudado2 = versiacc.groupby(['Mes'])
['FACTURADO_SOLES'].sum().reset_index()
plt.plot(total_recaudado2["Mes"],total_recaudado2["FACTURADO_SOLES"])
plt.title("Promedio de Dinero Recaudado de Accesorios por Mes")
plt.xlabel("Meses")
plt.ylabel("Promedio de Dinero Recaudado" )
plt.show()

Análisis Segmentado por Área: EQUIPOS


#histograma segmentado del area equipos
versieqp = T2[T2['AREA'] == 'EQUIPOS']
num_bins = 10
histo_tipo = plt.hist(versieqp['TIPO'],num_bins)

# Mes donde se vendieron más productos de la familia equipos


sns.distplot(versieqp['Mes'],num_bins,color = 'orange')

#Tienda donde se vendieron más productos de la familia equipos


histo_tienda = plt.hist(versieqp['Lugar de Entrega'])
#Total recaudado por la venta productos de la familia equipos en los
meses
total_recaudado4 = versieqp.groupby(['Mes'])
['FACTURADO_SOLES'].sum().reset_index()
plt.plot(total_recaudado4["Mes"],total_recaudado4["FACTURADO_SOLES"])
plt.title("Promedio de Dinero Recaudado de Equipos por Mes")
plt.xlabel("Meses")
plt.ylabel("Promedio de Dinero Recaudado" )
plt.show()
3.7 Nube de palabras
Librerías Utilizadas

#Librerías básicas
import numpy as np
import pandas as pd

#Librerías necesarias para el scraping


import requests
from bs4 import BeautifulSoup

#Librerías necesarias para abrir imágenes, generar nube de palabras y


plot
from PIL import Image
from wordcloud import WordCloud, ImageColorGenerator
import matplotlib.pyplot as plt

#Librerías necesarias para la limpieza de datos


import string
import nltk
from nltk.corpus import stopwords

Obtención de Textos

def get_texto_url(list_webs):

headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)


AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121
Safari/537.36",
"Accept-Encoding": "*", "Connection": "keep-alive"
}

texto =" "


long=0
for url in webs:

try:
web = requests.get(url, headers=headers)

soup = BeautifulSoup(web.text)
parrafos = soup.find_all('p')

for p in parrafos:
long += len(p.text)
texto += " "+ str(p.text)

except:
print("Error en la url {}, response {}".format(url,web))

print("Se han añadido un total de {} caractéres a la variable


texto".format(long))
return texto
################
webs = ["https://tiendaclaro.pe/",
"https://www.claro.com.pe/personas/movil/postpago/",
"https://www.evaluacionclaro.pe/",
"https://planesclaro.com.pe/",
"https://miasesorsmart.com/equipos-movistar-claro-entel-y-
bitel/",
"https://pe.celulares.com/claro",
"http://neuf.com.pe/?fbclid=IwAR2IxzVAiNd-
X6E4XmsPyDpJVnSume_B4O3vl05atTnKREePysUBRpf-9rI",
"https://www.telco.pe/",
"https://www.claro.com.pe/empresas/",
"https://www.teytel.com.co/teytel/servicio/planes-
moviles/planes-moviles"]

texto = get_texto_url(webs)

Se han añadido un total de 9227 caractéres a la variable texto

Limpieza

punctuation=[]
for s in string.punctuation:
punctuation.append(str(s))
sp_punctuation = ["¿", "¡", "“", "”", "…", ":", "–", "»", "«"]

punctuation += sp_punctuation

punctuation[:10]
['!', '"', '#', '$', '%', '&', "'", '(', ')', '*']
################
nltk.download('stopwords')

[nltk_data] Downloading package stopwords to /root/nltk_data...


[nltk_data] Package stopwords is already up-to-date!
True

stop_words = stopwords.words('spanish')

stop_words += ["\u200b", "\xa0", "para", "como", "puede","cómo",


"hacer", "forma", "parte", "hace", "además", "según", "pueden", "ser",
"claro","product","view","avs","max","mayor","iva","nicolás","arco", ]

#Reemplazamos signos de puntuación por "":


for p in punctuation:
clean_texto = texto.lower().replace(p,"")

for p in punctuation:
clean_texto = clean_texto.replace(p,"")

#Eliminamos espacios blancos, saltos de línea, tabuladores, etc


clean_texto = " ".join(clean_texto.split())

#Reemplazamos stop_words por "":


for stop in stop_words:
clean_texto_list = clean_texto.split()
clean_texto_list = [i.strip() for i in clean_texto_list]
try:
while stop in clean_texto_list: clean_texto_list.remove(stop)
except:
print("Error")
pass
clean_texto= " ".join(clean_texto_list)

Análisis de las palabras de Texto

lista_texto = clean_texto.split(" ")

palabras = []

#Paso intermedio para eliminar palabras muy cortas (emoticonos,etc) y


muy largas (ulr o similar) que se nos hayan pasado:
for palabra in lista_texto:
if (len(palabra)>=3 and len(palabra)<18):
palabras.append(palabra)
#Generamos un diccionario para contabilizar las palabras:

word_count={}

for palabra in palabras:


if palabra in word_count.keys():
word_count[palabra][0]+=1
else:
word_count[palabra]=[1]

#Visualizamos los datos


df = pd.DataFrame.from_dict(word_count).transpose()
df.columns=["freq"]
df.sort_values(["freq"], ascending=False, inplace=True)
df.head(10)

def plot_bar(data=df, top=5):


fig = plt.figure()
ax = fig.add_axes([0,0,2,1])
ax.bar(x =df.iloc[:top,:].index, height = df.iloc[:top,0].values)
plt.show()
#Graficamos el TOP 5 palabras por frecuencia

plot_bar(data=df, top=5)
Nube de Palabras

word_cloud = WordCloud(height=800, width=800,


background_color='white',max_words=150,
min_font_size=5).generate(clean_texto)

word_cloud.to_file("ejemplo_sencillo.png") #Guardamos la imagen


generada

plt.figure(figsize=(10,8))
plt.imshow(word_cloud)
plt.axis('off')
plt.tight_layout(pad=0)
plt.show()
3.8 Pre Procesamiento de Datos: Variables Dummy (One Hot
Encoding)

Las variables dummy corresponderá a los campos: AREA y TIPO de la tabla (T2)

area_dummy = pd.get_dummies(T2["AREA"],prefix="AREA")
tipo_dummy = pd.get_dummies(T2["TIPO"],prefix="AREA")

Agregamos las variables a la tabla

T2 = pd.concat([T2, area_dummy], axis = 1)


T2 = pd.concat([T2, tipo_dummy], axis = 1)

Cortamos las columnas innecesarias y mostramos los valores iniciales de la tabla

T2_dummies =
T2.drop(T2.columns[[0,1,2,3,4,5,6,7,8,9,10,14,15,16,17,18,19,20,21,22,2
3,25,26,27,28,29]], axis = 1)
T2_dummies.head()

3.9 Algoritmo Apriori


El algoritmo Apriori es comúnmente usado para sistemas de recomendación, como
en el caso del historial de compra en ventas, o sistema de recomendación de
películas.

Se importa las librerias


import sys
import csv
import argparse
import json
import os
from collections import namedtuple
from itertools import combinations
from itertools import chain

Se crea las clases de apriori:


class TransactionManager(object):
"""
Transaction managers.
"""

def __init__(self, transactions):


"""
Initialize.

Arguments:
transactions -- A transaction iterable object
(eg. [['A', 'B'], ['B', 'C']]).
"""
self.__num_transaction = 0
self.__items = []
self.__transaction_index_map = {}

for transaction in transactions:


self.add_transaction(transaction)

def add_transaction(self, transaction):


"""
Add a transaction.

Arguments:
transaction -- A transaction as an iterable object (eg.
['A', 'B']).
"""
for item in transaction:
if item not in self.__transaction_index_map:
self.__items.append(item)
self.__transaction_index_map[item] = set()
self.__transaction_index_map[item].add(self.__num_transacti
on)
self.__num_transaction += 1

def calc_support(self, items):


"""
Returns a support for items.

Arguments:
items -- Items as an iterable object (eg. ['A', 'B']).
"""
# Empty items is supported by all transactions.
if not items:
return 1.0

# Empty transactions supports no items.


if not self.num_transaction:
return 0.0

# Create the transaction index intersection.


sum_indexes = None
for item in items:
indexes = self.__transaction_index_map.get(item)
if indexes is None:
# No support for any set that contains a not existing
item.
return 0.0

if sum_indexes is None:
# Assign the indexes on the first time.
sum_indexes = indexes
else:
# Calculate the intersection on not the first time.
sum_indexes = sum_indexes.intersection(indexes)

# Calculate and return the support.


return float(len(sum_indexes)) / self.__num_transaction

def initial_candidates(self):
"""
Returns the initial candidates.
"""
return [frozenset([item]) for item in self.items]

@property
def num_transaction(self):
"""
Returns the number of transactions.
"""
return self.__num_transaction

@property
def items(self):
"""
Returns the item list that the transaction is consisted of.
"""
return sorted(self.__items)

@staticmethod
def create(transactions):
"""
Create the TransactionManager with a transaction instance.
If the given instance is a TransactionManager, this returns
itself.
"""
if isinstance(transactions, TransactionManager):
return transactions
return TransactionManager(transactions)

# Ignore name errors because these names are namedtuples.


SupportRecord = namedtuple( # pylint: disable=C0103
'SupportRecord', ('items', 'support'))
RelationRecord = namedtuple( # pylint: disable=C0103
'RelationRecord', SupportRecord._fields + ('ordered_statistics',))
OrderedStatistic = namedtuple( # pylint: disable=C0103
'OrderedStatistic', ('items_base', 'items_add', 'confidence',
'lift',))

def create_next_candidates(prev_candidates, length):


"""
Returns the apriori candidates as a list.

Arguments:
prev_candidates -- Previous candidates as a list.
length -- The lengths of the next candidates.
"""
# Solve the items.
item_set = set()
for candidate in prev_candidates:
for item in candidate:
item_set.add(item)
items = sorted(item_set)

# Create the temporary candidates. These will be filtered below.


tmp_next_candidates = (frozenset(x) for x in combinations(items,
length))

# Return all the candidates if the length of the next candidates is


2
# because their subsets are the same as items.
if length < 3:
return list(tmp_next_candidates)

# Filter candidates that all of their subsets are


# in the previous candidates.
next_candidates = [
candidate for candidate in tmp_next_candidates
if all(
True if frozenset(x) in prev_candidates else False
for x in combinations(candidate, length - 1))
]
return next_candidates

def gen_support_records(transaction_manager, min_support, **kwargs):


"""
Returns a generator of support records with given transactions.

Arguments:
transaction_manager -- Transactions as a TransactionManager
instance.
min_support -- A minimum support (float).

Keyword arguments:
max_length -- The maximum length of relations (integer).
"""
# Parse arguments.
max_length = kwargs.get('max_length')

# For testing.
_create_next_candidates = kwargs.get(
'_create_next_candidates', create_next_candidates)

# Process.
candidates = transaction_manager.initial_candidates()
length = 1
while candidates:
relations = set()
for relation_candidate in candidates:
support =
transaction_manager.calc_support(relation_candidate)
if support < min_support:
continue
candidate_set = frozenset(relation_candidate)
relations.add(candidate_set)
yield SupportRecord(candidate_set, support)
length += 1
if max_length and length > max_length:
break
candidates = _create_next_candidates(relations, length)

def gen_ordered_statistics(transaction_manager, record):


"""
Returns a generator of ordered statistics as OrderedStatistic
instances.

Arguments:
transaction_manager -- Transactions as a TransactionManager
instance.
record -- A support record as a SupportRecord instance.
"""
items = record.items
for combination_set in combinations(sorted(items), len(items) - 1):
items_base = frozenset(combination_set)
items_add = frozenset(items.difference(items_base))
confidence = (
record.support /
transaction_manager.calc_support(items_base))
lift = confidence / transaction_manager.calc_support(items_add)
yield OrderedStatistic(
frozenset(items_base), frozenset(items_add), confidence,
lift)

def filter_ordered_statistics(ordered_statistics, **kwargs):


"""
Filter OrderedStatistic objects.

Arguments:
ordered_statistics -- A OrderedStatistic iterable object.

Keyword arguments:
min_confidence -- The minimum confidence of relations (float).
min_lift -- The minimum lift of relations (float).
"""
min_confidence = kwargs.get('min_confidence', 0.0)
min_lift = kwargs.get('min_lift', 0.0)

for ordered_statistic in ordered_statistics:


if ordered_statistic.confidence < min_confidence:
continue
if ordered_statistic.lift < min_lift:
continue
yield ordered_statistic

API

def apriori(transactions, **kwargs):


"""
Executes Apriori algorithm and returns a RelationRecord generator.

Arguments:
transactions -- A transaction iterable object
(eg. [['A', 'B'], ['B', 'C']]).

Keyword arguments:
min_support -- The minimum support of relations (float).
min_confidence -- The minimum confidence of relations (float).
min_lift -- The minimum lift of relations (float).
max_length -- The maximum length of the relation (integer).
"""
# Parse the arguments.
min_support = kwargs.get('min_support', 0.1)
min_confidence = kwargs.get('min_confidence', 0.0)
min_lift = kwargs.get('min_lift', 0.0)
max_length = kwargs.get('max_length', None)

# Check arguments.
if min_support <= 0:
raise ValueError('minimum support must be > 0')

# For testing.
_gen_support_records = kwargs.get(
'_gen_support_records', gen_support_records)
_gen_ordered_statistics = kwargs.get(
'_gen_ordered_statistics', gen_ordered_statistics)
_filter_ordered_statistics = kwargs.get(
'_filter_ordered_statistics', filter_ordered_statistics)

# Calculate supports.
transaction_manager = TransactionManager.create(transactions)
support_records = _gen_support_records(
transaction_manager, min_support, max_length=max_length)

# Calculate ordered stats.


for support_record in support_records:
ordered_statistics = list(
_filter_ordered_statistics(
_gen_ordered_statistics(transaction_manager,
support_record),
min_confidence=min_confidence,
min_lift=min_lift,
)
)
if not ordered_statistics:
continue
yield RelationRecord(
support_record.items, support_record.support,
ordered_statistics)

def parse_args(argv):
"""
Parse commandline arguments.

Arguments:
argv -- An argument list without the program name.
"""
output_funcs = {
'json': dump_as_json,
'tsv': dump_as_two_item_tsv,
}
default_output_func_key = 'json'

parser = argparse.ArgumentParser()
parser.add_argument(
'-v', '--version', action='version',
version='%(prog)s {0}'.format(__version__))
parser.add_argument(
'input', metavar='inpath', nargs='*',
help='Input transaction file (default: stdin).',
type=argparse.FileType('r'), default=[sys.stdin])
parser.add_argument(
'-o', '--output', metavar='outpath',
help='Output file (default: stdout).',
type=argparse.FileType('w'), default=sys.stdout)
parser.add_argument(
'-l', '--max-length', metavar='int',
help='Max length of relations (default: infinite).',
type=int, default=None)
parser.add_argument(
'-s', '--min-support', metavar='float',
help='Minimum support ratio (must be > 0, default: 0.1).',
type=float, default=0.1)
parser.add_argument(
'-c', '--min-confidence', metavar='float',
help='Minimum confidence (default: 0.5).',
type=float, default=0.5)
parser.add_argument(
'-t', '--min-lift', metavar='float',
help='Minimum lift (default: 0.0).',
type=float, default=0.0)
parser.add_argument(
'-d', '--delimiter', metavar='str',
help='Delimiter for items of transactions (default: tab).',
type=str, default='\t')
parser.add_argument(
'-f', '--out-format', metavar='str',
help='Output format ({0}; default: {1}).'.format(
', '.join(output_funcs.keys()), default_output_func_key),
type=str, choices=output_funcs.keys(),
default=default_output_func_key)
args = parser.parse_args(argv)

args.output_func = output_funcs[args.out_format]
return args

def load_transactions(input_file, **kwargs):


"""
Load transactions and returns a generator for transactions.

Arguments:
input_file -- An input file.

Keyword arguments:
delimiter -- The delimiter of the transaction.
"""
delimiter = kwargs.get('delimiter', '\t')
for transaction in csv.reader(input_file, delimiter=delimiter):
yield transaction if transaction else ['']
def dump_as_json(record, output_file):
"""
Dump an relation record as a json value.

Arguments:
record -- A RelationRecord instance to dump.
output_file -- A file to output.
"""
def default_func(value):
"""
Default conversion for JSON value.
"""
if isinstance(value, frozenset):
return sorted(value)
raise TypeError(repr(value) + " is not JSON serializable")

converted_record = record._replace(
ordered_statistics=[x._asdict() for x in
record.ordered_statistics])
json.dump(
converted_record._asdict(), output_file,
default=default_func, ensure_ascii=False)
output_file.write(os.linesep)
def dump_as_two_item_tsv(record, output_file):
"""
Dump a relation record as TSV only for 2 item relations.

Arguments:
record -- A RelationRecord instance to dump.
output_file -- A file to output.
"""
for ordered_stats in record.ordered_statistics:
if len(ordered_stats.items_base) != 1:
continue
if len(ordered_stats.items_add) != 1:
continue
output_file.write('{0}\t{1}\t{2:.8f}\t{3:.8f}\t{4:.8f}
{5}'.format(
list(ordered_stats.items_base)[0],
list(ordered_stats.items_add)[0],
record.support, ordered_stats.confidence,
ordered_stats.lift,
os.linesep))

def main(**kwargs):
"""
Executes Apriori algorithm and print its result.
"""
# For tests.
_parse_args = kwargs.get('_parse_args', parse_args)
_load_transactions = kwargs.get('_load_transactions',
load_transactions)
_apriori = kwargs.get('_apriori', apriori)

args = _parse_args(sys.argv[1:])
transactions = _load_transactions(
chain(*args.input), delimiter=args.delimiter)
result = _apriori(
transactions,
max_length=args.max_length,
min_support=args.min_support,
min_confidence=args.min_confidence)
for record in result:
args.output_func(record, args.output)

Reglas de Asociación con el algoritmo Apriori

# Cargamos las librerias necesarias


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# Importamos el archivo de transacciones


dataset = pd.read_csv('/content/drive/MyDrive/20-2/ANALIDAT -
ST150U/ANALITICA-DATOS-GRUPAL/Market_Basket_Optimisation.csv', header =
None)
Dado que los registros se encuentran en columnas con y sin articulos, los
acomodamos en un arreglo con columnas variables

transactions = []
for i in range(0, 7501):
transactions.append([str(dataset.values[i,j]) for j in range(0,
20)])

El siguiente paso es cargar la clase Apriori, crear el objeto y entrenarla con el


conjunto de datos de transacciones

# Training Apriori on the dataset

rules = apriori(transactions, min_support = 0.003, min_confidence =


0.2, min_lift = 3, min_length = 2)

# Resultados
results = list(rules)

def inspect(results):
rh = [tuple(result[2][0][0]) for result in results]
lh = [tuple(result[2][0][1]) for result in results]
supports = [result[1] for result in results]
confidences = [result[2][0][2] for result in results]
lifts = [result[2][0][3] for result in results]
return list(zip(rh, lh, supports, confidences, lifts))

Invocamos la función creando un frame con las reglas encontradas.

# Este comamdo crea un frame para ver los datos resultados


resultDataFrame=pd.DataFrame(inspect(results),
columns=['rhs','lhs','support','confidence','lift'])

También podría gustarte