50
王者榮耀
潘金蓮改變了曆史嗎 - PostgreSQL輿情事件分析應用
標簽
PostgreSQL , 獨立事件分析 , 輿情分析 , 輿情事件 , 相關事件 , 行為軌跡 , 獨立事件的流水相關性分析 , PostgreSQL服務端編程實踐
背景
潘金蓮改變了曆史嗎?
網上的段子
潘金蓮撐開窗戶,撐窗戶滴棍子掉下去了,於是西門慶看到了,於是他們相遇了。如果潘金蓮同學當時沒有開窗,那麼她就不會遇到西門慶。
如果沒有遇到西門慶,那麼她就不會被迫出軌,那樣武鬆哥哥就不會怒發衝冠為紅顏,這樣他就不會奔上梁山。
武鬆就不會奔上梁上,不會奔上梁山之後,哪怕水泊梁山107將依舊轟轟烈烈,但是宋江和方臘的戰役,方臘也不會被武鬆單臂擒住。
隻要武鬆治不了方臘,梟雄方臘就能取得大宋的江山。
隻要方臘取得了大宋的江山,就不會有靖康恥,不會有偏安一隅,不會有金兵入關。
金兵不入關,就不會有後來的大清朝。
沒有大清朝,當然也不會有後來的閉關鎖國,沒有慈禧太後。
沒有慈禧太後,沒有閉關鎖國,自然也不會有八國聯軍侵略中國啊,不會有神馬鴉片戰爭啊。
沒有這些殺千刀的戰爭和不平等條約,中國說不定憑借五千年的文化首先就發展資本主義了。
發展了資本主義,發展到今天,說不定中國早就超過了美國、小日本神馬的,趕超了幾百年了。已經是最發達的最強悍的國家了。
所以,誰穿越一下告訴潘金蓮,你有事沒事開神馬窗戶啊!!!
類似蝴蝶效應,曆史是很有趣的事情。
實際上在我們的生活中也有這樣的現象或者需求,比如某些業務係統,會記錄事件,流水賬那樣。
然後業務可能想知道某類事件發生後,接下來發生了什麼,比如說房價調控措施出台後的事件,是不是有大量資金湧入股票市場?
說道這裏,我要把PostgreSQL數據庫搬出來,到底怎麼實現上述需求呢?
模擬現實
1. 構建事件輸入的表結構
create table event(
id serial8 primary key, -- 自增序列,用於區分事件的先後順序
class text, -- 事件類型
info text, -- 事件描述
crt_time timestamp -- 事件發生的時間
);
2. 插入1000萬事件記錄,其中5000個事件的種類。
insert into event (class, info , crt_time) select (5000*random())::int::text, 'test', clock_timestamp() from generate_series(1,10000000);
3. 針對事件種類,創建索引
create index idx_event_class on event (class);
需求
查詢某個事件發生後,若幹個接下來發生的事件
使用函數可以輕鬆實現這個需求
create or replace function f(
sql text, -- 查詢要分析的目標事件對應的ID
v_class text, -- 目標事件的類別
v_n int8, -- 要查看多少個接下來發生的事件
v_limit int -- 分析幾次事件,如果要輸出所有的,那麼可以輸入一個較大值。
) returns setof event as $$
declare
v_id int8;
begin
for v_id in execute sql loop
return query select * from event where id>=v_id order by id limit v_n+1;
v_limit := v_limit - 1;
if v_limit<=0 then
return;
end if;
end loop;
end;
$$ language plpgsql strict;
查詢舉例
查詢事件類別為1的事件,它後麵發生的2個事件,輸出10次分析結果。
postgres=# select * from f('select id from event where class=$$1$$', '1', 2, 10);
id | class | info | crt_time
-------+-------+------+----------------------------
1592 | 1 | test | 2017-03-31 15:07:23.77348
1593 | 3032 | test | 2017-03-31 15:07:23.773483
1594 | 3409 | test | 2017-03-31 15:07:23.773486
2784 | 1 | test | 2017-03-31 15:07:23.777265
2785 | 2819 | test | 2017-03-31 15:07:23.777268
2786 | 87 | test | 2017-03-31 15:07:23.777271
12176 | 1 | test | 2017-03-31 15:07:23.807489
12177 | 2586 | test | 2017-03-31 15:07:23.807491
12178 | 4101 | test | 2017-03-31 15:07:23.807494
19398 | 1 | test | 2017-03-31 15:07:23.83072
19399 | 1179 | test | 2017-03-31 15:07:23.830723
19400 | 4237 | test | 2017-03-31 15:07:23.830726
19571 | 1 | test | 2017-03-31 15:07:23.831296
19572 | 4368 | test | 2017-03-31 15:07:23.831299
19573 | 2313 | test | 2017-03-31 15:07:23.831302
24708 | 1 | test | 2017-03-31 15:07:23.847794
24709 | 1327 | test | 2017-03-31 15:07:23.847797
24710 | 4584 | test | 2017-03-31 15:07:23.847799
29756 | 1 | test | 2017-03-31 15:07:23.864234
29757 | 4386 | test | 2017-03-31 15:07:23.864237
29758 | 3044 | test | 2017-03-31 15:07:23.864239
30224 | 1 | test | 2017-03-31 15:07:23.865765
30225 | 4704 | test | 2017-03-31 15:07:23.865768
30226 | 332 | test | 2017-03-31 15:07:23.865771
32004 | 1 | test | 2017-03-31 15:07:23.871554
32005 | 219 | test | 2017-03-31 15:07:23.871557
32006 | 3548 | test | 2017-03-31 15:07:23.871559
36472 | 1 | test | 2017-03-31 15:07:23.886097
36473 | 640 | test | 2017-03-31 15:07:23.8861
36474 | 1139 | test | 2017-03-31 15:07:23.886103
(30 rows)
利用以上結果,我們就可以知道發生了事件1之後,都發生了其他什麼事件。
至於你要拿這些結果進行接下來的分析,可以使用類似關鍵詞的熱點分析方法,或者使用PostgreSQL提供的MADlib機器學習庫,又或者使用plR進行分析。
總之你肯定有方法找出事件之間的關聯關係。
非獨立事件的相關性分析
因為前麵分析的都是獨立事件,即本身就沒有相關性的,所以需要通過函數的方法來輸出結果。
對於非獨立事件,比如說用戶逛淘寶的點鼠標的行為,在點了某個商品後,又點了哪些其他商品。
對於非獨立事件,在結構設計上,就有關聯字段,比如USERID,所以我們可以很方便的進行關聯。
使用PostgreSQL遞歸調用,就可以對非獨立事件進行軌跡分析。
例子
《PostgreSQL 遞歸查詢CASE - 樹型路徑分組輸出》
《用PostgreSQL找回618秒逝去的青春 - 遞歸收斂優化》
《distinct xx和count(distinct xx)的變態遞歸優化方法 - 索引收斂(skip scan)掃描》
《PostgreSQL 使用遞歸SQL 找出數據庫對象之間的依賴關係》
《PostgreSQL Oracle 兼容性之 - WITH 遞歸 ( connect by )》
《遞歸優化CASE - group by & distinct tuning case : use WITH RECURSIVE and min() function》
小結
PostgreSQL的遞歸語法、plpgsql編程,可以很好的滿足輿情分析中事件前後事件的分析需求。
再利用PostgreSQL的熱點詞分析,聚類分析或者使用PostgreSQL提供的MADlib機器學習庫,又或者使用plR進行分析。找出事件之間的關聯關係。
最後更新:2017-04-01 17:13:51