Visualización de artículos frecuentemente comprados juntos

10

Tengo un conjunto de datos en la siguiente estructura insertada en un archivo CSV:

Banana  Water   Rice
Rice    Water
Bread   Banana  Juice

Cada fila indica una colección de artículos que se compraron juntos. Por ejemplo, la primera fila indica que los artículos Banana, Watery Ricese compraron juntos.

Quiero crear una visualización como la siguiente:

visualización de ejemplo

Esto es básicamente un gráfico de cuadrícula, pero necesito alguna herramienta (tal vez Python o R) que pueda leer la estructura de entrada y producir un gráfico como el anterior como salida.

João_testeSW
fuente

Respuestas:

6

Creo que lo que probablemente quieras es una versión discreta de un mapa de calor. Por ejemplo, ver abajo. Los colores rojos indican las compras más comunes juntas, mientras que las celdas verdes nunca se compran juntas. mapa de calor

En realidad, esto es bastante fácil de armar con Pandas DataFrames y matplotlib.

import numpy as np
from pandas import DataFrame
import matplotlib
matplotlib.use('agg') # Write figure to disk instead of displaying (for Windows Subsystem for Linux)
import matplotlib.pyplot as plt

####
# Get data into a data frame
####
data = [
  ['Banana', 'Water', 'Rice'],
  ['Rice', 'Water'],
  ['Bread', 'Banana', 'Juice'],
]

# Convert the input into a 2D dictionary
freqMap = {}
for line in data:
  for item in line:
    if not item in freqMap:
      freqMap[item] = {}

    for other_item in line:
      if not other_item in freqMap:
        freqMap[other_item] = {}

      freqMap[item][other_item] = freqMap[item].get(other_item, 0) + 1
      freqMap[other_item][item] = freqMap[other_item].get(item, 0) + 1

df = DataFrame(freqMap).T.fillna(0)
print (df)

#####
# Create the plot
#####
plt.pcolormesh(df, edgecolors='black')
plt.yticks(np.arange(0.5, len(df.index), 1), df.index)
plt.xticks(np.arange(0.5, len(df.columns), 1), df.columns)
plt.savefig('plot.png')
Apnorton
fuente
Muchas gracias :) ¿Puedo crear esto usando Spark Mllib?
João_testeSW
@ João_testeSW Probablemente puedas, pero no estoy familiarizado con Spark.
apnorton
¿recomendó algún IDE para ejecutar este código?
João_testeSW
@ João_testeSW Si guarda esto en un archivo como "somescript.py", puede ejecutarlo con "python3 somescript.py" en el terminal. No se necesita IDE, pero si lo carga en algún IDE compatible con Python, debería ejecutarse.
apnorton
gracias;) Veré si puedo usarlo en Pyspark, en caso afirmativo, puedo editar la publicación con la solución;)
João_testeSW
3

Para R, puedes usar la biblioteca ArulesViz. Hay buena documentación y en la página 12, hay ejemplos de cómo crear este tipo de visualización.

El código para eso es tan simple como esto:

plot(rules, method="grouped")
HonzaB
fuente
Si bien no es lo que está buscando el OP, hay un gran ejemplo de visualización utilizando esta biblioteca aquí: algobeans.com/2016/04/01/…
user35581
0

Con Wolfram Language en Mathematica .

data = {{"Banana", "Water", "Rice"},
        {"Rice", "Water"},
        {"Bread", "Banana", "Juice"}};

Obtenga recuentos por parejas.

counts = Sort /@ Flatten[Subsets[#, {2}] & /@ data, 1] // Tally
{{{"Banana", "Water"}, 1}, {{"Banana", "Rice"}, 1}, 
 {{"Rice", "Water"}, 2}, {{"Banana", "Bread"}, 1}, 
 {{"Bread", "Juice"}, 1}, {{"Banana", "Juice"}, 1}}

Obtenga índices para las garrapatas con nombre.

indices = Thread[# -> Range[Length@#]] &@Sort@DeleteDuplicates@Flatten[data]
{"Banana" -> 1, "Bread" -> 2, "Juice" -> 3, "Rice" -> 4, "Water" -> 5}

Parcela con el MatrixPlotuso SparseArray. También podría usar ArrayPlot.

MatrixPlot[
 SparseArray[Rule @@@ counts /. indices, ConstantArray[Length@indices, 2]],
 FrameTicks -> With[{t = {#2, #1} & @@@ indices}, {{t, None}, {t, None}}],
 PlotLegends -> Automatic
 ]

ingrese la descripción de la imagen aquí

Tenga en cuenta que es triangular superior.

Espero que esto ayude.

Edmund
fuente
0

Puede hacer esto en python con la biblioteca de visualización seaborn (construida sobre matplotlib).

data = [
  ['Banana', 'Water', 'Rice'],
  ['Rice', 'Water'],
  ['Bread', 'Banana', 'Juice'],
]

# Pull out combinations
from itertools import combinations
data_pairs = []
for d in data:
    data_pairs += [list(sorted(x)) + [1] for x in combinations(d, 2)]
    # Add reverse as well (this will mirror the heatmap)
    data_pairs += [list(sorted(x))[::-1] + [1] for x in combinations(d, 2)]

# Shape into dataframe
import pandas as pd
df = pd.DataFrame(data_pairs)
df_zeros = pd.DataFrame([list(x) + [0] for x in combinations(df[[0, 1]].values.flatten(), 2)])
df = pd.concat((df, df_zeros))
df = df.groupby([0, 1])[2].sum().reset_index().pivot(0, 1, 2).fillna(0)

import seaborn as sns
from matplotlib.pyplot import plt
sns.heatmap(df, cmap='YlGnBu')
plt.show()

El marco de datos final se dfve así:

ingrese la descripción de la imagen aquí

y la visualización resultante es:

ingrese la descripción de la imagen aquí

AlexG
fuente