[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

Eastmount發表於2019-01-24

本文主要是作者學習輿情分析、情感分析、人類行為動力學分析的線上筆記,主要包括兩方面內容,一是冪律特性,二是講解時間間隔分佈,三是Python繪製基於時間間隔分佈的冪律特性圖,四提供了另一種方法。基礎性文章,希望對您有所幫助。

參考前文:
[Python輿情分析] 一.輿情事件的冪律特性分析及時間間隔分佈圖繪製
[python資料分析] 簡述冪率定律及繪製Power-law函式

PS:最近參加CSDN2018年部落格評選,希望您能投出寶貴的一票。我是59號,Eastmount,楊秀璋。投票地址:https://bss.csdn.net/m/topic/blog_star2018/index

[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

一.冪律分佈

在我們的日常生活中Power Law(冪次分佈,Power-law Distributions)是常見的一個數學模型,如二八原則。這個世界上是20%的人掌握80%的人的金錢去經營,20%的人口擁有80%的財富,20%的上市公司創造了80%的價值,80%的收入來自20%的商品,80%的利潤來自20%的顧客等等。

下圖表示人類的財富冪率分佈圖,極少數人擁有微弱優勢的人卻擁有天文級別的財富。

[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

為什麼會有這樣的差別呢?
這是因為時間的乘積效應,智力上的微弱優勢,乘以時間,就會得到價值(財富)幾何級的增長。經濟學財富分佈滿足Pareto Power law tail分佈,語言中有詞頻的冪律分佈,城市規模和數量滿足冪律分佈,音樂中有f分之1噪音(冪律分佈)。通常人們理解冪律分佈就是所謂的馬太效應,二八原則,即少數人聚集了大量的財富,而大多數人的財富數量都很小,因為勝者通吃的原則。

f(x)表示某一數量指標x的發生次數,即冪率分佈公式。

[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

冪率公式推導參考kevinelstri大神的 部落格,如下圖所示:

[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

再如錢學森通訊反應間隔分佈:

[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

二.輿情分析基礎知識

該部分主要借鑑引用如下論文,強烈推薦讀者學習,尤其是研究輿情分析、圖書情報、人類行為動力學的同學。

  • 閆小勇. 人類個體出行行為的統計特徵. 電子科技大學學報, 2011.
  • 劉海鷗, 等. 線上社交活動中的使用者畫像及其資訊傳播行為研究. 情報科學, 2018.
  • 樑曉敏, 等. 輿情時間中評論物件的情感分析及其關係網路研究. 情報科學, 2018.
  • 郭宇, 等. 基於情感分析的社會網路使用者影響力模型研究. 情報科學, 2018.
  • Barabasi A-L. The origin of bursts and heavy tails in human dynamics. Natrue(London),2005,435:207-211.
  • 王澎. 人類線上行為的實證和建模. 安徽:中國科學技術大學,2010.

隨著網際網路迅速發展,社交網路發展為民眾瞭解社會現象、輿情事件的重要平臺,帶來便利的同時,部分網民也會在網際網路上宣洩情感,引發公共輿情事件。為了更好地進行輿情監控和情感預警,把握網民的情感趨向,基於人類行為動力學的輿情事件分析,探究輿情物件的情感變化和關係演化是非常必要的。

人類個體行為是隱藏在許多複雜社會經濟現象背後的驅動力,定量理解人類行為是現代科學的一個重要研究課題。2005年,Barabási研究顯示人類行為間隔規律是高度非均勻的,稱之服從冪律分佈,並在《自然》發表了一篇文章,開創了“人類行為動力學”的新研究方向。目前,科學家通過大量的實證統計發現了一些人類行為,如郵件通訊、簡訊通訊、網頁瀏覽、電影點播、微博事件等的時間間隔近似服從冪律分佈,這種冪律分佈特性無論在群體水平還是個體水平上都可以得到證實。除了發現人類行為的時間間隔分佈中廣泛存在的冪律現象外,近年來證實研究發現在人類的空間運動行為中也存在冪律分佈特性,如停留時間分佈和出行距離分佈。

常見的人類行為動力學分析包括:時間間隔分佈、活躍性分析、時間間隔分佈寬度、時間間隔重標度、互動週期與熱度分析、互動的陣發性和記憶性分析等。劉海鷗等老師研究發現微博、QQ群、天涯論壇、人人網服從冪律分佈如下圖所示,表明線上社交活動少數人處於活躍狀態,積極頻繁地釋出訊息,而大部分成員活躍性較低,處於靜默狀態。

[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

三.Python時間間隔分佈圖繪製

為解釋人類個體為何具有高概率進行長時間停留的特徵,通常會對個體在統計時間段內的日常活動事件序列進行分析。冪律特性分析通常會得到如下圖所示的圖形,而它如何通過Python進行繪製呢?

[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

1.資料集
假設作者定義網路爬蟲抓取了天涯社群某一個事件(如“嫦娥四號”事件)的992條回覆資訊,包括id、主題使用者、評論點贊數、評論被追評數、評論內容、評論時間、積極情緒分數。現在需要繪製時間間隔分佈圖。

[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

2.SQL語句
接著通過Python呼叫本地的MySQL資料庫,並獲取每個評論的時間,然後繪製胖尾圖,其中SQL語句核心程式碼如下:

select zhutishijian from yq_ml;

輸出結果如下所示:

[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

Python訪問MySQL資料庫的核心程式碼如下,本地資料庫名為“20181228db”。

class lianjie(object):
    def __init__(self):
        pass
    def connect(self,hostaddress):
        self.conn = msd.connect(host = hostaddress,user = "root",passwd = "123456",db = "20181228db",charset = 'utf8')
        #cur = self.conn.cursor()
        return self.conn
    def guanbi(self):
        return self.conn.close()

3.時間間隔分佈胖尾圖

核心步驟如下:

  • 通過SQL語句獲取每條評論的時間
  • 對評論時間陣列進行排序,然後依次獲取兩兩評論時間的時間間隔
  • 通過函式計算myset內容的無重複項,並統計每個時間間隔出現的頻次
  • 最後繪製Pow-low冪律分佈圖

完整程式碼如下:

# -*- coding: utf-8 -*-
from pylab import *
import MySQLdb as msd
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime

#繪圖顯示中文字型和負號
plt.rcParams['font.sans-serif'] = ['SimHei'] 
myfont = matplotlib.font_manager.FontProperties(fname='C:/Windows/Fonts/msyh.ttf')  
plt.rcParams['axes.unicode_minus'] = False 
font1 = {'family' : 'Times New Roman', 'weight' : 'normal', 'size'   : 26}

#連結本地資料庫20181228db
class lianjie(object):
    def __init__(self):
        pass
    def connect(self,hostaddress):
        self.conn = msd.connect(host = hostaddress,user = "root",passwd = "123456",
                                db = "20181228db",charset = 'utf8')
        return self.conn
    def guanbi(self):
        return self.conn.close()

#時間間隔 冪律分佈
if __name__ == '__main__':
    #呼叫資料
    lj = lianjie()
    conn = lj.connect("localhost")
    cur=conn.cursor()  
    #查詢評論時間
    sql = "select zhutishijian from yq_ml;"
    cur.execute(sql)
    times = cur.fetchall()
    PLTimeList = [] #評論時間列表
    Period= [] #時間間隔
    PeriodSeconds = []

    #獲取時間
    for i in times:
        PLTimeList.append(datetime.strptime(str(i[0]),"%Y-%m-%d %H:%M:%S"))

    PLTimeList.sort() #時間排序
    PLTimeList.reverse() #列表中元素反向

    #獲取時間間隔再賦值給列表
    for i in range(0, len(PLTimeList)-1):    
       cnt = (PLTimeList[i]-PLTimeList[i+1]) 
       Period.append(cnt)
    #獲取秒
    for i in Period:
        PeriodSeconds.append(i.seconds)
    print (PeriodSeconds)

    #myset是另外一個列表,裡面的內容是mylist裡面的無重複項
    x = []
    y = []
    myset = set(PeriodSeconds)  
    for item in myset:
        #print("the %d has found %d" %(item, PeriodSeconds.count(item)))
        x.append(item)
        y.append(PeriodSeconds.count(item)) #出現數量

    #繪圖
    plt.subplot(111)
    plt.plot(x, y,'ko')
    plt.yscale('log')
    plt.ylabel('P', font1)
    plt.xlabel('timespan', font1)
    plt.xscale('log')
    plt.ylim(0.5,20)
    #plt.xlim(0.001,)
    plt.show()

繪製最終的結果如下所示:

[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

四.SQL語句獲取時間間隔

由於作者比較喜歡SQL語句解決一些問題(雖然後臺語言積極更好),但這裡也提供這種SQL語句計算時間間隔的方法。因為感覺語言之間相互轉化並解決問題挺有意思的,希望讀者也試試。

1.時間間隔排序,ord_num為序號,輸出下標從2開始,命名為A

select a.id, a.zhutishijian, (@i := @i + 1) as ord_num 
from yq_ml a,(select @i := 1) d 
order by zhutishijian
[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

2.時間間隔排序,ord_num為序號,下標從1開始,命名為A。

[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

3.利用TIMESTAMPDIFF獲取A和B的時間間隔,該SQL語句較為複雜。

select TIMESTAMPDIFF(SECOND, A.zhutishijian, B.zhutishijian) sub_seconds, count(A.id)
from 
(select a.id, a.zhutishijian, (@i := @i + 1) as ord_num from yq_ml a,(select @i := 1) d 
 order by zhutishijian) as A 
LEFT JOIN 
(select a.id, a.zhutishijian, (@j := @j + 1) as ord_num from yq_ml a,( select @j := 0) c 
 order by zhutishijian) as B 
on A.ord_num=B.ord_num GROUP BY sub_seconds;

輸出結果是各時間差出現的頻次。

[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

4.Python完整程式碼。

# -*- coding: utf-8 -*-
from pylab import *
import MySQLdb as msd
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime

#繪圖顯示中文字型和負號
plt.rcParams['font.sans-serif'] = ['SimHei'] 
myfont = matplotlib.font_manager.FontProperties(fname='C:/Windows/Fonts/msyh.ttf')  
plt.rcParams['axes.unicode_minus'] = False 
font1 = {'family' : 'Times New Roman', 'weight' : 'normal', 'size'   : 26}

#連結本地資料庫20181228db
class lianjie(object):
    def __init__(self):
        pass
    def connect(self,hostaddress):
        self.conn = msd.connect(host = hostaddress,user = "root",passwd = "123456",
                                db = "20181228db",charset = 'utf8')
        return self.conn
    def guanbi(self):
        return self.conn.close()

#時間間隔 冪律分佈
if __name__ == '__main__':
    #呼叫資料
    lj = lianjie()
    conn = lj.connect("localhost")
    cur=conn.cursor()  
    #查詢評論時間
    sql = """select TIMESTAMPDIFF(SECOND, A.zhutishijian, B.zhutishijian) sub_seconds, count(A.id)
        from 
        (select a.id, a.zhutishijian, (@i := @i + 1) as ord_num from yq_ml a,(select @i := 1) d 
         order by zhutishijian) as A 
        LEFT JOIN 
        (select a.id, a.zhutishijian, (@j := @j + 1) as ord_num from yq_ml a,( select @j := 0) c 
         order by zhutishijian) as B 
        on A.ord_num=B.ord_num GROUP BY sub_seconds;
        """
    cur.execute(sql)
    result = cur.fetchall()

    #時間間隔 單位秒
    time1 = [n[0] for n in result]
    del time1[0] #第一個值為空
    print len(time1)
    print time1
    
    #出現頻次
    num1 = [n[1] for n in result]
    del num1[0] 
    print len(num1),type(num1)
    print num1.index(max(num1)) #獲取最大值的序列
    
    #繪圖
    plt.subplot(111)
    plt.plot(time1, num1, 'ko')
    plt.yscale('log')
    plt.ylabel('P', font1)
    plt.xlabel('timespan', font1)
    plt.xscale('log')
    plt.ylim(0.5,20)
    #plt.xlim(0.001,)
    plt.show()

輸出結果如下圖所示,

[Python輿情分析] 二.時間間隔分佈研究及冪律分佈圖繪製

這是2019年的基礎性文章,希望對大家有所幫助,不喜勿噴。同時,寒假已開始了自己奮鬥學習之路,希望一個月的時間能堅持把英語、專業課鞏固上來。考博之路很艱辛,且努力且珍惜。娜女神和我一起加油,也希望讀者給我投一票吧。我是59號,Eastmount,楊秀璋。
投票地址:https://bss.csdn.net/m/topic/blog_star2018/index

(By:Eastmount 2019-01-24 下午2點 http://blog.csdn.net/eastmount/ )

相關文章