Visualização de itens frequentemente comprados juntos

10

Eu tenho um conjunto de dados na seguinte estrutura inserida em um arquivo CSV:

Banana  Water   Rice
Rice    Water
Bread   Banana  Juice

Cada linha indica uma coleção de itens que foram comprados juntos. Por exemplo, a primeira linha denota que os itens Banana, Watere Riceforam comprados juntos.

Quero criar uma visualização como a seguinte:

visualização de exemplo

Este é basicamente um gráfico de grade, mas preciso de alguma ferramenta (talvez Python ou R) que possa ler a estrutura de entrada e produzir um gráfico como o acima como saída.

João_testeSW
fonte

Respostas:

6

Eu acho que o que você provavelmente quer é uma versão discreta de um mapa de calor. Por exemplo, veja abaixo. As cores vermelhas indicam as mais comuns compradas juntas, enquanto as células verdes nunca são compradas juntas. mapa de calor

Na verdade, isso é bastante fácil de montar com os Pandas DataFrames e o 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
fonte
Muito obrigado :) Posso criar isso usando o Spark Mllib?
João_testeSW
@ João_testeSW Você provavelmente pode, mas não estou familiarizado com o Spark.
apnorton
você recomendou algum IDE para executar este código?
João_testeSW
@ João_testeSW Se você salvar isso em um arquivo como "somescript.py", poderá executá-lo com "python3 somescript.py" no terminal. Nenhum IDE é necessário, mas se você o carregar em algum IDE compatível com Python, ele deverá ser executado.
apnorton
Graças;) Vou ver se eu posso usá-lo em Pyspark, se sim, então eu posso editar o post com a solução;)
João_testeSW
3

Para R, você pode usar a biblioteca ArulesViz. Há uma boa documentação e, na página 12, há um exemplo de como criar esse tipo de visualização.

O código para isso é tão simples como este:

plot(rules, method="grouped")
HonzaB
fonte
Embora não seja o que o OP esteja procurando, há um ótimo exemplo de visualização usando esta biblioteca aqui: algobeans.com/2016/04/01/…
user35581
0

Com Wolfram Language no Mathematica .

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

Obtenha contagens aos pares.

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}}

Obter índices para ticks nomeados.

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

Traçar com o MatrixPlotuso SparseArray. Também poderia usar ArrayPlot.

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

insira a descrição da imagem aqui

Observe que é triangular superior.

Espero que isto ajude.

Edmund
fonte
0

Você pode fazer isso em python com a biblioteca de visualização marítima (construída sobre o 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()

O dataframe final dffica assim:

insira a descrição da imagem aqui

e a visualização resultante é:

insira a descrição da imagem aqui

AlexG
fonte