Wizualizacja przedmiotów często kupowanych razem

10

Mam zestaw danych w następującej strukturze wstawiony do pliku CSV:

Banana  Water   Rice
Rice    Water
Bread   Banana  Juice

Każdy wiersz wskazuje kolekcję przedmiotów, które zostały zakupione razem. Na przykład, pierwszy wiersz oznacza, że przedmioty Banana, Wateri Ricezostały zakupione razem.

Chcę utworzyć wizualizację, jak poniżej:

przykładowa wizualizacja

Jest to w zasadzie wykres siatki, ale potrzebuję jakiegoś narzędzia (może Python lub R), które może odczytać strukturę wejściową i wygenerować taki wykres jak powyższy jako wynik.

João_testeSW
źródło

Odpowiedzi:

6

Myślę, że prawdopodobnie chcesz dyskretnej wersji mapy cieplnej. Na przykład patrz poniżej. Czerwone kolory wskazują najczęściej kupowane razem, podczas gdy zielone komórki nigdy nie są kupowane razem. Mapa ciepła

W rzeczywistości jest to dość łatwe do zestawienia z Pandas DataFrames i 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
źródło
Wielkie dzięki :) Czy mogę to stworzyć za pomocą Spark Mllib?
João_testeSW
@ João_testeSW Prawdopodobnie możesz, ale nie jestem zaznajomiony z Spark.
apnorton
poleciłeś jakieś IDE do wykonania tego kodu?
João_testeSW
@ João_testeSW Jeśli zapiszesz to w pliku jako „somescript.py”, możesz uruchomić go z „python3 somescript.py” na terminalu. IDE nie jest potrzebne, ale jeśli załadujesz go do jakiegoś IDE obsługującego Python, powinien on działać.
apnorton
dzięki;) Zobaczę, czy mogę użyć go w Pyspark, jeśli tak, to mogę edytować post za pomocą rozwiązania;)
João_testeSW
3

Dla R, można użyć biblioteki ArulesViz. Jest ładna dokumentacja, a na stronie 12 znajduje się przykład tworzenia tego rodzaju wizualizacji.

Kod tego jest tak prosty:

plot(rules, method="grouped")
HonzaB
źródło
Chociaż nie tego szuka OP, istnieje świetna przykładowa wizualizacja z wykorzystaniem tej biblioteki tutaj: algobeans.com/2016/04/01/…
user35581
0

Z Wolfram Language in Mathematica .

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

Uzyskaj liczbę par.

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

Uzyskaj indeksy dla nazwanych kleszczy.

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

Rysuj za MatrixPlotpomocą SparseArray. Przydałby się również ArrayPlot.

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

wprowadź opis zdjęcia tutaj

Pamiętaj, że jest on trójkątny.

Mam nadzieję że to pomoże.

Edmund
źródło
0

Możesz to zrobić w Pythonie z biblioteką wizualizacji dna morskiego (zbudowaną na 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()

Ostateczna ramka danych dfwygląda następująco:

wprowadź opis zdjęcia tutaj

a wynikowa wizualizacja to:

wprowadź opis zdjęcia tutaj

AlexG
źródło