史文崇
(河北科技師范學院 數(shù)學與信息科技學院,河北 秦皇島 066004)
“詞云”一詞由美國學者Rich Gordon提出,曾稱“標簽云”,也有人稱作“字云”[1].詞云圖是近年來興起的數(shù)據(jù)可視化工具之一,可以直觀地反映科技文獻中許多關鍵詞的出現(xiàn)頻次的對比情況.某詞條文字越大,說明其出現(xiàn)頻度越高.目前許多技術可以生成特殊輪廓的詞云圖,如地圖形、動物輪廓形、人物頭像形等.生成詞云圖的途徑或工具也有很多:電腦版的有WordArt、Wordle、圖悅網(wǎng)、易詞云網(wǎng)、優(yōu)詞云網(wǎng)、微詞云網(wǎng)等;手機版的有字云生成器、美字云、字云等軟件;一些大型軟件如Python、Matlab等,近年來也紛紛推出詞云庫或詞云函數(shù)[2-3].這些途徑生成的詞云一般密度較大[4],但多有詞條文字套疊現(xiàn)象.一些詞云圖工具只側(cè)重審美和藝術化[5],忽視了其原本的統(tǒng)計學意義;有的只有詞頻大小排序,卻沒有具體詞頻數(shù)據(jù)[6];有的甚至連詞頻大小順序也無須輸入,已演變成游戲、娛樂活動[7].必須指出,密度過大、文字套疊嚴重,致使詞條不易辨認或詞條重復、詞條被拆散的,已經(jīng)失去了統(tǒng)計學使用價值;而詞條文字顯示殘缺,詞條過少或過于松散,其藝術性和實用性都不復存在.
為了提高詞云圖的統(tǒng)計學使用價值,詞條首先要易于辨認.不是越密越好,不能為了提高密度刻意使文字套疊,犧牲可辨識性[8].保持適當?shù)拈g隔是必要的,只需防止過于稀疏即可.另外,在詞云圖中,雖通過詞條字體大小表示其頻度,但當兩個詞條詞頻差異較小時,僅靠文字大小已不易辨識,還應通過其位置、顏色等屬性輔助表征其不同頻度;同時必須杜絕文字殘缺、顯示不全的現(xiàn)象.要達到這些目的,一般以圓形輪廓詞云圖更易于實現(xiàn),也更便于使用,即中心點的詞頻最高,越是遠離中心點的詞條,其頻度越低.
本文研究在Matlab中生成詞云問題.Matlab是優(yōu)秀的大數(shù)據(jù)處理和機器學習軟件之一,也有優(yōu)秀的繪圖功能,尤其是其圖形(圖像)色彩處理、圖形中的文字處理功能非常強悍[9-10].Matlab自2017年版(僅可在64位機運行)起已有詞云函數(shù)wordcloud.首先嘗試用該函數(shù)得到詞云圖.現(xiàn)有關于某項研究的關鍵詞詞頻統(tǒng)計數(shù)據(jù),內(nèi)含76個關鍵詞——有二、三、四字中文詞匯,也有英文詞匯和縮略語.詞頻最高的為“字云”,最低的為“框架”.實驗表明,即使將wordcloud.m文件復制到低版本的Matlab軟件(如32位機可安裝的最高版本Matlab R2015b)的相應文件夾,也不能得到詞云圖,說明該函數(shù)的軟、硬件局限性;而在Matlab R2018環(huán)境中,用wordcloud函數(shù)繪出的相應詞云圖,如圖1.不難看出,該詞云圖色彩單調(diào),看不出藝術價值;有些詞條已經(jīng)小到難以識別;一些詞條文字大小相同,很難辨別哪個頻度更高——統(tǒng)計學價值也明顯不足.總之,該函數(shù)的實用性不能令人滿意.
圖1 用Matlab 2018的wordcloud函數(shù)生成的詞云圖
這里嘗試在Matlab R2015b環(huán)境(32位機)生成較為理想的詞云圖.Matlab R2015b可輕松實現(xiàn)詞頻數(shù)據(jù)的批量導入,自動排序,其text函數(shù)可按指定位置、大小、色彩、旋轉(zhuǎn)角度顯示指定文本內(nèi)容,為生成詞云圖提供了便利.設定中心點為頻度最高的詞,其他詞繞其順時針(或逆時針)旋轉(zhuǎn),在其外圍依次出現(xiàn),隨詞條頻度降低,字號逐漸減小,顏色發(fā)生改變.依此原理生成詞云圖,問題的核心是各個詞條顯示位置、文字大小、旋轉(zhuǎn)角度、顏色的確定.難點在于既要防止重疊,又不能使得分布過于松散稀疏;要使得詞云圖輪廓形成平滑的圓形;文字應呈現(xiàn)五彩繽紛的顏色,以增強其美感.
因為詞云圖采用圓形輪廓,可定義從內(nèi)到外每個圓周呈現(xiàn)的詞條數(shù),內(nèi)圈點位用完后,逐漸拓展到外圈,隨著圓周半徑增大,詞條數(shù)增加.如此循環(huán)若干周,直至處理完所有詞條.
最理想的做法是初始圓半徑和初始旋轉(zhuǎn)角度均按某種規(guī)律遞增.但由于每個詞條的字數(shù)往往并不一致,如在同一圓周呈現(xiàn)詞條較少,詞云會顯得過于稀疏;如詞條偏多又會造成個別詞的重疊;處理不當甚至是有的地方稀疏,有的地方重疊.鑒于這種情況,考慮到實用性,嘗試人為定義每周的圓半徑r0i和每周的詞條數(shù)n0i.這里,i=1-N.N為總周數(shù)(正整數(shù)),可由系統(tǒng)求出.
也就是說,除了圓心點外,共用N個圓周呈現(xiàn)所有詞條,從內(nèi)圓到外圓,每個圓周分布的詞條數(shù)構(gòu)成n0矩陣,每個圓周的半徑構(gòu)成矩陣r0.不難計算同一周內(nèi)每個詞條所在圓周的半徑數(shù)據(jù)構(gòu)成的矩陣為:Ri=r0i*ones(1,n0i),i=1-N.
由此可構(gòu)成各個圓周上各個點的半徑數(shù)據(jù)矩陣.假如有5個圓周,即:R=[R1,R2,R3,R4,R5].
為便于瀏覽詞云圖,假定每一周的第一個詞條從正上方(圓心角π/2處)開始逆時針分布,則同一圓周內(nèi)每個詞條所在位置的圓心角可構(gòu)成矩陣:
ti=(0:2*pi/n0i:2*(n0i-1)*pi/n0i)+pi/2
由此可構(gòu)成各個圓周上各個點的圓心角數(shù)據(jù)矩陣,如為5個圓周,即:T=[t1,t2,t3,t4,t5].同時亦可確定各個點的坐標數(shù)據(jù)矩陣為:X=R.*cos(T),Y=R.*sin(T).(“.*”是Matlab運算符,與“*”作用不同.)這決定了各詞條的顯示位置,而它們與初始的r0和n0矩陣密切相關.用plot函數(shù),畫出各個分布點并按順序連線.圖2顯示出各個詞條出現(xiàn)的順序呈螺旋狀;圖3顯示出最終呈現(xiàn)的輪廓,很明顯最外層已接近圓形.
圖2 各詞條出現(xiàn)順序
圖3 各個詞條的位置分布與總輪廓
可見,只要初始r0和n0矩陣數(shù)據(jù)得當,生成圓形輪廓的詞云圖不成問題.欲用text函數(shù)顯示各個詞條,各詞條初始坐標可由X、Y確定.
text函數(shù)在輸出文本時,默認設置是水平方向左對齊,垂直方向基線對齊,不旋轉(zhuǎn).極不利于維持詞云圖的圓形輪廓.需設置水平方向居中對齊,垂直方向居中對齊,并按所在位置旋轉(zhuǎn)角度.轉(zhuǎn)換為角度矩陣,即rot=T*180/pi-90.這里,由于系統(tǒng)默認的0度(弧度)始于水平向右方向,減去90度,可使每一周的第一個詞出現(xiàn)在正上方.text函數(shù)的相應屬性值設置見表1.
表1 text函數(shù)的關鍵屬性設置
在詞云圖中,總是用詞條文字的大小直觀地反應其頻度,字的大小為其頻度的增函數(shù).繪制詞云圖之前,各個詞條的頻度必已獲知(可導入相應數(shù)據(jù)文件).從理論上說,文字顯示大小(磅數(shù))可以和頻度數(shù)字相等,或是其若干倍.但在實際的詞頻矩陣中,出現(xiàn)頻度最高的詞條的詞頻可能達到數(shù)百次,而最低詞頻可能只有一兩次.二者相差懸殊.文字顯示過大極易造成彼此重疊,文字顯示過小會造成不易辨認,都不利于詞云的視覺效果.為此,只要文字大小是其頻度的增函數(shù),可做相應的函數(shù)變換.假如詞頻矩陣為D,其第一列為各詞條文本,第二列為各詞條的頻度,則有:
F(i)=fix(D{i,2}/k1)+k2
其中,F(xiàn)(i)是每個詞的顯示的字體的磅數(shù),k1、k2均為正整數(shù),使用fix函數(shù)旨在取整,而之所以加k2是為了防止取整后為0.k2實質(zhì)上就是各詞條最小的顯示磅數(shù)(如5磅),以便識別.
當兩個詞的詞頻相同時,它們顯示的大小必然相同.鑒于上文關于文字大小的處理,當不同詞條的詞頻差異不大時,文字可能以相同大小顯示.為了便于區(qū)分,應使之顯示為不同色彩.這在Matlab處理起來極為方便,Matlab提供了多種色圖(colormap)序列.只要按照需要的效果和色彩數(shù)目選擇即可.這里可采用lines序列,因為中心點外圍有m(總詞條數(shù))個詞,定義色彩矩陣co,可令co= lines(m).在輸出各個詞條時,按其順序獲取色彩三元組co(i,:)即可(表1).
由此,可創(chuàng)建生成詞云圖的函數(shù)如下:
functionwcchart(D,n0,r0) %三參數(shù)為詞云矩陣,各圈點數(shù)、半徑矩陣
R=[];T=[]; %半徑、角度矩陣初始為空矩陣
J=sum(n0);%計算總的詞條數(shù)
%以下定義各詞條點位及轉(zhuǎn)角(弧度)矩陣
fori=1:length(n0) %保證圈數(shù)
R0=r0(i)*ones(1,n0(i)); T0=(0:2*pi/n0(i):2*(n0(i)-1)*pi/n0(i))+pi/2;
R=[R,R0];T=[T,T0]; %重組R、T矩陣
end
rot=T*180/pi-90;%中心角矩陣轉(zhuǎn)化為角度
X=R.*cos(T);Y=R.*sin(T);
figure('color','w'); hold on;%背景白色,持續(xù)畫圖
D1=sortrows(D,-2); %對原始詞云矩陣按照詞頻降序排列
F00=D1{1,2};%獲得最大的詞頻值
F0=fix(D1{1,2}/5)+8;%定義字號
%以下在中心點輸出詞頻最高的詞
text(0,0,D1{1,1},'fontname','SimSun','fontsize',F0, 'color', 'b', 'HorizontalAlignment',
'center',
'verticalAlignment','middle', 'FontWeight','Bold')
co= lines(J);%定義色圖序列
%以下依次輸出各個詞條
fori=1:J
F(i)=fix(D1{i+1,2}/5)+8; txt=D1{i+1,1};
text(X(i),Y(i),txt,'color',[co(i,:)], 'fontname','SimSun','fontsize',F(i), 'HorizontalAlignment','center','verticalAlignment','middle', 'rotation',rot(i),'FontWeight','Bold')
end
axissquare;box on; %等比例尺、圖幅為正方形,顯示邊框
set(gca,'xtick',[],'ytick',[],'looseinset',[0 0 0 0]) %不顯示坐標軸刻度,邊界尺寸為0.
下面基于與圖1相同的基礎數(shù)據(jù)(已存入data.mat文件),用上述自制的詞云圖函數(shù)wcchart畫詞云圖.因詞條不足100個,考慮在五個圓周呈現(xiàn)所有詞條,設置各周的詞條數(shù)和各圈的半徑,如N=[5,10,15,20,25];r=[2.0,3.4,4.4,5.3,6.1]; 再依次執(zhí)行以下命令,可得到詞云圖(圖4).
loaddata.matD;%裝入詞云數(shù)據(jù)文件,數(shù)據(jù)轉(zhuǎn)移給矩陣D
wcchart(D,N,r);%調(diào)用自定義的詞云函數(shù)
axis([-6.6,6.6,-6.6,6.6]);%%設置坐標軸范圍
圖4 本文生成的詞云圖
該詞云圖函數(shù)代碼簡短(不及Matlab R2018中提供的wordcloud函數(shù)的1/3),其調(diào)用不受詞條數(shù)目限制,調(diào)用時只需調(diào)整N、R矩陣數(shù)據(jù)即可,使用方便.由于沒有刻意追求文字套疊效果,與目前一些詞云圖相比,該詞云密度較低,局部可能較為稀疏,這主要是由于各個詞條字數(shù)不等,為防止彼此重疊而留有余地.由于已知詞條是按詞頻大小從里到外逆時針出現(xiàn),可以輕松看出“信息流”的頻度高于“機器學習”“可視化”的頻度高于“大數(shù)據(jù)”等.與圖1相比,既美觀,又實用.
實踐表明,該詞云圖函數(shù)在32位、64位機均可運行,普適性好;可實現(xiàn)詞頻數(shù)據(jù)的批量導入和自動排序;可實現(xiàn)各詞條的有序、定位輸出,既具有統(tǒng)計學價值,又兼顧了美觀,在許多方面已超越了高版本Matlab自帶的wordcloud函數(shù),是一種較為實用的詞云圖定制方案.