1 前言 此前,我們學習了一篇和Gephi相關的研究范文《基于引文網絡和語義分析的技術演化路徑識別及拓展研究》,該范例作者使用Gephi軟件作為網絡分析的工具,同時運用Girvan-Newman算法對引文網絡進行社群劃分和主路徑提取。接下來我們將用多個notebook和文章演示社群劃分的方法。本篇notebook先演示用Python實現Girvan-Newman算法。演示了兩種方法:1,手工寫Girvan-Newman算法;2,使用networkx的函數。手工寫Girvan-Newman算法僅作演示用,不建議在實際項目項目中使用。下面手工寫的Girvan-Newman算法也沒有經過大量測試,所以,要采用第二種方法。 我們今天就Girvan-Newman算法做一次編程練習和實驗,期望能夠形成一個初步認識:針對什么樣的數據可以做社>**(不當用詞)現。 另外,Gephi也有社群分析功能,我們將在接下來的文章中介紹Gephi的用法,這里先做個簡單介紹。 Gephi是一款很強的網絡可視化分析軟件,下面是Gephi官網提到的幾個功能: - 社交網絡分析:輕松創建社交數據連接器,以映射社區組織和小世界網絡。
- 探索性數據分析:通過網絡操作進行實時直覺分析。
- 鏈接分析:揭示對象之間關聯的底層結構。
- 生物網絡分析:表示生物數據的模式。
- 海報制作:通過高質量的可打印地圖進行科學的工作推廣。

