Market Basket Analysis Overview
Market Basket Analysis Overview
Market basket analysis is a method or technique of data analysis for retail and marketing purpose.
Market basket analysis is done to understand the purchasing behavior of customers. MBA (Market
Business Analysis) is used to uncover what items are frequently brought together by the customer.
Market basket analysis leads to effective sales and [Link] basket analysis measures
the co-occurrence of products and services. Market basket analysis is only considered when there
Eg:if a customer is buying bread then he is likely to buy butter, jam or milk to compliment bread.
Market basket analysis is applied to various fields of the retail sector in order to boost sales and
generate revenue by identifying the needs of the customers and make purchase suggestions to
them.
In order to make it easier to understand, think of Market Basket Analysis in terms of shopping
at a supermarket. Market Basket Analysis takes data at transaction level, which lists all items
bought by a customer in a single purchase. The technique determines relationships of what
products were purchased with which other product(s). These relationships are then used to
The If part of the rule (the {A} above) is known as the antecedent and the THEN part of the rule
is known as the consequent (the {B} above). The antecedent is the condition and the
consequent is the result.
Assosciation Rules
Association Rules are widely used to analyze retail basket or transaction data, and are
intended to identify strong rules discovered in transaction data using measures of
interestingness, based on the concept of strong rules.
Let I={i1,i2,i3,…,in} be a set of n attributes called items and D={t1,t2,…,tn} be the set of
transactions. It is called database. Every transaction, ti in D has a unique transaction ID, and
● Apriori Algorithm
● Eclat Algorithm
● FP-growth Algorithm
A rule can be defined as an implication, X Y where X and Y are subsets of I(X,Y⊆I), and they
have no element in common. X and Y are the antecedent and the consequent of the rule,
respectively.
There are various metrics in place to help us understand the strength of assosciation
● Support
● Confidence
● Lift or Correlation or interest
● Leverage
● Conviction
Support
It gives an idea of how frequent an itemset is in all the [Link] say in formal terms it's
the fraction of total no. of transactions in which the itemset [Link] refer to an itemset as a
supp(X−>Y)
(TransactionscontainingbothXandY)
([Link])
Range:[0,1] Value of support helps us identifying the rules worth for future analysis.
Confidence
It defines the likelihood of occurence of consequent on the cart given that cart already has
[Link] signifies the likelihood of item Y being purchased when item X is purchased.
confidence(X−>Y)=
support(X−>Y)
support(X)
Range:[0,1]
If confidence is 0.75 then that imples that 75%of transactions containing X also contain Y .It
can also be interpreted as the conditional probability P(Y|X), i.e, the probability of finding the
itemset Y in transactions given the transaction already contains X.
It has a major drawback i.e. It only takes into account the popularity of the itemset X and not
the popularity of Y. If Y is equally popular as X then there will be a higher probability that a
transaction containing X will also contain Y thus increasing the confidence. To overcome this
drawback there is another measure called lift.
Lift
Lift gives the rise in the probability of having {Y} on the cart with the knowlede of {X} being
present over the probability of having {Y} on the cart without knowlede about presence of {X}.
Lift(X−>Y)=
confidence(X−>Y)
support(Y)
Range:[0,Infinity]
It can simply be considered as correlation between the antecedent and [Link] the value of
lift is greater than 1, it means that the itemset Y is likely to be bought with itemset X, while a value
less than 1 implies that itemset Y is unlikely to be bought if the itemset X is bought.
Levarage or Piatetsky-Snapiro
It computes the difference between the observed frequency of X & Y appearing together and
Leverage(X−>Y)=support(X−>Y)
−support(X)∗support(Y)
Range:[-1,1]
If X,Y are positively correlated then we get leverage>0 ,we need such type of rules.
If X,Y are negatively correlated then we get leverage<0.
If X,y are independent , then we get leverage = 0.
Conviction
It can be interpreted as the ratio of the expected frequency that X occurs without Y (that is to
say, the frequency that the rule makes an incorrect prediction) if X and Y were independent
divided by the observed frequency of incorrect predictions.
Conviction(X−>Y)
support(Y)
confidence(X−>Y)
Range:[0,Infinity]
A high conviction value means that the consequent is highly depending on the antecedent. For
instance, in the case of a perfect confidence score, the denominator becomes 0 (due to 1 - 1)
for which the conviction score is defined as 'inf'. Similar to lift, if items are independent, the
conviction is 1.
Apriori Algorithm
Apriori algorithm is a classical algorithm in data mining. It is used for mining frequent
itemsets and relevant association rules. It is devised to operate on a database containing a
lot of transactions, for instance, items brought by customers in a [Link] rule
learning is a prominent and a well-explored method for determining relations among
variables in large databases.
Rule - generation is a two step process. First is to generate frequent item set and second is
One approach to find the frequent itemsets is to check all possible subsets of the given item
set and check the support value of each itemset and consider only those that have support
Here the Apriori uses the result of antimontone property of support and makes the generation
of frequent Item set faster by reducing the search [Link] has two principles:
Apriori principle allows us to prune all supersets of an itemset which does nogt satisfy the
minimum threshold condition for [Link] example if {Milk,Bread} does not satify our
threshold value , then the superset of {Milk,Bread} will also not cross the threshold value there
by we can just prune them away i.e. do not consider the itemsets that wil be generated from the
{Milk,Bread}.
1. Generate all frequent itemsets each satisfying the minimum threshold and having only
one item let it be L1. Next use self join and generate all possible combinations of L1
and now let the result be L2.
2. At each step as we keep on generating candidate itemsets, for each candidate we
scan entire database so as to know its support and remove the candidates that do not
satisfy minimum threshold
3. Here To reduce the no of comparisions, store the generated candidate items in
a Hash Tree,Instead of matching each of candidate itemsets against each
transaction,match each transaction with the candidates in hash tree(there by
we can enhance the speed of apriori using this method)
In similar way create Lk from Lk-1 until the point where we are unable to apply selfjoin.
This approach of extending a frequent itemset one at a time is called the “bottom up” approach.
[Link] all possible rules from Frequent Itemsets
n+1
If n items are in set I , no of possible assosciation rules possible are 3<supn</sup>- 2 +
[Link] becomes computationally expensive to generate all the rules and there is no meaning in
genearting all that many no. of rules.
Rules are formed by binary partition of each [Link] a list of all possible candidate
rules, we aim to identify rules that fall above the minimum confidence [Link] like
antimontone property of support, confidence of rules generated from same itemset also
follow the anti montone property. It's antimontone w.r.t no. of elements in consequent.
=> CONF(A,B,C -> D) >= CONF(B,C -> A,D) >= CONF(C -> A,B,D)
If you want to refer further on Advanced Apriori Algorithms, Please refer to Advanced
Apriori Algorithms.
Apriori uses a breadth-first search strategy to count the support of itemsets and uses a
candidate generation function which exploits the downward closure property of support.
Development
Importing Libraries
In [1]:
import pandas as pd
import numpy as np
#Visualizations
%matplotlib inline
sns.set_style("dark")
import squarify
import matplotlib
#for preprocessing
InteractiveShell.ast_node_interactivity = "all"
Importing data
data = pd.read_csv('/content/market
basket .csv', sep=';',parse_dates=['Date'])
[Link]()
Output
BillNo Itemna Quantit Date Price Custo Countr
me y merID y
HOLDE
R
RN 0
3 UNION 08:26:0 m
FLAG 0
HOT
WATER
BOTTL
E
RED
WHITE
HEART.
[Link]
Output
(133459, 7)
#head of data
[Link]()
Output
[Link]()
Output
trans=[]
for i in range(0,7501):
trans=[Link](trans)
print([Link])
Output
(7501, 20)
t=TransactionEncoder()
data=t.fit_transform(trans)
data=[Link](data,columns=t.columns_,dtype=int)
[Link]
Output
(7501, 121)
##here we also find nan as one of the columns so lets drop that column
[Link]('nan',axis=1,inplace=True)
[Link]
'nan' in [Link]
Output
(133459, 7)False
[Link]()
Output
/usr/local/lib/python3.10/dist-packages/ipykernel/[Link]: DeprecationWarning:
`should_run_async` will not call `transform_cell` automatically in the future. Please pass
the result to `transformed_cell` argument and any exception that happen during
thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
and should_run_async(code)
BillNo Itemnam Quantity Date Price Custome Country
e rID
Data Visualizations
r=[Link](axis=0).sort_values(ascending=False)[:20]
[Link](figsize=(20,10))
s=[Link](x=[Link],y=[Link])
s.set_xticklabels(s.get_xticklabels(), rotation=90)
Output
# create a color palette, mapped to these
values my_values=[Link]
cmap = [Link]
mini=min(my_values)
maxi=max(my_values)
[Link](figsize=(10,10))
[Link]('off')
Output
Work on apriori
freq_items=apriori(data,min_support=0.05,use_colnames=True
freq_items
Output
/usr/local/lib/python3.10/dist-packages/ipykernel/[Link]:
DeprecationWarning: `should_run_async` will not call
`transform_cell` automatically in the future. Please pass the result
to `transformed_cell` argument and any exception that happen during
thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
and should_run_async(code)
support itemsets
0 1.0 (BillNo)
11.0 (Itemname)
2 1.0 (Quantity)
3 1.0 (Date)
41.0 (Price)
res=association_rules(freq_items,metric="lift",min_threshold=1.3)
res
Output
/usr/local/lib/python3.10/dist-packages/ipykernel/[Link]: DeprecationWarning:
`should_run_async` will not call `transform_cell` automatically in the future. Please pass
the result to `transformed_cell` argument and any exception that happen during
thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
and should_run_async(code)
antec conse antec conse supp confi lift levera convi zhang
edent quent edent quent ort dence ge ction s_met
s s supp supp ric
ort ort
frequent_itemsets['length'] =
frequent_itemsets['itemsets'].apply(lambda x: len(x))
frequent_itemsets
Output
/usr/local/lib/python3.10/dist-packages/ipykernel/[Link]: DeprecationWarning:
`should_run_async` will not call `transform_cell` automatically in the future. Please pass
the result to `transformed_cell` argument and any exception that happen during
thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
and should_run_async(code)
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/[Link]:
DeprecationWarning: DataFrames with non-bool types result in worse computationalperformance
and their support might be discontinued in the [Link] use a DataFrame with bool type
[Link](
support itemsets length
0 1.0 (BillNo) 1
1 1.0 (Itemname) 1
2 1.0 (Quantity) 1
3 1.0 (Date) 1
4 1.0 (Price) 1
# getting th item sets with length = 2 and support more han 10%
Output
/usr/local/lib/python3.10/dist-packages/ipykernel/[Link]:
DeprecationWarning: `should_run_async` will not call `transform_cell`
automatically in the future. Please pass the result to
`transformed_cell` argument and any exception that happen during
thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
and should_run_async(code)
# getting th item sets with length = 2 and support more han 10%
Output
/usr/local/lib/python3.10/dist-packages/ipykernel/[Link]:
DeprecationWarning: `should_run_async` will not call
`transform_cell` automatically in the future. Please pass the result
to `transformed_cell` argument and any exception that happen during
thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
and should_run_async(code)
0 1.0 (BillNo) 1
1 1.0 (Itemname) 1
2 1.0 (Quantity) 1
3 1.0 (Date) 1
4 1.0 (Price) 1
5 1.0 (CustomerID) 1
6 1.0 (Country) 1
ECLAT ALGORITHM
BottleNecks of Apriori:
Eg:
k=1,min_support=0.5 a={t1,t2,t3},sup=1
b={t1,t2},sup=0.66 c={t1},sup=0.33
Number of Computations: The ECLAT algorithm does not involve the repeated
scanning of the data to compute the individual support values.
FP TREE
3) The next step is to scan the database again and examine the
transactions. Examine the first transaction and find out the itemset
in it. The itemset with the max count is taken at the top, the next
itemset with lower count and so on. It means that the branch of the
tree is constructed with transaction itemsets in descending order of
count.
4) The next transaction in the database is examined. The itemsets
are ordered in descending order of count. If any itemset of this
transaction is already present in another branch (for example in the
1st transaction), then this transaction branch would share a common
prefix to the root.
This means that the common itemset is linked to the new node of
another itemset in this transaction.
6) The next step is to mine the created FP Tree. For this, the
lowest node is examined first along with the links of the lowest
nodes. The lowest node represents the frequency pattern length 1.
From this, traverse the path in the FP Tree. This path or paths are
called a conditional pattern base.
res=fpgrowth(data,min_support=0.05,use_colnames=True)
res
Output
/usr/local/lib/python3.10/dist-packages/ipykernel/[Link]:
DeprecationWarning: `should_run_async` will not call
`transform_cell` automatically in the future. Please pass the result
to `transformed_cell` argument and any exception that happen during
thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
and should_run_async(code)
support itemsets
0 1.0 (Country)
1 1.0 (CustomerID)
21.0 (Price)
31.0 (Date)
41.0 (Quantity)
res=association_rules(res,metric="lift",min_threshold=1)
res
Output
/usr/local/lib/python3.10/dist-packages/ipykernel/[Link]: DeprecationWarning:
`should_run_async` will not call `transform_cell` automatically in the future. Please pass
the result to `transformed_cell` argument and any exception that happen during
thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
and should_run_async(code)
antec conse antec conse supp confi lift levera convi zhang
edent quent edent quent ort dence ge ction s_met
s s supp supp ric
ort ort
(Coun (Cust 1.0 1.0 1.0 1.0 1.0 0.0 inf 0.0
0 try) omerI
D)
1 (Cust (Coun 1.0 1.0 1.0 1.0 1.0 0.0 inf 0.0
omerI try)
D)
2 (Coun (Price 1.0 1.0 1.0 1.0 1.0 0.0 inf 0.0
try) )
3 (Price (Coun 1.0 1.0 1.0 1.0 1.0 0.0 inf 0.0
) try)
4 (Coun (Date) 1.0 1.0 1.0 1.0 1.0 0.0 inf 0.0
try)
... ... ... ... ... ... ... ... ... ... ...
(Coun (Itemn 1.0 1.0 1.0 1.0 1.0 0.0 inf 0.0
try) ame,
1927 Quant
ity,
Price,
Date,
Custo
merID
, ...
(Price (Itemn 1.0 1.0 1.0 1.0 1.0 0.0 inf 0.0
) ame,
Quant
ity,
1928 Count
ry,
Date,
Custo
merID
...
(Date) (Itemn 1.0 1.0 1.0 1.0 1.0 0.0 inf 0.0
ame,
Quant
1929 ity,
Count
ry,
Price,
Custo
merI...
(Cust (Itemn 1.0 1.0 1.0 1.0 1.0 0.0 inf 0.0
omerI ame,
D) Quant
ity,
1930 Count
ry,
Price,
Date,
Bil...
(BillN (Itemn 1.0 1.0 1.0 1.0 1.0 0.0 inf 0.0
o) ame,
Quant
ity,
1931 Count
ry,
Price,
Date,
Cus...
Apriori Vs FP Growth
import time
l=[0.01,0.02,0.03,0.04,0.05]
t=[]
for i in l:
t1=[Link]()
apriori(data,min_support=i,use_colnames=True)
t2=[Link]()
[Link]((t2-t1)*1000)
Output
/usr/local/lib/python3.10/dist-packages/ipykernel/[Link]:
DeprecationWarning: `should_run_async` will not call
`transform_cell` automatically in the future. Please pass the result
to `transformed_cell` argument and any exception that happen during
thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
and should_run_async(code)
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/fpcom
[Link]: DeprecationWarning: DataFrames with non-bool types result in
worse computationalperformance and their support might be discontinued in
the [Link] use a DataFrame with bool type
[Link](
support itemsets
0 1.0 (BillNo)
11.0 (Itemname)
21.0 (Quantity)
31.0 (Date)
41.0 (Price)
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/fpcom
[Link]: DeprecationWarning: DataFrames with non-bool types result in
worse computationalperformance and their support might be discontinued in
the [Link] use a DataFrame with bool type
[Link](
support itemsets
0 1.0 (BillNo)
11.0 (Itemname)
21.0 (Quantity)
31.0 (Date)
41.0 (Price)
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/fpcom
[Link]: DeprecationWarning: DataFrames with non-bool types result in
worse computationalperformance and their support might be discontinued in
the [Link] use a DataFrame with bool type
[Link](
support itemsets
0 1.0 (BillNo)
11.0 (Itemname)
21.0 (Quantity)
31.0 (Date)
41.0 (Price)
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/fpcom
[Link]: DeprecationWarning: DataFrames with non-bool types result in
worse computationalperformance and their support might be discontinued in
the [Link] use a DataFrame with bool type
[Link](
support itemsets
0 1.0 (BillNo)
11.0 (Itemname)
21.0 (Quantity)
31.0 (Date)
41.0 (Price)
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/fpcom
[Link]: DeprecationWarning: DataFrames with non-bool types result in
worse computationalperformance and their support might be discontinued in
the [Link] use a DataFrame with bool type
[Link](
support itemsets
0 1.0 (BillNo)
11.0 (Itemname)
21.0 (Quantity)
31.0 (Date)
4 1.0 (Price)
... ... ...
/usr/local/lib/python3.10/dist-packages/ipykernel/[Link]: DeprecationWarning:
`should_run_async` will not call `transform_cell` automatically in the future. Please pass
the result to `transformed_cell` argument and any exception that happen during
thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
and should_run_async(code)
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/[Link]:
DeprecationWarning: DataFrames with non-bool types result in worse computationalperformance
and their support might be discontinued in the [Link] use a DataFrame with bool type
[Link](
support itemsets
0 1.0 (BillNo)
1 1.0 (Itemname)
2 1.0 (Quantity)
3 1.0 (Date)
4 1.0 (Price)
1.0
122
(Itemname, Quantity, Country,
Price, CustomerI...
123
1.0 (Itemname, Country, Price,
Date, CustomerID, B...
124 1.0 (Quantity, Country, Price,
Date, CustomerID, B...
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/[Link]:
DeprecationWarning: DataFrames with non-bool types result in worse computationalperformance
and their support might be discontinued in the [Link] use a DataFrame with bool type
[Link](
support itemsets
0 1.0 (BillNo)
1 1.0 (Itemname)
2 1.0 (Quantity)
3 1.0 (Date)
4 1.0 (Price)
1.0
122
(Itemname, Quantity, Country,
Price, CustomerI...
123
1.0 (Itemname, Country, Price,
Date, CustomerID, B...
124
1.0 (Quantity, Country, Price,
Date, CustomerID, B...
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/[Link]:
DeprecationWarning: DataFrames with non-bool types result in worse computationalperformance
and their support might be discontinued in the [Link] use a DataFrame with bool type
[Link](
support itemsets
0 1.0 (BillNo)
1 1.0 (Itemname)
2 1.0 (Quantity)
3 1.0 (Date)
4 1.0 (Price)
1.0
122
(Itemname, Quantity, Country,
Price, CustomerI...
123
1.0 (Itemname, Country, Price,
Date, CustomerID, B...
124
1.0 (Quantity, Country, Price,
Date, CustomerID, B...
125
1.0
126
1.0
127 rows × 2 columns
(Itemname, Quantity, Country,
Price, Date, Cus...
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/[Link]:
DeprecationWarning: DataFrames with non-bool types result in worse computationalperformance
and their support might be discontinued in the [Link] use a DataFrame with bool type
[Link](
support itemsets
0 1.0 (BillNo)
1 1.0 (Itemname)
2 1.0 (Quantity)
3 1.0 (Date)
4 1.0 (Price)
123
1.0 (Itemname, Country, Price,
Date, CustomerID, B...
124
1.0 (Quantity, Country, Price,
Date, CustomerID, B...
125
1.0
126
1.0
127 rows × 2 columns
(Itemname, Quantity, Country,
Price, Date, Cus...
l=[0.01,0.02,0.03,0.04,0.05]
f=[]
for i in l:
t1=[Link]()
fpgrowth(data,min_support=i,use_colnames=True)
t2=[Link]()
[Link]((t2-t1)*1000)
Output
/usr/local/lib/python3.10/dist-packages/ipykernel/[Link]: DeprecationWarning:
`should_run_async` will not call `transform_cell` automatically in the future. Please pass
the result to `transformed_cell` argument and any exception that happen during
thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
and should_run_async(code)
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/[Link]:
DeprecationWarning: DataFrames with non-bool types result in worse computationalperformance
and their support might be discontinued in the [Link] use a DataFrame with bool type
[Link](
supportitemsets
0 1.0 (Country)
1 1.0 (CustomerID)
2 1.0 (Price)
3 1.0 (Date)
4 1.0 (Quantity)
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/[Link]:
DeprecationWarning: DataFrames with non-bool types result in worse computationalperformance
and their support might be discontinued in the [Link] use a DataFrame with bool type
[Link](
supportitemsets
0 1.0 (Country)
1 1.0 (CustomerID)
2 1.0 (Price)
3 1.0 (Date)
4 1.0 (Quantity)
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/[Link]:
DeprecationWarning: DataFrames with non-bool types result in worse computationalperformance
and their support might be discontinued in the [Link] use a DataFrame with bool type
[Link](
supportitemsets
0 1.0 (Country)
1 1.0 (CustomerID)
2 1.0 (Price)
3 1.0 (Date)
4 1.0 (Quantity)
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/[Link]:
DeprecationWarning: DataFrames with non-bool types result in worse computationalperformance
and their support might be discontinued in the [Link] use a DataFrame with bool type
[Link](
supportitemsets
0 1.0 (Country)
1 1.0 (CustomerID)
2 1.0 (Price)
3 1.0 (Date)
4 1.0 (Quantity)
/usr/local/lib/python3.10/dist-packages/mlxtend/frequent_patterns/[Link]:
DeprecationWarning: DataFrames with non-bool types result in worse computationalperformance
and their support might be discontinued in the [Link] use a DataFrame with bool type
[Link](
supportitemsets
0 1.0 (Country)
1 1.0 (CustomerID)
2 1.0 (Price)
3 1.0 (Date)
4 1.0 (Quantity)
[Link](x=l,y=f,label="fpgrowth")
[Link](x=l,y=t,label="apriori")
[Link]("Min_support Threshold")
Output
Conclusion:
Association analysis, often referred to as market basket analysis in the context of retail, is a
technique used to discover interesting relationships between items in a dataset. This analysis
is commonly used to identify which items are frequently purchased together, helping
businesses make informed decisions about product placement, promotions, and more.
Here are the basic steps for performing association analysis and generating insights in
market basket analysis:
1. **Data Collection**: Gather transaction data, where each transaction lists the
items purchased by a customer.
2. **Data Preprocessing**: Organize the data into a suitable format, such as a matrix or list
of transactions, with items as columns and transactions as rows.
3. **Support and Confidence**: Calculate support and confidence for item pairs. Support
measures how often items appear together, while confidence measures how likely one item
is purchased when another is.
6. **Interpreting Results**: Explore the discovered association rules to gain insights. Focus
on rules with high support and confidence, as these are the most reliable associations.
7. **Visualizing and Presenting Insights**: Visualize the results with tools like scatter plots,
bar charts, or word clouds. These visuals can make it easier to understand and communicate
the insights.
8. **Implementing Business Decisions**: Use the insights to inform business decisions, such as
optimizing product placement, creating cross-selling strategies, or designing promotions.