Datamining för handeln i R

Ämne: Avancerad Analys

Inledning

Skall man erbjuda datamining (kunskapsutvinning är ett alternativt ord på svenska) till företag inom handelssektorn, så är det oftast kundkorgsanalys och kundsegmentering man pratar om. Genom att utöka en generell BI-lösning med mining funktionalitet kan man få djupare insikt om försäljning och
kundbeteende – vilket i sin tur leder till förfining av marknadsföringen, lyckade kampanjer, bättre placering av varor i butiken – och i slutändan, större vinst.

Jag kommer i detta blogginlägg ge er en enkel guide på en tillämpning som använder R kan se ut.

Varning – ingen magi inblandad, kräver kunskap

Datamining är av naturen inkrementell. Man ska inte förvänta att kunskapsutvinning sker genom någon form av magi, där systemet trollar fram rätta  svar på allt. Som nedan flödesbild (EU-standard)för ett typiskt projekt visar, måste både dataförberedelse och utvärdering ske i en dialog med verksamheten. Utvärderingsdialogen leder oftast till nya frågor, nytt data och nya
kunskapsutvinningsprojekt. Verksamheten måste ha klart för sig vad de vill veta/uppnå och kommunicera detta. Analytikern måste ha förståelse för
data han får och vara proaktiv vad gäller nytt data och berikande av befintligt data. I slutändan skall frågeställningen – och dess inkrementella ändringar –
styras av lönsamhet.

Med detta sagt, kan vi tillsammans titta på hur en typisk första fas av en sådan djupgående säljanalys kan se ut.

Transaktionsdata

Vi ska analysera försäljningsdata för ett fiktivt företag som heter Foodmart.  Datafilen (en mysql dump)  följer t.ex. med Mondrian-installationen.
Efter importen till MySQL-server skapas det en databas i stjärnform; med en faktatabell som innehåller kvittorader och 4 dimensionstabeller
(kunder, produkter, produktklass och tid).

Vi börjar med att skapa en csv-fil bestående av par <transaktions-id : produktkategori>. Detta gör vi genom att exportera resultatet av queryn

select time_id*10000 + customer_id as trans_id, 
product_subcategory as product_name
from sales_fact_1997
join product 
on sales_fact_1997.product_id=product.product_id
join product_class
on product_class.product_class_id = product.product_class_id
order by rand()
limit 2000

(kommentera bort de sista två raderna om du vill köra analysen på hela försäljningsdatat, annars är de där för att sampla).

Foodmart verkar ha många produkter av samma typ men av olika tillverkare; dessutom är det testdata för Mondrian och därför är köp mycket uniformt
distribuerade med avseende på produktnamn. Detta är den främsta anledningen att vi helst väljer produktkategori som attribut.

 transid           product_name____
7239782         Pot Cleaners
6809064         Soda
5359237        Fresh Vegetables
4739401        Personal Hygiene
………..              ………………

Analysen

Vår metod här blir  Association Rule Mining. Som resultat hittar man relationer (“om A då B”) eller associationer (“A och B oftast tillsammans”)
mellan produktnamn i Foodmart. Det som undersöks är vilka varor som oftast köps tillsammans och på så sätt kan omfattas av planerade kupongkampanjer, eller
ommöblering på butikshyllorna. T.ex. har man välkända exempel:

  • Tomatsås => Pasta
  • Chips => Cola

Upptäcker man sådana associationer, är det lämpligt att lägga chips och läsk på närliggande hyllor eller starta en rabattkampanj där pasta och tomatsås uppträder som kombo.

Hur kan vi mäta om en regel är intressant eller ej?
Låt oss ta en liten mängd exempeltransaktioner (1= finns med på kvittot, 0=finns ej):

kvittoid bröd mjölk smör öl
KV1 1 1 0 0
KV2 0 0 1 0
KV3 0 0 0 1
KV4 1 1 1 0
KV5 0 1 0 0

Vi inför följande mått: stöd (support) supp X , dvs hur ofta itemset X intraffar.

  • {MJÖLK; BRÖD} inträffar 2 gånger av 5 (kvitton 1 och 4), alltså är supp{MJÖLK;BRÖD} = 2/5.
  • {MJÖLK; BRÖD; SMÖR} förekommer bara 1 gång (kvitto 4), och då är  supp{MJÖLK;BRÖD;SMÖR} =1/5

Vidare, konfidens (confidence) för regeln ”itemset X medför itemset Y” definieras som supp(X∪Y)/ supp(X).

  • I vårt exempel  är conf({MJÖLK, BRÖD} =>{SMÖR}) =0.2/0.4=0.5

OBS:Andra mätetal kan introduceras (lift, conviction. certainty osv.) En överblick över dessa och vad de står för finns t.ex. här.

Vi letar efter regler som har vettigt stöd och relativt stor konfidens (evt minsta värde begränsningar på andra mått). Detta kan man göra mha följande algoritm:

  1. Hitta alla itemsets med stort stöd
  2. Forma regler mha dessa itemsets utifrån begränsningen på konfidens.

Vi kommer att använda verktyget (ramverk, programmeringsspråk) R, statistiskt språk för att analysera datat.  R har ett eget interaktivt shell, alternativt kan man för IDE använda det briljanta programmet Rstudio. Algoritmer som vi behöver finns i R-modulerna arules  (för utvinning av reglerna) och arulesViz (för visualisering) som man måste installera och sedan ”ansluta” till shell-sessionen.

R tolkar om vårt usrprungliga schema för datat: key-value par <transaktions-id : produktnamn>  till  <transaktions-id : {listan över köpta produkter}>.

items                    transactionID
 {Cheese, 
 Coffee, 
 Dried Fruit, 
 Fresh Vegetables, 
 Milk}                       3670106

 {Fresh Fruit, 
 Nuts, 
 Peanut Butter, 
 Soda}                       3671900

 {Batteries, 
 Cookies, 
 Fashion Magazines, 
 Fresh Fruit, 
 Frozen Vegetables, 
 Sliced Bread}               3671906

Vi är nu redo att börja utvinna reglerna för våra  kundkorgar med apriori-algoritmen. Välj support =0.00024 och konfidens 80%. Anledningen att vi väljer en så pass liten support är återigen mycket uniforma köp. Detta ger intressanta analyser i kuben men dock inte så många regler att titta på.
Observera att vi också bara tittar på reglerna med relativt stor lyft.

lhs                          rhs                 support confidence lift
 {Hard Candy, 
 Shellfish}              => {Dips}           0.0002436410 0.8333333 15.98287
2 {Computer Magazines, 
 Fresh Vegetables, 
 Wine}                   => {Paper Wipes}    0.0002436410 0.8333333 10.60240
3 {Cooking Oil, 
 Fresh Vegetables, 
 Tools}                  => {Jam}            0.0002923692 0.8571429 21.37337
4 {Beer, 
 Fresh Fruit, 
 TV Dinner}              => {Eggs}           0.0002436410 0.8333333 13.02488
5 {Mouthwash, 
 Personal Hygiene, 
 Popcorn}                => {Eggs}           0.0002436410 0.8333333 13.02488
6 {Eggs, 
 Personal Hygiene, 
 Popcorn}                => {Mouthwash}      0.0002436410 0.8333333 29.89802

Nu visualiserar vi det vi har hittat (23 regler i subrules) med de två mest lättolkade plottar: matris och regelgraf.

Matrisen:

Grafen efter lite dra-och-släppa städning:

Möjlig automatisering

Med ett ETL-verktyg som tillåter shellskript (.bat på Windows eller bash ) kan man lätt automatisera den ovan beskrivna datamining-processen.