Machine Learning: Как да анализираме последователност от състояния/събития?

Автор: Десислава Христова

Анализът на последователност от състояния/събития е една доста интересна задача, която намира широко приложение в различни области. Например в търговията при анализ на поведението на клиентите или при изследване на определена бизнес ситуация като продажба или друга дейност, която преминава през различни етапи.

С получените резултати от анализа можем да достигнем до конкретни изводи и да предприемем действия, с които да подпомогнем работата на бизнеса.

Тази тема беше разгледана на нашия семинар от 12 март 2021 - Бизнес и маркетинг с R: Как да анализираме поредица от събития и състояния?

По време на семинара чрез практически пример бяха представени възможностите на пакетите TraMineR и arulesSequences за езика R. В тази статия ще ви покажа в контекста на същия пример как можем да анализираме последователност от състояния/събития само че с езика за програмиране Python.

С какви данни ще работим?

Извадката съдържа 2000 наблюдения с данни от социологическо проучване за семейното състояние. Участниците са на възраст между 15 и 30 години.

Състоянията са кодирани по следния начин:

КодСъстояниеОтделноСемействоДецаРазвод
0Parent (P)нененене
1Left (L)даненене
2Married (M)недада/нене
3Left+Marr (LM)даданене
4Childr (C)ненедане
5Left+Childr (LC)данедане
6Left+Marr+Childr (LMC)дададане
7Divorced (D)да/неда/неда/неда

5 произволни реда от данните:

 idhoussexbirthyrnat_1_02plingu02p02r01p02r04cspfajcspmoja15a16a17a18a19a20a21a22a23a24a25a26a27a28a29a30wp00tbgpwp00tbgsyr_cuts
32769531woman1926SwitzerlandgermanProtestant or Reformed Churchabout once a monthqualified manual professionsnan00000000033666661385.641.229731919-28
386nanwoman1945nannannannanqualified non-manual professionsnan00000000111111111280.91.136781939-48
762nanman1934nannannannannannan00000000000000331764.671.566121929-38
150189821man1911Switzerlandnannannanunqualified non-manual and manual workersnan00000000000006661158.911.028511909-18
175259191man1951SwitzerlandfrenchRoman Catholiconce a weekintermediate professionsnan0000000000000013757.7410.6724831949-58

Как изглеждат описателните статистики?

За да добием малко повече представа за това с какви данни разполагаме, ще погледнем описателните статистики (мода, медиана, средна стойност, стандартно отклонение и др.). Те ни позволяват на пръв поглед да видим кои са най-често срещаните стойности в данните.

Първо ще погледнем описателните статистики за числовите променливи в извадката. За тази цел ще използваме метода describe, предоставен от библиотеката за анализ на данни Pandas.

 idhousbirthyra15a16a17a18a19a20a21a22a23a24a25a26a27a28a29a30wp00tbgpwp00tbgs
count17762000200020002000200020002000200020002000200020002000200020002000200020002000
mean73908.71942.530.0140.0520.080.1540.2780.5020.7761.131.4861.8442.3242.7163.0653.43.663.8881193.871.06
std4273610.460.1180.2220.3050.5540.8081.1351.4171.7321.9512.1032.2432.3172.3382.3492.322.279707.3230.628
min27611909000000000000000000
25%3624119350000000000011112797.2890.708
50%72716194400000000.5111233331007.050.894
75%109864195100000111233666661381.111.226
max148921195711666677777777776793.166.029

Годините на раждане са със стойности от 1909 до 1957. Средната година на раждане е 1943 година. За останалите колони describe не дава особено полезна информация, тъй като колоните с години на участниците в проучването (от а15 до а30) съдържат кодове на състоянията. По-нататък в задачата ще анализираме данните в тях.

За да видим описателните статистики за категорийните променливи, ще използваме отново метода describe, но на параметъра include ще зададем стойността object.

 sexnat_1_02plingu02p02r01p02r04cspfajcspmoj
count200017751647156615661584552
unique221391088
topwomanSwitzerlandgermanProtestant or Reformed Churchonly for family ceremoniesother self-employedother self-employed
freq109216471125711521551258

От таблицата става ясно например, че в извадката има най-много хора, които са швейцарци и такива с роден език немски. Също така ако погледнем колоната пол, ще видим, че мъжете и жените са приблизително равномерно разпределени. Жените са 1092 на брой, а останалите 908 са мъже.

Изследване на данните

Ще работим предимно с колоните от а15 до а30, тъй като те съдържат данните за състоянията, които ще анализираме. За няколко визуализации ще използваме и някои от останалите колони - пол (sex), година на раждане (birthyr) и роден език
(plingu02).

Първо ще отделим само тези колони в нов DataFrame.