有關Gephi的學習,可以參考我們發布的系列文章: 另外,我們也發布了多篇Jupyter Notebook,使用Python進行各種算法的演練,比如在這篇《對共詞關系求協方差矩陣后是否有更好的社會網絡分析結果?》中,我們演練了怎樣用協方差矩陣表示共詞矩陣,同時講解了使用協方差矩陣的意義,并且設想了更進一步編程探索的方向。 2 Girvan-Newman算法是什么? Girvan-Newman算法是一種社交網絡的聚類方法,簡稱GN算法。 以下對社區發現和GN算法的解釋和圖片,參考了這2篇知乎文章:《Girvan和Newman社團發現算法》,《社區發現算法-GN》。 2.1 網絡中的社區/社群是什么? 所謂社區/社群就是:其內部頂點的連接稠密,而與其他社區內的頂點連接稀疏。 這就意味著社區與社區之間聯系的通道比較少,一個社區到另一個社區至少要通過這些通道中的一條。 下面,我們將混用“社區”和“社群”,當成一回事。 2.2 什么是社區發現 一個社區由一組連接緊密的結點組成,同時這些結點與社區外部的結點連接稀疏,如下圖所示。那么,社區發現就是在復雜網絡中發現這些連接緊密的社區結構。其實,社區發現可以理解為網絡中的結點聚類。下圖引用自《社區發現算法-GN》 
2.3 什么是Girvan-Newman算法(GN算法)? GN算法是社區發現中的第一個算法,也就是它開啟了這個研究領域。它的基本思想是刪除掉那些社區之間的連接,那么剩下的每個連通部分就是一個社區。那么問題來了,就是哪些是社區之間的邊呢?作者巧妙地借助最短路徑解決了這個問題,他們定義一條邊的介數(betweeness)為網絡中所有結點之間的最短路徑中通過這條邊的數量,而介數高的邊要比介數低的邊更可能是社區之間的邊。其實,這也比較好理解,因為兩個社區中的結點之間的最短路徑都要經過那些社區之間的邊,所以它們的介數會很高。 GN算法每次都刪除網絡中介數最大的邊,直至網絡中的所有邊都被刪除。這樣GN的過程對應著一顆自頂向下構建的層次樹。在層次樹中選擇一個合適的層次分割即可。下圖引用自《社區發現算法-GN》 
GN算法的基本流程如下: - 計算網絡中各條邊的邊介數;
- 找出邊介數最大的邊,并將它移除(如果最大邊介數的邊不唯一,那么既可以隨機挑選一條邊斷開也可以將這些邊同時斷開);
- 重新計算網絡中剩余各條邊的邊介數;
- 重復第2)、3)步,直到網絡中所有的邊都被移除。
3 使用方法 操作順序是: - 在GooSeeker分詞和文本分析軟件上創建文本分析任務并導入包含待分析內容的excel,分析完成后導出共詞矩陣表
- 將導出的excel表放在本notebook的data/raw文件夾中
- 從頭到尾執行本notebook的單元
注意:GooSeeker發布的每個notebook項目目錄都預先規劃好了,具體參看Jupyter Notebook項目目錄規劃參考。如果要新做一個分析項目,把整個模板目錄拷貝一份給新項目,然后編寫notebook目錄下的ipynb文件。 4 實驗數據 本Notebook針對不同的實驗數據使用不同的計算方法做了多個實驗,通過對比選擇最好的方法: 實驗一:使用了networkx自帶的空手道俱樂部數據,分別實驗自定義Girvan-Newman算法和networkx提供的算法 實驗二:使用了從知乎采集得到的有關話題“二舅”的社交媒體數據,經GooSeeker分詞軟件選詞處理后導出的共詞矩陣表(一共100個詞頻數高并且文檔頻數也高的詞)。 實驗三:針對“二舅”數據,不使用缺省的中介中心度,而是采用其他指標進行社區發現 
5 修改歷史 2022-10-15:第一版發布 6 版權說明 本notebook是GooSeeker大數據分析團隊開發的,所分析的源數據是GooSeeker分詞和文本分析軟件生成的或者基于測試數據,本notebook中的代碼可自由共享使用,包括轉發、復制、修改、用于其他項目中。 7 準備運行環境 7.1 引入需要用到的庫 # -*- coding: utf-8 -*- ? import networkx as nx import matplotlib.pyplot as plt import os import numpy as np import pandas as pd import pylab ? %xmode Verbose import warnings ? # 軟件包之間配套時可能會使用過時的接口,把這類告警忽略掉可以讓輸出信息簡練一些 warnings.filterwarnings("ignore", category=DeprecationWarning) ? # 把RuntimeWarning忽略掉,不然畫圖的時候有太多告警了 warnings.filterwarnings("ignore", category=RuntimeWarning) %matplotlib inline
7.2 設置中文字體 因為含有中文,pyplot畫圖有可能會顯示下面的錯誤信息: C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\backends\backend_agg.py:238: RuntimeWarning: Glyph 32993 missing from current font. font.set_text(s, 0.0, flags=flags) 這是因為找不到中文字體,所以在圖上的中文顯示不出來,為了解決pyplot顯示找不到字體的問題,參看glyph-23130-missing-from-current-font,先做如下設置。 #plt.rcParams['font.sans-serif']=['SimHei'] # 上面一行在macOS上沒有效果,所以,使用下面的字體 plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] plt.rcParams['axes.unicode_minus'] = False # 下面的配置用于解決windows下畫圖不顯示中文的問題 #plt.rcParams['font.sans-serif'] = [u'SimHei'] #plt.rcParams['axes.unicode_minus'] = False
8 實驗一:基于networkx自帶數據 networkx自帶的空手道俱樂部測試數據做Girvan-Newman算法實驗,從下面的網絡圖可以看到,這個數據集有很好的分群特征。 8.1 基于測試數據生成圖并顯示 # load the graph G = nx.karate_club_graph() nx.draw(G, with_labels = True)

8.2 輸出圖的節點數和邊條數 len(G.nodes), len(G.edges)
輸出結果: (34, 78) 8.3 算法1: 使用自定義Girvan Newman算法 僅作為演示和體驗算法原理只用,在實際項目中盡量采用networkx和numpy等程序庫現有的算法,以獲得更好的性能。 自定義算法有下面特點: 8.3.1 定義函數:執行后返回目前需要刪除的邊 按GN算法的定義,選擇介數中心性最大的邊作為需要刪除的邊 def edge_to_remove(graph): G_dict = nx.edge_betweenness_centrality(graph) edge = () ? # extract the edge with highest edge betweenness centrality score for key, value in sorted(G_dict.items(), key=lambda item: item[1], reverse = True): edge = key break ? return edge
8.3.2 定義函數:實現GN算法 - 計算網絡中各條邊的邊介數;
- 找出邊介數最大的邊,并將它移除(如果最大邊介數的邊不唯一,那么既可以隨機挑選一條邊斷開也可以將這些邊同時斷開);
- 重新計算網絡中剩余各條邊的邊介數;
- 重復第2)、3)步,直到網絡中所有的邊都被移除。
def girvan_newman(graph): # find number of connected components sg = nx.connected_components(graph) sg_count = nx.number_connected_components(graph) ? while(sg_count == 1): to_remove = edge_to_remove(graph) graph.remove_edge(to_remove[0], to_remove[1]) sg = nx.connected_components(graph) sg_count = nx.number_connected_components(graph) ? return sg
8.3.3 針對已經生成的測試圖,尋找社區并輸出節點 # find communities in the graph c = girvan_newman(G.copy()) ? # find the nodes forming the communities node_groups = [] ? for i in c: node_groups.append(list(i))
8.3.4 輸出圖,不同社區的節點以不同顏色顯示 # plot the communities color_map = [] for node in G: if node in node_groups[0]: color_map.append('blue') else: color_map.append('green') ? nx.draw(G, node_color=color_map, with_labels=True, font_color='white') plt.show()

