Visualiser les articles fréquemment achetés ensemble

10

J'ai un jeu de données dans la structure suivante inséré dans un fichier CSV:

Banana  Water   Rice
Rice    Water
Bread   Banana  Juice

Chaque ligne indique une collection d'articles achetés ensemble. Par exemple, la première ligne indique que les articles Banana, Wateret Riceont été achetés ensemble.

Je veux créer une visualisation comme celle-ci:

exemple de visualisation

Il s'agit essentiellement d'un graphique en grille, mais j'ai besoin d'un outil (peut-être Python ou R) qui peut lire la structure d'entrée et produire un graphique comme celui ci-dessus en sortie.

João_testeSW
la source

Réponses:

6

Je pense que ce que vous voulez probablement, c'est une version discrète d'une carte thermique. Par exemple, voir ci-dessous. Les couleurs rouges indiquent les plus couramment achetées ensemble, tandis que les cellules vertes ne sont jamais achetées ensemble. carte de chaleur

C'est en fait assez facile à assembler avec Pandas DataFrames et 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
la source
Merci :) Puis-je créer ceci en utilisant Spark Mllib?
João_testeSW
@ João_testeSW Vous le pouvez probablement, mais je ne connais pas Spark.
apnorton
avez-vous recommandé un IDE pour exécuter ce code?
João_testeSW
@ João_testeSW Si vous l'enregistrez dans un fichier en tant que "somescript.py", vous pouvez l'exécuter avec "python3 somescript.py" sur le terminal. Aucun IDE n'est nécessaire, mais si vous le chargez dans un IDE compatible Python, il doit s'exécuter.
apnorton
merci;) Je vais voir si je peux l'utiliser dans Pyspark, si oui, je peux éditer le message avec la solution;)
João_testeSW
3

Pour R, vous pouvez utiliser la bibliothèque ArulesViz. Il y a une belle documentation et à la page 12, il y a un exemple comment créer ce type de visualisation.

Le code pour cela est aussi simple que cela:

plot(rules, method="grouped")
HonzaB
la source
Bien que ce ne soit pas ce que l'OP recherche, il existe un excellent exemple de visualisation utilisant cette bibliothèque ici: algobeans.com/2016/04/01/…
user35581
0

Avec Wolfram Language dans Mathematica .

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

Obtenez des comptes par paire.

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

Obtenez des indices pour les tiques nommées.

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

Tracer avec l' MatrixPlotaide SparseArray. Pourrait également utiliser ArrayPlot.

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

entrez la description de l'image ici

Notez qu'il est triangulaire supérieur.

J'espère que cela t'aides.

Edmund
la source
0

Vous pouvez le faire en python avec la bibliothèque de visualisation seaborn (construite au-dessus de 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()

La trame de données finale dfressemble à ceci:

entrez la description de l'image ici

et la visualisation résultante est:

entrez la description de l'image ici

AlexG
la source