Данните изглеждат по следния начин:

 a15a16a17a18a19a20a21a22a23a24a25a26a27a28a29a30
2030111111111111111
15390000000002277777
11700000003333666666
13670000066666666666
1980111111666666666

Тъй като така с числа е малко по-трудно да разберем за кое състояние точно става въпрос и е нужно да правим справка, ще кодираме стойностите, за да е по-лесна интерпретацията на данните.

След кодиране на състоянията данните изглеждат така:

 a15a16a17a18a19a20a21a22a23a24a25a26a27a28a29a30
203PLLLLLLLLLLLLLLL
1539PPPPPPPPPMMDDDDD
1170PPPPPPLMLMLMLMLMCLMCLMCLMCLMCLMC
1367PPPPPLMCLMCLMCLMCLMCLMCLMCLMCLMCLMCLMC
198PLLLLLLLMCLMCLMCLMCLMCLMCLMCLMCLMC

Например нека погледнем ред 1170 от таблицата. При него до 20 годишна възраст участникът е живял при родителите си, след което е напуснал и сключил брак на 21 години и 4 години по-късно е имал дете. Състоянието не се променя след това до 30 годишна възраст.

Вероятности за преминаване от едно състояние в друго

С функцията crosstab() първо ще изчислим за всеки ред броя преходи между отделните състояния, след което ще ги групираме и агрегираме с функцията sum() в една обща кръстосана таблица и накрая ще разделим на общия брой за всеки ред, за да получим условните вероятности.

Резултат:

->PLMLMCLCLMCD
P0.8860.0550.0150.03200.0010.0110
L00.8900.08300.0040.0230
M000.9690.01000.0110.01
LM0000.787000.1990.014
C000.12500.8120.06200
LC000000.8820.1180
LMC0000000.9940.006
D00000001

Получената таблица е по-различна от стандартната кръстосана таблица, която е симетрична (A -> B е равно на B -> A) и съответно стойностите по диагонала са равни на единица. Тук това не е така и елементите по диагонала отразяват вероятността даденият човек да се намира в конкретното състояние. Най-стабилно е LMC, т.е. участниците, които са семейни, не живеят при родителите и имат деца - 0.994. Другото стабилно състояние е M (сключили брак) със стойност 0.969. При D (разведените) се е получила единица, защото това е последното състояние и данните са ограничени, тъй като обхващат 30 годишен период.

Средна продължителност за пребиваване в състояние

С помощта на стълбовидни диаграми ще представим графично колко време средно участниците пребивават в дадено състояние. Първо ще видим общо за всички участници, а след това според колоната пол.

mean time barchart

Най-високо средно време участниците прекарват в състояние P (при родителите). На второ и трето място по средно време са състоянията L (живеят самостоятелно) и LMC (живеят самостоятелно, имат брак и деца).

Нека сега да видим какви са разликите в средното време за пребиваване в дадено състояние при мъже и жени.

mean_time_barchart_gender

От визуализацията става ясно, че мъжете средно живеят по-дълго време при родителите, докато жените по-продължително време са семейни с деца.

Визуализация на определени последователности

На следващите визуализации ще представим определени последователности за конкретни диапазони от индекси. Първо ще видим началните 10, а след това за всички 2000 наблюдения.

first 10 sequences

Нека погледнем например реда с индекс 4. Този участник е живял при родителите си до 19 годишна възраст, след което е напуснал дома и на 27 години е сключил брак и е имал дете.

index plot

На тази визуализация можем да видим, че синьото надделява над останалите цветове до около 19 годишна възраст, което отново потвърждава извода, който направихме по-рано, че участниците прекарват най-много време, живеейки при родителите си. След 21 години прави впечатление най-вече розовият цвят, който е за състоянието LMC, т.е. след тази възраст повечето участници живеят самостоятелно, имат сключен брак и дете.

Използване на алгоритъма PrefixSpan за откриване на чести последователности

Алгоритъмът PrefixSpan е начин да открием кои последователности от състояния/събития се срещат по-често в нашата извадка. Това става на базата на предварително зададен праг (threshold) за честота на срещане.

Алгоритъмът първо открива тези, които са с дължина от 1 елемент, след което продължава с последователности от повече елементи. Полученият резултат е в следния вид:

<последователност> : <честота на срещане>

За нашия пример, нека кажем, че искаме да видим само онези последователности, които се срещат в 25% от данните. Тъй като имаме 2000 наблюдения, е нужно да видим тези последователности, които се срещат в минимум 500 от тях.

Ще използваме пакета на Python - prefixspan за тази цел.

 countfrequent sequence pattern
