
2.3. Алгоритми
2.3.1. Алгоритм Apriori
Виявлення частих наборів об'єктів – операція, що вимагає великої кількості обчислень, а отже, і часу. Алгоритм Apriori описаний в 1994 р. Срікантом Рамакрішнан (Ramakrishnan Srikant) і Ракешом Агравалом (Rakesh Agrawal). Він використовує одну з властивостей підтримки, яка стверджує: підтримка будь-якого набору об'єктів не може перевищувати мінімальної підтримки будь-якої з його підмножин:
,
за
.
Наприклад, підтримка 3-об'єктного набору {пиво, вода, чіпси} буде завжди менше або дорівнювати підтримці 2-об'єктних наборів {пиво, вода}, {вода, чіпси}, {пиво, чіпси}. Це пояснюється тим, що будь-яка транзакція, яка містить {пиво, вода, чіпси}, містить також і набори {пиво, вода}, {вода, чіпси}, {пиво, чіпси}, причому обернене невірно.
Алгоритм Apriori
визначає набори, що часто зустрічаються
за кілька етапів. На
-му
етапі визначаються всі
-елементні
набори, що часто зустрічаються. Кожен
етап складається з двох кроків: формування
кандидатів (candidate generation) і підрахунку
підтримки кандидатів (candidate counting).
Розглянемо
-й
етап. На кроці формування кандидатів
алгоритм створює множину кандидатів з
-елементних
наборів, чия підтримка поки не
вираховуються. На кроці підрахунку
кандидатів алгоритм сканує множину
транзакцій, обчислюючи підтримку
наборів-кандидатів. Після сканування
відкидаються кандидати, підтримка яких
менша певного мінімуму, визначеного
користувачем, і зберігаються тільки
-елементні
набори, що часто зустрічаються. Під час
1-го етапу вибрана множина наборів-кандидатів
містить всі 1-елементні часті набори.
Алгоритм обчислює їх підтримку під час кроку підрахунку кандидатів.
Описаний алгоритм можна записати у вигляді наступного псевдокоду:
L1 = {1-елементні набори, що часто зустрічаються }
для (k=2; Lk-1 <>ø; + +)
Сk=Apriorigen (Fk-l) // генерація кандидатів
для
всіх транзакцій
виконати
Ct=subset (Ck, t) // видалення надлишкових правил
для
всіх кандидатів
виконати
с.count + +
кінець для всіх
кінець для всіх
//
відбір кандидатів
кінець для
Результат
.
Опишемо позначення, які використовуються в алгоритмі:
-
– множина
-елементних частих наборів, чия підтримка не менше заданої користувачем. Кожен елемент множини має набір впорядкованих (
, якщо
) елементів
і значення підтримки набору
:
,
де
;
-
– множина кандидатів
-елементних наборів, потенційно частих. Кожен елемент множини має набір упорядкованих (
, якщо
) елементів
і значення підтримки набору
.
Опишемо даний алгоритм по кроках.
Крок 1. Присвоїти
і виконати відбір всіх 1-елементних
наборів, у яких підтримка більше
мінімально заданої користувачем
.
Крок 2.
.
Крок 3. Якщо не
вдається створювати
-елементні
набори, то завершити алгоритм, інакше
виконати наступний крок.
Крок 4. Створити
множину
-елементних
наборів кандидатів у часті набори. Для
цього необхідно об'єднати в
-елементні
кандидати (
)-елементні
часті набори. Кожен кандидат
буде формуватися шляхом додавання до
(
)-елементного
частого набору –
елемента з іншого (
)-елементного
частого набору –
.
Причому додається останній елемент
набору
,
який за порядком вище, ніж останній
елемент набору
(
).
При цьому перші всі
елемента обох наборів однакові (
).
Це може бути записано у вигляді наступного SQL-подібного запиту.
insert into Ck
select p.item1, p.item2, ..., p.itemk-1, q.item k-1
from L k-1 p, L k-1 q
where p.item1=q.item1, p.item2=q.item2,. .., p.itemk-2=q.item k-2,
p.item k-1<q.item k-1
Крок 5. Для кожної
транзакції
з множини
вибрати кандидатів
з множини
присутніх в транзакції
.
Для кожного набору з побудованої множини
видалити набір, якщо хоча б одна з його
(
)
підмножин не часто зустрічається, тобто
відсутня у множині
.
Це можна записати у вигляді наступного
псевдокоду:
для
всіх наборів
виконати
для
всіх ()–піднаборів
з
виконати
якщо
()
то
видалити
з
Крок 6. Для кожного
кандидата з множини
збільшити значення підтримки на одиницю.
Крок 7. Вибрати
тільки кандидатів
з множини
,
у яких значення підтримки більше заданої
користувачем
.
Повернутися до кроку 2.
Результатом роботи
алгоритму є об'єднання всіх множин
для всіх
.
Розглянемо роботу
алгоритму на прикладі, наведеному в
табл. 6.1, при
.
На першому кроці маємо наступну множину
кандидатів
(вказуються ідентифікатори товарів)
(табл. 6.5).
Таблиця 6.5
№ |
Набір |
|
1 |
{0} |
0 |
2 |
{1} |
0,5 |
3 |
{2} |
0,75 |
4 |
{4} |
0,25 |
5 |
{3} |
0,75 |
6 |
{5} |
0,75 |
Заданій мінімальній підтримці задовольняють лише кандидати 2, 3, 5 і 6, отже:
={{1},
{2}, {3}, {5}}.
На другому кроці
збільшуємо значення
до двох. Так як можна побудувати
2-елементні набори, то отримуємо множину
(табл. 6.6).
Таблиця 6.6
№ |
Набір |
|
1 |
{1,2} |
0,25 |
2 |
{1,3} |
0,5 |
3 |
{1,5} |
0,25 |
4 |
{2,3} |
0,5 |
5 |
{2,5} |
0,75 |
6 |
{3,5} |
0,5 |
З побудованих кандидатів заданій мінімальній підтримці задовольняють лише кандидати 2, 4, 5 і 6, отже:
={{1,3},
{2,3}, {2,5}, {3,5}}.
На третьому кроці
перейдемо до створення 3-елементних
кандидатів і підрахунку їх підтримки.
В результаті отримаємо наступну множину
(табл. 6.7).
Таблиця 6.7
№ |
Набір |
|
1 |
{2,3,5} |
0,5 |
Даний набір задовольняє мінімальну підтримку, отже:
={{2,
3,5}}.
Так як 4-елементні набори створити не вдасться, то результатом роботи алгоритму є множина:
={{1},
{2}, {3}, {5}, {1,3}, {2, 3}, {2, 5}, {3, 5}, {2, 3, 5}}.
Для підрахунку підтримки кандидатів потрібно порівняти кожну транзакцію з кожним кандидатом. Очевидно, що кількість кандидатів може бути дуже великою і потрібен ефективний спосіб підрахунку. Набагато швидше і ефективніше використовувати підхід, оснований на зберіганні кандидатів в хеш-дереві. Внутрішні вузли дерева містять хеш-таблиці з покажчиками на нащадків, а листя – на кандидатів. Це дерево використовується при швидкому підрахунку підтримки для кандидатів.
Хеш-дерево будується щоразу, коли формуються кандидати. Спочатку дерево складається тільки з кореня, який є листом, і не містить ніяких кандидатів-наборів. Кожного разу, коли формується новий кандидат, він заноситься в корінь дерева, і так до тих пір, поки кількість кандидатів в корені-листі не перевищить якогось порогу. Як тільки це відбувається, корінь перетворюється в хеш-таблицю, тобто стає внутрішнім вузлом, і для нього створюються нащадки-листя. Усі кандидати розподіляються по вузлах-нащадкам згідно хеш-значенням елементів, що входять у набір. Кожен новий кандидат хеширується на внутрішніх вузлах, поки не досягне першого вузла-листа, де він і буде зберігатися, поки кількість наборів знову ж таки не перевищить порогу.
Після того як
хеш-дерево з кандидатами-наборами
побудовано, легко підрахувати підтримку
для кожного кандидата. Для цього потрібно
"пропустити" кожну транзакцію
через дерево і збільшити лічильники
для тих кандидатів, чиї елементи також
містяться і в транзакції,
.
На кореневому рівні хеш-функція
застосовується до кожного об'єкта з
транзакції. Далі, на другому рівні,
хеш-функція застосовується до других
об'єктів і т. д. На
-у
рівні хеширується
-елемент,
і так до тих пір, поки не досягнемо листа.
Якщо кандидат, що зберігається в листі,
є підмножиною, що розглядається в
транзакції, збільшуємо лічильник
підтримки цього кандидата на одиницю.
Після того як кожна транзакція з вихідного набору даних "пропущена" через дерево, можна перевірити, чи задовольняють значення підтримки кандидатів мінімальному порогу. Кандидати, для яких ця умова виконується, переносяться в розряд тих, що часто зустрічаються. Крім того, слід запам'ятати і підтримку набору, яка стане в нагоді при побудові правил.
Ці ж дії застосовуються
для знаходження ()-елементних
наборів і т. д.
2.3.2. Різновиди алгоритму Apriori
Алгоритм AprioriTid є
різновидом алгоритму Apriori. Відмінною
рисою даного алгоритму є підрахунок
значення підтримки кандидатів не при
скануванні множини
,
а з допомогою множини
,
що є множингою кандидатів (
-елементних
наборів) потенційно частих, у відповідність
яким ставиться ідентифікатор TID
транзакцій, в яких вони містяться.
Кожен член множини
є парою виду <TID, {
}>,
де кожен
є потенційно частим
-елементним
набором, представленим в транзакції з
ідентифікатором TID. Множина
відповідає множині транзакцій, хоча
кожен об'єкт в транзакції відповідає
одно-об'єктному набору в множині
,
що містить цей об'єкт. Для
множина
генерується відповідно до алгоритму,
описаному нижче. Член множини
,
що відповідає транзакції
,
є парою наступного виду:
<T.TID, {}>.
Підмножина наборів
у
з однаковими TID (тобто містяться в одній
і тій же транзакції) називається записом.
Якщо транзакція не містить ні одного
-елементного
кандидата, то
не буде мати запису для цієї транзакції.
Тобто кількість записів в
може бути менше, ніж в
,
особливо для великих значень
.
Крім того, для великих значень
кожен запис може бути менше, ніж відповідна
їй транзакція, тому що в транзакції буде
міститися мало кандидатів. Однак для
малих значень
кожен запис може бути більше, ніж
відповідна транзакція, тому що
включає всіх кандидатів
-елементних
наборів, що містяться в транзакції.
Іншим різновидом алгоритму Apriori є алгоритм MSAP (Mining Sequential Alarm Patterns), спеціально розроблений для виконання сиквенціального аналізу збоїв телекомунікаційної мережі.
Він використовує
таку властивість підтримки послідовностей:
для будь-якій послідовності
її підтримка буде менше, ніж підтримка
послідовностей з множини
.
Алгоритм MSAP для пошуку подій, що йдуть одна за одної, використовує поняття "термінового вікна" (Urgent Window). Це дозволяє виявляти не просто однакові послідовності подій, а наступні один за одним. У Алгоритм MSAP для пошуку подій, наступних один за одним, використовує поняття "термінового вікна" (Urgent Window). Це дозволяє виявляти не просто однакові послідовності подій, а ті, що йдуть одна за одною. В іншому даний алгоритм працює за тим же принципом, що і Apriori.