8.4 算法2: 使用networkx提供的算法 networkx的community算法有很多,不只是Girvan Newman算法,所以盡量采用networkx提供的算法,熟練使用networkx以期獲得最大能力和性能。 networkx提供的girvan_newman算法生成了分層的社區,根據需要選擇深入觀察到第幾層??梢园l現,如果觀察到第一層,那么結果跟自定義算法是一樣的 from networkx.algorithms import community
8.4.1 拆分社區 communities_generator = community.girvan_newman(G.copy()) top_level_communities = next(communities_generator) top_level_communities
輸出結果: ({0, 1, 3, 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 19, 21}, {2, 8, 9, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33}) 如果拆分到第二層,看到的結果是這樣的 next_level_communities = next(communities_generator) next_level_communities
輸出結果: ({0, 1, 3, 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 19, 21}, {2, 8, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33}, {9}) 還可以繼續拆分成第三層,是這樣的 third_level_communities = next(communities_generator) third_level_communities
輸出結果: ({0, 1, 3, 7, 11, 12, 13, 17, 19, 21}, {2, 8, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33}, {4, 5, 6, 10, 16}, {9}) 8.4.2 轉換成數組 因為數組比較好處理 top_level_array = sorted(map(sorted, top_level_communities)) top_level_array
輸出結果: [[0, 1, 3, 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 19, 21], [2, 8, 9, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]] 8.4.3 定義更通用的標注社區的畫圖程序 # 用這個函數,可以最多畫4種顏色不同的社區 def plot_communities(G, group_array): color_map = [] for node in G: found = False for idx, group in enumerate(group_array): if node in group: found = True if idx == 0: color_map.append('blue') elif idx == 1: color_map.append('green') elif idx == 2: color_map.append('orange') elif idx == 3: color_map.append('red') else: color_map.append('purple') if found == False: color_map.append('black') ? nx.draw(G, node_color=color_map, with_labels=True, font_color='white') plt.show()
一層層畫圖 plot_communities(G, top_level_array)

plot_communities(G, sorted(map(sorted, next_level_communities)))

plot_communities(G, sorted(map(sorted, third_level_communities)))

9 實驗二:發現GooSeeker分詞軟件導出的共詞矩陣表中的社群 使用GooSeeker分詞軟件導出的共詞矩陣表做Girvan-Newman算法實驗,下面不再使用自定義函數,而是使用networkx自帶的函數。 9.1 常量和配置 在我們發布的一系列Jupyter Notebook中,凡是處理GooSeeker分詞軟件導出的結果文件的,都給各種導出文件起了固定的名字。為了方便大家使用,只要把導出文件放在data/raw文件夾,notebook就會找到導出文件,賦值給對應的文件名變量。下面羅列了可能用到的文件名變量: file_all_word:詞頻表 file_chosen_word: 選詞結果表 file_seg_effect: 分詞效果表 file_word_occurrence_matrix: 選詞矩陣表(是否出現) file_word_frequency_matrix: 文檔詞頻對應矩陣 file_word_document_match: 選詞匹配表 file_co_word_matrix: 共詞矩陣表
pd.set_option('display.width', 1000) # 設置字符顯示寬度 pd.set_option('display.max_rows', None) # 設置顯示最大 # np.set_printoptions(threshold=np.inf) # threshold 指定超過多少使用省略號,np.inf代表無限大 ? # 存原始數據的目錄 raw_data_dir = os.path.join(os.getcwd(), '../../data/raw') # 存處理后的數據的目錄 processed_data_dir = os.path.join(os.getcwd(), '../../data/processed') filename_temp = pd.Series(['詞頻','分詞效果','選詞矩陣','選詞匹配','選詞結果','共詞矩陣']) file_all_word = '' file_seg_effect = '' file_word_occurrence_matrix = '' file_word_frequency_matrix = '' file_word_document_match = '' file_chosen_word = '' file_co_word_matrix = ''
9.2 檢測data\raw目錄下是否有GooSeeker分詞結果表 在本notebook只使用共詞矩陣表,下面的代碼將檢查data/raw中有沒有這個表,如果沒有會報錯,后面的程序就沒法執行了。 # 0:'詞頻', 1:'分詞效果', 2:'選詞矩陣', 3:'選詞匹配', 4:'選詞結果', 5:'共詞矩陣' print(raw_data_dir + '\r\n') ? for item_filename in os.listdir(raw_data_dir): if filename_temp[5] in item_filename: file_co_word_matrix = item_filename continue ? if file_co_word_matrix: print("共詞矩陣表:", "data/raw/", file_co_word_matrix) else: print("共詞矩陣表:不存在")
輸出結果如下: C:\Users\work\notebook\社區發現算法Girvan-Newman(GN)學習-對比\notebook\eda\../../data/raw 共詞矩陣表: data/raw/ 共詞矩陣-知乎-二舅.xlsx
9.3 讀取共詞矩陣表并存入矩陣 讀入過程不展開講解,具體參看《共詞分析中的共詞關系是怎么得到的?》。這篇文章也對比了共詞矩陣和選詞矩陣的不同使用場合。為了更好的分辨社區,本notebook也會展示用選詞矩陣得到的分析效果。 9.3.1 用pandas dataframe讀入共詞矩陣 df_co_word_matrix = pd.read_excel(os.path.join(raw_data_dir, file_co_word_matrix)) df_co_word_matrix.head(2)

9.3.2 提取字段名 將用于給graph的node命名 coword_names = df_co_word_matrix.columns.values[1:] print("There are ", len(coword_names), " words") coword_names
輸出結果如下: There are 100 words array(['世界', '時候', '作品', '東西', '故事', '現實', '個人', '時間', '人生', '時代', '人民', '事情', '社會', '苦難', '感覺', '人們', '中國', '問題', '精神', '年輕人', '底層', '回村', '內耗', '作者', '一生', '孩子', '命運', '態度', '殘疾', '經歷', '普通人', '農村', '價值', '原因', '媒體', '城市', '房子', '力量', '母親', '觀眾', '地方', '本質', '評論', '國家', '意義', '角度', '辦法', '老人', '內心', '文案', '流量', '方式', '雞湯', '能量', '醫生', '能力', '年代', '內容', '電影', '環境', '情況', '老師', '農民', '關系', '視角', '大眾', '情緒', '條件', '壓力', '文化', '分鐘', '朋友', '窮人', '人物', '村里', '資本', '想法', '觀點', '大學', '心理', '思想', '父母', '群眾', '文藝創作', '個體', '機會', '悲劇', '歷史', '藝術', '勵志', '殘疾人', '文藝', '平臺', '生命', '身體', '編劇', '物質', '熱度', '醫療', '官方'], dtype=object)
9.3.3 生成矩陣數據結構 # 使用astype函數對數據類型進行轉換,否則,下面畫圖的時候可能會報錯 array_co_word_matrix = df_co_word_matrix.values[:, 1:].astype(float) array_co_word_matrix

word_num = len(array_co_word_matrix) word_num
輸出結果如下: 100 9.3.4 對角線賦0 為了避免對角線上畫出來自環邊。 np.fill_diagonal(array_co_word_matrix, 0) array_co_word_matrix

9.4 生成圖并進行探索 9.4.1 從NumPy數組生成networkx圖 參看networkx文檔,有專門的函數從其他數據結構直接生成graph #graph_co_word_df = nx.from_pandas_adjacency(df_co_word_matrix) graph_co_word_matrix = nx.from_numpy_array(array_co_word_matrix) print(nx.info(graph_co_word_matrix)) #graph_co_word_matrix.edges(data=True)
輸出結果如下: Name: Type: Graph Number of nodes: 100 Number of edges: 4746 Average degree: 94.9200 9.4.2 給node加上label 如果不加label,畫出來的圖上的每個節點只是一個編號,加上label可以看到節點對應的詞。 根據get_node_attributes,查看現在的note labels coword_labels = nx.get_node_attributes(graph_co_word_matrix,'labels') coword_labels
輸出結果如下: {} 根據How-do-I-label-a-node-using-networkx-in-python,重新命名labels for idx, node in enumerate(graph_co_word_matrix.nodes()): print("idx=", idx, "; node=", node) coword_labels[node] = coword_names[idx] graph_co_word_matrix = nx.relabel_nodes(graph_co_word_matrix, coword_labels) sorted(graph_co_word_matrix)