01972['P']
11896['P', 'P']
21847['P', 'P', 'P']
31762['P', 'P', 'P', 'P']
41631['P', 'P', 'P', 'P', 'P']
51411['P', 'P', 'P', 'P', 'P', 'P']
61191['P', 'P', 'P', 'P', 'P', 'P', 'P']
71000['P', 'P', 'P', 'P', 'P', 'P', 'P', 'P']
8833['P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P']
9682['P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P']
10509['P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P']
11564['P', 'P', 'P', 'P', 'P', 'P', 'P', 'LM']
12677['P', 'P', 'P', 'P', 'P', 'P', 'LM']
13604['P', 'P', 'P', 'P', 'P', 'P', 'LMC']
14543['P', 'P', 'P', 'P', 'P', 'P', 'LMC', 'LMC']
15792['P', 'P', 'P', 'P', 'P', 'LM']
16538['P', 'P', 'P', 'P', 'P', 'LM', 'LM']
17712['P', 'P', 'P', 'P', 'P', 'LMC']
18638['P', 'P', 'P', 'P', 'P', 'LMC', 'LMC']
19556['P', 'P', 'P', 'P', 'P', 'LMC', 'LMC', 'LMC']

От таблицата става ясно, че най-често срещаните последователности са тези, при които участникът живее известно време при родителите, след което сключва брак и напуска дома. В повече от 700 от всички случаи има и деца.

Как са разпределени състоянията във времето и какво се променя?

Със следващите графики ще представим разпределението на състоянията във времето. Първо ще видим общо за всички наблюдения, а след това според пол и роден език.

chronogram general

Можем да кажем, че 50% от участниците на възраст 22 години живеят при родителите си, след това с нарастване на възрастта това започва да се променя. Има много малко хора, които са разведени и те са след 25 годишна възраст. Преди това са много редки такива случаи.

Хронограмите според пола на участниците изглеждат по следния начин:

Има доста повече разведени при жените отколкото при мъжете. На 23 годишна възраст 51% от мъжете живеят при родителите си, за разлика от жените, от които 34% са в това състояние на тази възраст. Можем да кажем, че жените по-рано напускат родния дом и живеят самостоятелно. Също отново можем да достигнем до извода, че повече жени са със сключен брак и имат деца отколкото мъже.

Хронограмите според родния език на участниците са следните:

18% от всички италианци, на 29 годишна възраст все още живеят при родителите си за разлика от французите и германците, които са респективно 7% и 9%. За сметка на това обаче само 1% от италианците са разведени. Най-голям е броят на разведените при французите.

Ентропия

Като метрика за оценка на състоянията ще използваме ентропия. Тя е мярка за неопределеност и се повишава с нарастване на състоянията. Ентропията достига максимум, когато всички състояния са с равна вероятност и може да е вертикална или хоризонтална

При изчисление на ентропията ще използваме основа 8, защото имаме 8 възможни състояния. Необходимо е първо да открием стойностите на метриката по колони (вертикална), след което ще визуализираме данните в линейна диаграма.

entropy_line

От графиката можем да достигнем до следните изводи:

  • на 15 години всички се намират в едно и също състояние (при родителите) ~ 0
  • между 24-27 години - активна смяна на семейния статус
  • над 27 има лек спад, но нивото остава високо

Нека сега да видим какво е положението според пола на участниците и годините на раждане. Ще изчислим ентропията по редове (хоризонтална), след което ще запазим данните в нов DataFrame и след това ще изградим диаграми тип "кутия".

В следната таблица са представени 5 случайни реда от данните, които ще използваме за изграждане на визуализациите по-надолу:

 sexyrsentropy
940man1929-380.37388
61woman1939-480.329566
1298man1949-580.423927
1103woman1949-580.473246
1392woman1949-580.5
boxplots_gender

На визуализацията можете да видите диаграми тип "кутия", представящи разпределението на ентропията според пола на участниците. Можем да кажем, че жените са по-склонни да сменят социалния си статус отколкото мъжете.

boxplots_year_birth

Необходимо е към годините на раждане да добавим съответните години от колоните a15-a30, за да добием представа за кой период става въпрос. От визуализацията можем да стигнем до извод, че през 70-те и 80-те години на XX век, хората са били по-активни в смяната на своя социален статус, отколкото в първата половина на века.

Цялостния пример можете да изтеглите от тук.

Извод

С получените резултати от анализа на състояния и събития можем да намерим отговорите на конкретни бизнес въпроси като например кои са типичните последователности, има ли прилики между тях и можем ли да отделим определени модели. Това би помогнало много за подобряването на работата на бизнеса.

Искате да научите повече за машинното обучение?

Включете се в курса по машинно обучение и анализ на данни с Python.

© Copyright 2019 DeviseExpert Всички права запазени
envelopephone-handsetmap-marker linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram