Reguły asocjacyjne (association rules) dają możliwość odkrywania relacji między obserwacjami w bazach danych. Można to wykorzystać do przygotowywana rekomendacji kolejnych filmów dla klientów platform streamingowych. W tym projekcie została przeprowadzona przykładowa analiza z wykorzystaniem zbioru danych MovieLense, w którym znajdują się informacje odnośnie ocen obejrzanych filmów, wystawionych przez konkretnych użytkowników. Zostały przygotowane reguły asocjacyjne i ich wizualizacje, a także prosta rekomendacja kolejnego filmu na konkretnym przykładzie.
Zostały wykorzystane biblioteki arules (do przeprowadzenia analizy reguł asocjacyjnych), arulesViz (do wizualizacji reguł) i recommenderlab (do pobrania danych).
W projekcie sztuczna inteligencja została wykorzystana do pomocy w przygotowaniu kodu.
library(arules)
library(arulesViz)
library(recommenderlab)
Na początku dane zostały pobrane z internetowej bazy MovieLense. Mają one postać realRatingMatrix.
data("MovieLense")
Aby móc dalej wykorzystać pobrane dane, należy je przetworzyć na “transakcje”. W tym celu za “lubiane” filmy zostały uznane te, które uzyskały ocenę 4 lub 5 w skali 1-5. Pierwotny zbiór danych został przekształcony na typ binaryRatingMatrix przy pomocy funkcji binarize, a następnie z tego zbioru zostały uzyskane “koszyki” - zbiory filmów jednocześnie rekomendowanych przez konkretnych użytkowników.
movie_binary <- binarize(MovieLense, minRating = 4)
movie_trans <- as(as(movie_binary, "list"), "transactions")
Uzyskany zbiór składa się z 943 “koszyków”.
length(movie_trans)
## [1] 943
Zanim zostanie wykorzystany algorytm do przygotowania reguł asocjacyjnych, można zwizualizować przetworzony zbiór danych. Poniższy wykres prezentuje najczęściej lubiane w wybranym zbiorze danych filmy.
itemFrequencyPlot(movie_trans, topN = 10, col = 'steelblue', main = 'Najczęściej lubiane filmy', ylab = 'Częstość występowania (support)')
Do przygotowania reguł została wykorzystana metoda apriori. Jako parametry zostały przyjęte minimalny support w wysokości 0.2 oraz minimalne confidence w wysokości 0.25. Ponadto, został wykorzystany parametr maxlen, aby znaleźć tylko reguły zawierające pojedyncze filmy po lewej stronie. Następnie reguły zostały oczyszczone z ewentualnej redundancji. W efekcie działania algorytmu zostały uzyskane 72 reguły.
rules <- apriori(movie_trans, parameter = list(supp = 0.2, conf = 0.25, minlen = 2, maxlen = 2))
## Apriori
##
## Parameter specification:
## confidence minval smax arem aval originalSupport maxtime support minlen
## 0.25 0.1 1 none FALSE TRUE 5 0.2 2
## maxlen target ext
## 2 rules TRUE
##
## Algorithmic control:
## filter tree heap memopt load sort verbose
## 0.1 TRUE TRUE FALSE TRUE 2 TRUE
##
## Absolute minimum support count: 188
##
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[1433 item(s), 943 transaction(s)] done [0.01s].
## sorting and recoding items ... [49 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2
## done [0.00s].
## writing ... [72 rule(s)] done [0.00s].
## creating S4 object ... done [0.00s].
rules <- rules[!is.redundant(rules)]
summary(rules)
## set of 72 rules
##
## rule length distribution (lhs + rhs):sizes
## 2
## 72
##
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 2 2 2 2 2 2
##
## summary of quality measures:
## support confidence coverage lift
## Min. :0.2004 Min. :0.3772 Min. :0.2301 Min. :1.138
## 1st Qu.:0.2041 1st Qu.:0.5198 1st Qu.:0.3107 1st Qu.:1.399
## Median :0.2179 Median :0.6071 Median :0.3690 Median :1.584
## Mean :0.2315 Mean :0.6291 Mean :0.3882 Mean :1.651
## 3rd Qu.:0.2450 3rd Qu.:0.7589 3rd Qu.:0.5313 3rd Qu.:1.857
## Max. :0.3701 Max. :0.9352 Max. :0.5313 Max. :2.385
## count
## Min. :189.0
## 1st Qu.:192.5
## Median :205.5
## Mean :218.3
## 3rd Qu.:231.0
## Max. :349.0
##
## mining info:
## data ntransactions support confidence
## movie_trans 943 0.2 0.25
## call
## apriori(data = movie_trans, parameter = list(supp = 0.2, conf = 0.25, minlen = 2, maxlen = 2))
Uzyskaną listę reguł można posortować po różnych parametrach: lift, confidence oraz support. Dla każdej z posortowanych list została przygotowana interaktywna wizualizacja dwudziestu pierwszych reguł. We wszystkich przypadkach można zauważyć dominację filmów z serii Star Wars i Indiana Jones.
Miara lift oznacza, ile razy polubienie filmu z lewej strony zwiększa szansę polubienia filmu z prawej strony.
rules_sorted_lift <- sort(rules, by = 'lift', decreasing = TRUE)
inspect(head(rules_sorted_lift, 20))
## lhs rhs support confidence coverage lift count
## [1] {Terminator, The (1984)} => {Raiders of the Lost Ark (1981)} 0.2025451 0.8801843 0.2301166 2.385097 191
## [2] {Raiders of the Lost Ark (1981)} => {Terminator, The (1984)} 0.2025451 0.5488506 0.3690350 2.385097 191
## [3] {Indiana Jones and the Last Crusade (1989)} => {Raiders of the Lost Ark (1981)} 0.2078473 0.8340426 0.2492047 2.260064 196
## [4] {Raiders of the Lost Ark (1981)} => {Indiana Jones and the Last Crusade (1989)} 0.2078473 0.5632184 0.3690350 2.260064 196
## [5] {Empire Strikes Back, The (1980)} => {Raiders of the Lost Ark (1981)} 0.2545069 0.8191126 0.3107105 2.219607 240
## [6] {Raiders of the Lost Ark (1981)} => {Empire Strikes Back, The (1980)} 0.2545069 0.6896552 0.3690350 2.219607 240
## [7] {Back to the Future (1985)} => {Raiders of the Lost Ark (1981)} 0.2004242 0.8042553 0.2492047 2.179347 189
## [8] {Raiders of the Lost Ark (1981)} => {Back to the Future (1985)} 0.2004242 0.5431034 0.3690350 2.179347 189
## [9] {Fugitive, The (1993)} => {Raiders of the Lost Ark (1981)} 0.2184517 0.7803030 0.2799576 2.114442 206
## [10] {Raiders of the Lost Ark (1981)} => {Fugitive, The (1993)} 0.2184517 0.5919540 0.3690350 2.114442 206
## [11] {Princess Bride, The (1987)} => {Raiders of the Lost Ark (1981)} 0.2004242 0.7620968 0.2629905 2.065107 189
## [12] {Raiders of the Lost Ark (1981)} => {Princess Bride, The (1987)} 0.2004242 0.5431034 0.3690350 2.065107 189
## [13] {Pulp Fiction (1994)} => {Silence of the Lambs, The (1991)} 0.2195122 0.7040816 0.3117709 1.930084 207
## [14] {Silence of the Lambs, The (1991)} => {Pulp Fiction (1994)} 0.2195122 0.6017442 0.3647932 1.930084 207
## [15] {Empire Strikes Back, The (1980)} => {Return of the Jedi (1983)} 0.2396607 0.7713311 0.3107105 1.919169 226
## [16] {Return of the Jedi (1983)} => {Empire Strikes Back, The (1980)} 0.2396607 0.5963061 0.4019088 1.919169 226
## [17] {Raiders of the Lost Ark (1981)} => {Pulp Fiction (1994)} 0.2152704 0.5833333 0.3690350 1.871032 203
## [18] {Pulp Fiction (1994)} => {Raiders of the Lost Ark (1981)} 0.2152704 0.6904762 0.3117709 1.871032 203
## [19] {Silence of the Lambs, The (1991)} => {Empire Strikes Back, The (1980)} 0.2099682 0.5755814 0.3647932 1.852468 198
## [20] {Empire Strikes Back, The (1980)} => {Silence of the Lambs, The (1991)} 0.2099682 0.6757679 0.3107105 1.852468 198
plot(head(rules_sorted_lift, 20), method = 'graph', engine = 'htmlwidget')
Miara confidence oznacza, jakiemu odsetkowi oglądających, którym podobał się film po lewej stronie, podobał się także film po prawej stronie.
rules_sorted_conf <- sort(rules, by = 'confidence', decreasing = TRUE)
inspect(head(rules_sorted_conf, 20))
## lhs rhs support confidence coverage lift count
## [1] {Empire Strikes Back, The (1980)} => {Star Wars (1977)} 0.2905620 0.9351536 0.3107105 1.760179 274
## [2] {Return of the Jedi (1983)} => {Star Wars (1977)} 0.3700954 0.9208443 0.4019088 1.733246 349
## [3] {Terminator, The (1984)} => {Raiders of the Lost Ark (1981)} 0.2025451 0.8801843 0.2301166 2.385097 191
## [4] {Indiana Jones and the Last Crusade (1989)} => {Star Wars (1977)} 0.2163309 0.8680851 0.2492047 1.633941 204
## [5] {Alien (1979)} => {Star Wars (1977)} 0.2025451 0.8565022 0.2364793 1.612139 191
## [6] {Princess Bride, The (1987)} => {Star Wars (1977)} 0.2216331 0.8427419 0.2629905 1.586239 209
## [7] {Raiders of the Lost Ark (1981)} => {Star Wars (1977)} 0.3107105 0.8419540 0.3690350 1.584756 293
## [8] {Terminator 2: Judgment Day (1991)} => {Star Wars (1977)} 0.2014846 0.8407080 0.2396607 1.582410 190
## [9] {Indiana Jones and the Last Crusade (1989)} => {Raiders of the Lost Ark (1981)} 0.2078473 0.8340426 0.2492047 2.260064 196
## [10] {Back to the Future (1985)} => {Star Wars (1977)} 0.2046660 0.8212766 0.2492047 1.545836 193
## [11] {Empire Strikes Back, The (1980)} => {Raiders of the Lost Ark (1981)} 0.2545069 0.8191126 0.3107105 2.219607 240
## [12] {Fugitive, The (1993)} => {Star Wars (1977)} 0.2279958 0.8143939 0.2799576 1.532881 215
## [13] {Monty Python and the Holy Grail (1974)} => {Star Wars (1977)} 0.2078473 0.8099174 0.2566278 1.524455 196
## [14] {Back to the Future (1985)} => {Raiders of the Lost Ark (1981)} 0.2004242 0.8042553 0.2492047 2.179347 189
## [15] {Fugitive, The (1993)} => {Raiders of the Lost Ark (1981)} 0.2184517 0.7803030 0.2799576 2.114442 206
## [16] {Empire Strikes Back, The (1980)} => {Return of the Jedi (1983)} 0.2396607 0.7713311 0.3107105 1.919169 226
## [17] {Toy Story (1995)} => {Star Wars (1977)} 0.2619300 0.7694704 0.3404030 1.448325 247
## [18] {Princess Bride, The (1987)} => {Raiders of the Lost Ark (1981)} 0.2004242 0.7620968 0.2629905 2.065107 189
## [19] {Godfather, The (1972)} => {Star Wars (1977)} 0.2820785 0.7578348 0.3722163 1.426424 266
## [20] {Silence of the Lambs, The (1991)} => {Star Wars (1977)} 0.2714740 0.7441860 0.3647932 1.400733 256
plot(head(rules_sorted_conf, 20), method = 'graph', engine = 'htmlwidget')
Miara support oznacza, jaki odsetek wszystkich oglądających polubił jednocześnie oba filmy.
rules_sorted_supp <- sort(rules, by = 'support', decreasing = TRUE)
inspect(head(rules_sorted_supp, 20))
## lhs rhs support confidence coverage lift count
## [1] {Return of the Jedi (1983)} => {Star Wars (1977)} 0.3700954 0.9208443 0.4019088 1.733246 349
## [2] {Star Wars (1977)} => {Return of the Jedi (1983)} 0.3700954 0.6966068 0.5312831 1.733246 349
## [3] {Raiders of the Lost Ark (1981)} => {Star Wars (1977)} 0.3107105 0.8419540 0.3690350 1.584756 293
## [4] {Star Wars (1977)} => {Raiders of the Lost Ark (1981)} 0.3107105 0.5848303 0.5312831 1.584756 293
## [5] {Empire Strikes Back, The (1980)} => {Star Wars (1977)} 0.2905620 0.9351536 0.3107105 1.760179 274
## [6] {Star Wars (1977)} => {Empire Strikes Back, The (1980)} 0.2905620 0.5469062 0.5312831 1.760179 274
## [7] {Fargo (1996)} => {Star Wars (1977)} 0.2831389 0.6576355 0.4305408 1.237825 267
## [8] {Star Wars (1977)} => {Fargo (1996)} 0.2831389 0.5329341 0.5312831 1.237825 267
## [9] {Godfather, The (1972)} => {Star Wars (1977)} 0.2820785 0.7578348 0.3722163 1.426424 266
## [10] {Star Wars (1977)} => {Godfather, The (1972)} 0.2820785 0.5309381 0.5312831 1.426424 266
## [11] {Silence of the Lambs, The (1991)} => {Star Wars (1977)} 0.2714740 0.7441860 0.3647932 1.400733 256
## [12] {Star Wars (1977)} => {Silence of the Lambs, The (1991)} 0.2714740 0.5109780 0.5312831 1.400733 256
## [13] {Toy Story (1995)} => {Star Wars (1977)} 0.2619300 0.7694704 0.3404030 1.448325 247
## [14] {Star Wars (1977)} => {Toy Story (1995)} 0.2619300 0.4930140 0.5312831 1.448325 247
## [15] {Empire Strikes Back, The (1980)} => {Raiders of the Lost Ark (1981)} 0.2545069 0.8191126 0.3107105 2.219607 240
## [16] {Raiders of the Lost Ark (1981)} => {Empire Strikes Back, The (1980)} 0.2545069 0.6896552 0.3690350 2.219607 240
## [17] {Return of the Jedi (1983)} => {Raiders of the Lost Ark (1981)} 0.2449629 0.6094987 0.4019088 1.651601 231
## [18] {Raiders of the Lost Ark (1981)} => {Return of the Jedi (1983)} 0.2449629 0.6637931 0.3690350 1.651601 231
## [19] {Silence of the Lambs, The (1991)} => {Raiders of the Lost Ark (1981)} 0.2449629 0.6715116 0.3647932 1.819642 231
## [20] {Raiders of the Lost Ark (1981)} => {Silence of the Lambs, The (1991)} 0.2449629 0.6637931 0.3690350 1.819642 231
plot(head(rules_sorted_supp, 20), method = 'graph', engine = 'htmlwidget')
Przygotowane i oczyszczone reguły asocjacyjne można wykorzystać do stworzenia rekomendacji dalszych filmów do oglądania dla osób, które polubiły konkretne filmy. Jako przykład został wzięty film Star Wars (1977), dla którego zostało przygotowane 5 rekomendacji posortowanych po mierze confidence. Są to więc filmy, dla których jest największe prawdopodobieństwo, że oglądający je polubi, jeżeli podobał mu się też oryginalny film.
star_wars_rules <- subset(rules, lhs %in% 'Star Wars (1977)')
star_wars_rules <- sort(star_wars_rules, by = 'confidence', decreasing = TRUE)
inspect(head(star_wars_rules, 5))
## lhs rhs support
## [1] {Star Wars (1977)} => {Return of the Jedi (1983)} 0.3700954
## [2] {Star Wars (1977)} => {Raiders of the Lost Ark (1981)} 0.3107105
## [3] {Star Wars (1977)} => {Empire Strikes Back, The (1980)} 0.2905620
## [4] {Star Wars (1977)} => {Fargo (1996)} 0.2831389
## [5] {Star Wars (1977)} => {Godfather, The (1972)} 0.2820785
## confidence coverage lift count
## [1] 0.6966068 0.5312831 1.733246 349
## [2] 0.5848303 0.5312831 1.584756 293
## [3] 0.5469062 0.5312831 1.760179 274
## [4] 0.5329341 0.5312831 1.237825 267
## [5] 0.5309381 0.5312831 1.426424 266
Na pierwszym miejscu znalazł się sequel tego filmu, czyli Return of the Jedi (1983). 70% osób, którym podobał się oryginalny film, podobał się też ten sequel. Ponadto, szansa polubienia sequela wzrasta około 1.73 razy, jeżeli wiadomo, że dana osoba polubiła oryginalny film. Można też odczytać, że 37% wszystkich osób polubiło oba filmy jednocześnie.