for idx, node in enumerate(graph_co_word_matrix.nodes()): print("idx=", idx, "; node=", node)

9.4.3 畫圖 figure函數的使用方法參看pyplot官網 。其他參考資料: # 方案1:用pylab畫圖 #pos=nx.shell_layout(graph_co_word_matrix) #nx.draw(graph_co_word_matrix,pos,with_labels=True, node_color='white', edge_color='grey', node_size=1200, alpha=1 ) #pylab.title('co-word matrix',fontsize=25) #pylab.show() ? # 方案2 #pos = nx.circular_layout(maximum_tree) pos = nx.spring_layout(graph_co_word_matrix) plt.figure(1,figsize=(10,10)) nx.draw(graph_co_word_matrix, pos, node_size=10, with_labels=True, font_size=10, font_color="red") #nx.draw(graph_co_word_matrix, pos, with_labels=True) #nx.draw_networkx_labels(graph_co_word_matrix, pos, labels) plt.show()

graph_co_word_dis_15 = graph_co_word_matrix.copy() edges = graph_co_word_dis_15.edges(data=True) for u, v, d in edges: d["weight"] //= 15 ? pos = nx.spring_layout(graph_co_word_dis_15) plt.figure(1,figsize=(10,10)) nx.draw(graph_co_word_dis_15, pos, node_size=10, with_labels=True, font_size=10, font_color="red") plt.show()

9.5 社區發現 針對已經生成的圖,尋找社區并輸出節點。你會發現效果很不好,在每一層只能分出一個詞。因為這個數據集從知乎上用網絡爬蟲采集下來的,每篇內容都很長,那么,詞與詞之間的關系十分稠密,從上圖就能看出來,幾乎都全互聯的,那么介數這個指標幾乎沒有太大區分的作用。 9.5.1 分拆社區 communities_generator = community.girvan_newman(graph_co_word_matrix.copy()) top_level_co_word = sorted(map(sorted, next(communities_generator))) top_level_co_word

第一層的效果很不好,只有一個詞“官方”分出來了。因為“二舅”這批數據是用網絡爬蟲從知乎回答爬下來的,每個回答比較長,所有的詞之間的連接很稠密,不同詞之間的中介中心性基本一致。 試試第二層 second_level_co_word = sorted(map(sorted, next(communities_generator))) second_level_co_word

9.5.2 畫社區圖 雖然分到第二層,效果依然不好。前面已經分析了原因,繼續分拆下去也不會有理想的結果,所以,我們要嘗試其他計算指標。暫時先畫一下第二層的社區圖,幾乎看不到有意義的信息。 plot_communities(graph_co_word_matrix, second_level_co_word)

10 實驗三:為共詞矩陣定義其他社區發現指標 networkx提供的girvan_newman函數,允許提供一個函數參數,這個函數用來計算其他指標。參看networkx community案例 我們自然會想到圖上面的邊的權重。在共詞矩陣中,權重表示共現發生的次數,用這個權重疊加到中介中心性上,可以將原先中介中心性相同的區分開來。 10.1 利用權重屬性 10.1.1 定義most_valuable_edge函數 我們定義了兩個函數。如果權重越大越重要,那么就應該使用第二個,把權重小的先剔除。 from operator import itemgetter def heaviest(G): u, v, w = max(G.edges(data="weight"), key=itemgetter(2)) return (u, v)
from operator import itemgetter def lightest(G): u, v, w = min(G.edges(data="weight"), key=itemgetter(2)) return (u, v)
10.1.2 探索edge屬性 edges = graph_co_word_matrix.edges(data=True) for edge in edges: print(edge) #for u, v in edges: # print("u = ", u, "\nv = ", v)

graph_co_word_matrix.edges(data="weight")

print("u = ", u, "; v = ", v, ", w = ", w)
輸出結果如下: u = 精神 ; v = 內耗 , w = 147.0 10.1.3 使用權重分拆社區 #com_gen = community.girvan_newman(graph_co_word_matrix.copy(), most_valuable_edge=heaviest) com_gen = community.girvan_newman(graph_co_word_matrix.copy(), most_valuable_edge=lightest) top_level_co_word_weight = sorted(map(sorted, next(com_gen))) top_level_co_word_weight

second_level_co_word_weight = sorted(map(sorted, next(com_gen))) second_level_co_word_weight

third_level_co_word_weight = sorted(map(sorted, next(com_gen))) third_level_co_word_weight

10.1.4 畫社區圖 可以看到,經過三輪分拆,每次拆出一個詞,分拆速度太慢了,畫圖效果如下,很不好。需要想辦法提高分拆速度。 plot_communities(graph_co_word_matrix, third_level_co_word_weight)

10.2 壓縮權重的層級 前面我們在畫原始數據圖的時候,嘗試了壓縮權重的層級。原先最大權重是147,也就是說,可能有147級。如果壓縮成7級,分拆速度是否會快很多? 經過實驗發現,社區發現算法其實也在逐步裁剪邊,但是,這個算法不是為裁剪邊設計的,用它來裁剪邊的速度太低了,一次裁掉一個。 graph_co_word_dis_5 = graph_co_word_matrix.copy() edges = graph_co_word_dis_5.edges(data=True) for u, v, d in edges: d["weight"] //= 20 pos = nx.spring_layout(graph_co_word_dis_5) plt.figure(1,figsize=(10,10)) nx.draw(graph_co_word_dis_5, pos, node_size=10, with_labels=True, font_size=10, font_color="red") plt.show()

edges 
com_gen = community.girvan_newman(graph_co_word_dis_5.copy(), most_valuable_edge=lightest) top_level_co_word_dis_5 = sorted(map(sorted, next(com_gen))) top_level_co_word_dis_5

second_level_co_word_dis_5 = sorted(map(sorted, next(com_gen))) second_level_co_word_dis_5

third_level_co_word_dis_5 = sorted(map(sorted, next(com_gen))) third_level_co_word_dis_5

forth_level_co_word_dis_5 = sorted(map(sorted, next(com_gen))) forth_level_co_word_dis_5

fifth_level_co_word_dis_5 = sorted(map(sorted, next(com_gen))) fifth_level_co_word_dis_5

sixth_level_co_word_dis_5 = sorted(map(sorted, next(com_gen))) sixth_level_co_word_dis_5

10.3 權重加中介中心性 10.3.1 定義most_valuable_edge函數 from networkx import edge_betweenness_centrality as betweenness def most_central_edge(G): centrality = betweenness(G, weight="weight") return max(centrality, key=centrality.get)
10.3.2 分拆社區 下面的計算會花很長時間。因為這個數據集有100個節點,但是,計算結果依然沒有改善。因為由girvan_newman算法決定了不會有理想的結果,只會一層層把當前層數值最大的一個節點篩選出來。 com_gen = community.girvan_newman(graph_co_word_matrix, most_valuable_edge=most_central_edge) top_level_co_word_bt_weight = sorted(map(sorted, next(com_gen))) top_level_co_word_bt_weight

并沒有看到改善,再往下看一層試試: second_level_co_word_bt_weight = sorted(map(sorted, next(com_gen))) second_level_co_word_bt_weight

11 總結 經過上面的實驗過程,我們僅僅練習了networkx的社區發現的編程方法,但是,并沒有從GooSeeker分詞軟件導出的共詞矩陣中有所發現。 我們期望能否發現多個詞從語義方面形成的聚集,但是,上述實驗沒有達到目的。每一層社區分解只能分出一個詞。因為這個數據集從知乎上用網絡爬蟲采集下來的,每篇內容都很長,那么,詞與詞之間的關系十分稠密,從上圖就能看出來,幾乎都全互聯的,那么介數這個指標幾乎沒有太大意義。 我們嘗試了調整權重的值,最多取5個不同的值,但是,用發現社區算法效果依然不好。至此,我們自然會想到,可以先對圖進行裁剪,剩下骨干詞以后再進行社區發現。 我們此前發布的Jupyter Notebook探索了文本處理中的選詞矩陣的作用,以及在其上進行協方差處理的意義,然后再對協方差矩陣形成的圖進行裁剪,可以觀察到很好的詞聚集現象。參看《對共詞關系求協方差矩陣后是否有更好的社會網絡分析結果?》。那么,接下來一個notebook將專門進行探索。 12 下載源代碼 下載Jupyter Notebook源代碼,請進入《對共詞關系求協方差矩陣后再用Girvan-Newman算法做社區發現》 |