漢語中的詞頻及筆畫數分佈規律探析
一、引言
大約八十年前,哈佛大學的語言學家喬治·金斯利·齊普夫(George Kingsley Zipf)對英語中的詞頻分佈進行了研究,發現了一條經驗規律,他發現:如果把一篇較長文章中每個詞出現的頻次統計起來,按照高頻詞在前、低頻詞在後的遞減順序排列,並用自然數個這些詞編上的等級序號,即頻次最高的詞等級為1,頻次次之的等級為2等等,若用表示頻次,表示序號,則有(為常數),也就是說詞語的頻次和其頻次排名呈反比例關係。假如以單詞的頻次排名為橫軸,以單詞的頻次為縱軸繪製散點圖,會發現圖形大致呈現雙曲線形。為了數學上處理的方便,我們可以對詞頻及詞頻排名取對數(自然對數或以十為底的對數均可),考慮到:,則有: 所以與應呈線性關係,在圖形上應該是一條直線,如下:
受到齊普夫的啟發,其它學者也紛紛驗證該定律對其它語言的適用性,他們發現齊普夫定律在很多語言中也是成立的。如上圖,頻次排名對數與頻次的對數成線性關係。一個很自然的問題是,該定律在漢語中的適用性如何?
漢字作為象形文字,顯著不同於以英語為代表的拼音文字,其語言的基本單位為單字,然後再由單字組成兩字詞、三字詞等以表達更加複雜的意義。拼音文字的基本單位為單詞,意義的擴充套件通過創造新詞彙或者拼接已有單片語成新詞彙來實現。因此,英語可以以單詞為單位來統計詞頻,而漢語則必須以詞語為基本單位來統計,這既包括單字,也包括多字詞,只有這樣才能準確描述漢語詞頻的分佈規律
利用教育部語言文字應用研究所計算語言學研究室提供的線上語料庫字詞頻資料,我們可以檢驗齊普夫定律在漢語中的適用性,加深我們對漢語詞頻分佈規律的認識。由於以上資料並不包括漢字的筆畫數資料,我們可以利用笪駿提供的現代漢語單字頻率列表,進一步研究漢字筆畫數的分佈規律。
我們使用jupyter notebook對以上資料進行分析,相關notebook及資料檔案已經上傳到這個倉庫,大家可以下載資料進行分析驗證。資料檔案版權歸原作者所有,如有侵權請通知我刪除。
二、漢語詞頻分佈規律
首先,我們匯入一些資料分析必要的庫,並做一些初始化設定:
import numpy as np
import statsmodels. api as sm
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")
import seaborn as sns
sns.set(style="white",color_codes=True)
import pandas as pd
%matplotlib inline
plt.rcParams['figure.figsize'] = (15,9.27)
然後匯入word_freq.xlsx
這個資料檔案,這個資料檔案收錄了現代漢語語料庫中出現次數大於50次的詞的出現次數、頻率與累計頻率資料。該語料庫的規模為2000萬字,該表共收集了14629個詞,既包括單字,也包括多字詞。讓我們先看下資料的基本情況:
df = pd.read_excel('word_freq.xlsx')
df.head(10)
rank | word | freq | freq_percent | cum_freq_percent | |
---|---|---|---|---|---|
0 | 1 | 的 | 744863 | 7.7946 | 7.7946 |
1 | 2 | 了 | 130191 | 1.3624 | 9.1570 |
2 | 3 | 在 | 118823 | 1.2434 | 10.4004 |
3 | 4 | 是 | 118527 | 1.2403 | 11.6407 |
4 | 5 | 和 | 83958 | 0.8786 | 12.5193 |
5 | 6 | 一 | 81119 | 0.8489 | 13.3682 |
6 | 7 | 這 | 65146 | 0.6817 | 14.0499 |
7 | 8 | 有 | 53556 | 0.5604 | 14.6103 |
8 | 9 | 他 | 52912 | 0.5537 | 15.1640 |
9 | 10 | 我 | 52728 | 0.5518 | 15.7158 |
資料的前十行顯示如上表:其中第一列為漢字中詞語按出現頻次從高向低排名,如“的”字在語料庫中出現的次數最多,則排在第一名;第二列為對應的漢字及詞語;第三列為該漢字或詞語在語料庫中出現的次數,如“的”在語料庫中共出現了744863次;第四列表示該漢字或詞語在語料庫中出現的頻率的百分比,如“的”出現的頻率為7.7946%;第五列為累計頻率,為該漢字(詞語)及排名靠前的漢字(詞語)累計出現的頻率,如到排名第十的漢字“我”,前十名漢字出現的累計頻率為15.7158%。
為了之後分析的方便,我們需要另外計算三列資料,分別為詞語頻次排名的以10為底的對數、頻次以10為底的對數及詞語中漢字數(單字詞還是多字詞),則:
df['log_rank'] = np.log10(df['rank'])
df['log_freq'] = np.log10(df['freq'])
df['word_count'] = df['word'].apply(len)
df.head(10)
rank | word | freq | freq_percent | cum_freq_percent | log_rank | log_freq | word_count | |
---|---|---|---|---|---|---|---|---|
0 | 1 | 的 | 744863 | 7.7946 | 7.7946 | 0.000000 | 5.872076 | 1 |
1 | 2 | 了 | 130191 | 1.3624 | 9.1570 | 0.301030 | 5.114581 | 1 |
2 | 3 | 在 | 118823 | 1.2434 | 10.4004 | 0.477121 | 5.074901 | 1 |
3 | 4 | 是 | 118527 | 1.2403 | 11.6407 | 0.602060 | 5.073817 | 1 |
4 | 5 | 和 | 83958 | 0.8786 | 12.5193 | 0.698970 | 4.924062 | 1 |
5 | 6 | 一 | 81119 | 0.8489 | 13.3682 | 0.778151 | 4.909123 | 1 |
6 | 7 | 這 | 65146 | 0.6817 | 14.0499 | 0.845098 | 4.813888 | 1 |
7 | 8 | 有 | 53556 | 0.5604 | 14.6103 | 0.903090 | 4.728808 | 1 |
8 | 9 | 他 | 52912 | 0.5537 | 15.1640 | 0.954243 | 4.723554 | 1 |
9 | 10 | 我 | 52728 | 0.5518 | 15.7158 | 1.000000 | 4.722041 | 1 |
從word_count
列,我們可以看到,詞頻表中收錄的最長的詞包含十個單字,平均而言包含兩個單字。通過簡單的統計,我們可以看到詞語中漢字個數的分佈規律如下表:其中兩字詞出現的次數最多,為10476次,佔比達到71.61%;其次為單字詞,為2391次,佔比達到16.34%。
# Count the frequency and frequency of occurrences of words of various lengths
word_length = pd.DataFrame(df.word_count.value_counts()).sort_index()
word_length.columns = ['freq']
word_length['freq_percent'] = 100*word_length['freq']/sum(word_length['freq'])
word_length.head(10)
freq | freq_percent | |
---|---|---|
1 | 2391 | 16.344248 |
2 | 10476 | 71.611183 |
3 | 1181 | 8.073006 |
4 | 506 | 3.458883 |
5 | 43 | 0.293937 |
6 | 22 | 0.150386 |
7 | 8 | 0.054686 |
8 | 1 | 0.006836 |
10 | 1 | 0.006836 |
現在讓我們看看漢語中詞頻的分佈規律是否符合齊普夫定律:
sns.regplot(df.log_rank,df.log_freq)
plt.xlim(0,4.3)
plt.ylim(1,7)
plt.title('The relationship between the logarithm of the frequency ranking and the logarithm of the frequency')
從上圖可以看出,頻次排名的對數與頻次的關係大致是線性關係,基本符合齊普夫定律。讓我們對兩個變數做一個線性迴歸,觀察相關指標是否表明兩者之間的線性關係足夠強。首先,我定義了一個輔助函式,呼叫statmodels庫中的相關函式進行線性迴歸並返回迴歸結果。
def reg(y,*args):
import statsmodels.api as sm
x = np.vstack((args)).T
mat_x = sm.add_constant(x)
res = sm.OLS(y,mat_x).fit()
print(res.summary())
reg(df.log_rank,df.log_freq)
OLS Regression Results
==============================================================================
Dep. Variable: log_rank R-squared: 0.990
Model: OLS Adj. R-squared: 0.990
Method: Least Squares F-statistic: 1.502e+06
Date: Sat, 15 Sep 2018 Prob (F-statistic): 0.00
Time: 10:27:07 Log-Likelihood: 25420.
No. Observations: 14629 AIC: -5.084e+04
Df Residuals: 14627 BIC: -5.082e+04
Df Model: 1
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
const 5.7144 0.002 3450.432 0.000 5.711 5.718
x1 -0.8846 0.001 -1225.535 0.000 -0.886 -0.883
==============================================================================
Omnibus: 15756.722 Durbin-Watson: 0.007
Prob(Omnibus): 0.000 Jarque-Bera (JB): 2257816.630
Skew: -5.242 Prob(JB): 0.00
Kurtosis: 62.952 Cond. No. 12.8
==============================================================================
Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
我們可以發現迴歸的,並且常數項與自變數的p值都小於1%,這都表明頻次的對數與頻次排名的對數在很大程度上呈線性關係,這與齊普夫定律的預言一致。但是,我們也可以從迴歸圖形中發現,低頻詞語的擬合程度更好,而高頻詞語的擬合程度較差,這表現在,前者基本都位於擬合直線上,而後者則大多位於擬合直線的下方。這說明對於漢語的高頻詞語而言,齊普夫定律預言的頻率要高於高頻詞語的實際出現頻率。我們可以通過下面的殘差圖更加直觀的觀察到這一點:
sns.residplot(df.log_rank,df.log_freq)
plt.ylabel('resid')
plt.title('The relationship between the residual and the logarithm of the frequency ranking')
因此,為了觀察不同頻次詞語的分佈規律,我們可以用四分位將頻次與排名資料分為四組:前25%的詞語為出現次數大於等於296;25%至50%分位的詞語的出現次數位於126與296之間;50%分位至75%分位的詞語出現次數位於51至126之間;最後25%的詞語出現頻次小於等於51次,由於原資料中刪除了所有出現次數小於等於50次的詞語,則最後一部分資料的頻次都為51次為一個常數,此一部分的迴歸沒有什麼意義,但為了完整性,我們還是將其列出來。我們對這四組資料分別做迴歸並觀察其殘差圖:
log_rank_first = df.log_rank[df.freq>=296]
log_freq_first = df.log_freq[df.freq>=296]
log_rank_second = df.log_rank[(126<=df.freq) & (df.freq<296)]
log_freq_second = df.log_freq[(126<=df.freq) & (df.freq<296)]
log_rank_third = df.log_rank[(51<df.freq) & (df.freq<126)]
log_freq_third = df.log_freq[(51<df.freq) & (df.freq<126)]
log_rank_fourth = df.log_rank[df.freq<=51]
log_freq_fourth = df.log_freq[df.freq<=51]
plt.subplot(221)
sns.regplot(log_rank_first,log_freq_first)
plt.title('$frequency \geq 296,R^2=0.992$')
plt.xlabel('')
plt.subplot(222)
sns.regplot(log_rank_second,log_freq_second)
plt.title('$126 \leq frequency \leq 296,R^2=0.999$')
plt.xlabel('')
plt.ylabel('')
plt.subplot(223)
sns.regplot(log_rank_third,log_freq_third)
plt.title('$51<frequency<126,R^2=1.000$')
plt.subplot(224)
sns.regplot(log_rank_fourth,log_freq_fourth)
plt.title('$frequency \leq 51,R^2=0.000$')
plt.ylabel('')
plt.subplot(221)
sns.residplot(log_rank_first,log_freq_first)
plt.title('$frequency \geq 296,R^2=0.992$')
plt.xlabel('')
plt.ylim(-1,0.2)
plt.subplot(222)
sns.residplot(log_rank_second,log_freq_second)
plt.title('$126 \leq frequency \leq 296,R^2=0.999$')
plt.xlabel('')
plt.ylabel('')
plt.ylim(-0.1,0.1)
plt.subplot(223)
sns.residplot(log_rank_third,log_freq_third)
plt.title('$51<frequency<126,R^2=1.000$')
plt.ylim(-0.1,0.1)
plt.subplot(224)
sns.residplot(log_rank_fourth,log_freq_fourth)
plt.title('$frequency \leq 51,R^2=0.000$')
plt.ylabel('')
我們可以看到對於25%-75%分位的詞語,線性迴歸的擬合情況非常好,均接近於一,而前25%的高頻詞語擬合程度就不太好,只有,而大部分的迴歸殘差都來自於排名前300名的詞語。總之,漢語詞頻的分佈規律基本與齊普夫定律保持一致,而低頻詞語的一致性程度更高。從迴歸結果我們可以得到,則頻次排名每增加1%,其出現頻次要下降0.88%。
三、漢字筆畫數分佈規律
在這篇論文裡,Bengt Sigurd等人發現英語中詞語的長度與其出現頻率的關係大致服務伽馬分佈,如下圖:
儘管在漢語中沒有單詞長度這種說法,但漢字的筆畫數與其有一定相似之處,它們都衡量了人們為了表達特定的含義而願意付出多少代價。詞語的長度不能太短,因為這樣能夠形成的詞語就太少,不能表達足夠豐富的含義;詞語的長度也不能太長,這樣記憶與表達的難度會提升,從而影響溝通的效率。這就使得英語中長度太長或太短的詞語出現的頻率都比較低,同樣的道理對於漢字的筆畫數也是適用的。我們可以使用現有資料,來檢驗一下漢字筆畫數的分佈規律是否與英語單詞長度的分佈規律類似,都服從伽馬分佈。
首先,讓我們匯入資料並看一下資料的基本資訊:
sc = pd.read_excel('char_stroke_count.xlsx')
sc.head(10)
rank | char | stroke_count | |
---|---|---|---|
0 | 1 | 的 | 8 |
1 | 2 | 一 | 1 |
2 | 3 | 是 | 9 |
3 | 4 | 不 | 4 |
4 | 5 | 了 | 2 |
5 | 6 | 在 | 6 |
6 | 7 | 人 | 2 |
7 | 8 | 有 | 6 |
8 | 9 | 我 | 7 |
9 | 10 | 他 | 5 |
該表格共收錄了10000個漢字,其中第三列為漢字的筆畫數,我們可以首先看下漢字筆畫數的直方圖,從而讓我們對漢字筆畫數的分佈情況有一個直觀的理解(如下圖)。我們可以看到,筆畫數為10,11與12的漢字較多,頻率均處於9%-10%之間。如果筆畫數小於11,則隨著筆畫數下降,出現的頻率逐漸降低;反之,筆畫數大於11,則隨著筆畫數上升,出現的頻率逐漸降低。
count_pert = []
for i in range(1,36):
count_pert.append(len(sc.stroke_count[sc.stroke_count==i])/100.)
x = np.arange(1,36)
sns.barplot(x,count_pert)
plt.xlabel('Number of strokes of Chinese characters')
plt.ylabel('Frequency')
plt.title('Histogram of the number of strokes in Chinese characters')
接下來讓我們比較漢字筆畫數的實際分佈與伽馬分佈與正態分佈的相似程度(如下圖),我們可以發現,實際分佈與伽馬分佈非常接近,而與正態分佈相距較遠。通過繪製quantiles-quantiles圖,我們可以更加直觀的觀察到這一點:
from scipy.stats import norm,gamma,probplot
sns.distplot(sc.stroke_count,hist=False,kde_kws={"shade": True,"label":"actual distribution"},
fit=gamma,fit_kws={"label":"gamma distribution"},color='c')
sns.distplot(sc.stroke_count,hist=False,fit=norm,
fit_kws={"label":"norm distribution","color":"red","linestyle":"--"})
plt.ylabel('frequency')
plt.title('real distribution v.s. gamma distribution v.s. norm distribution')
plt.ylim(0,0.1)
plt.legend(frameon=True,fontsize=12)
plt.subplot(121)
probplot(sc.stroke_count,plot=plt,dist='gamma',sparams=(12.68,),fit=True)
plt.title('actual distribution v.s. gamma distribution')
plt.subplot(122)
probplot(sc.stroke_count,plot=plt,dist='norm',fit=True)
plt.title('actual distribution v.s. norm distribution')
四、結論
有趣的是,雖然英語與漢語之間存在著天壤之別,它們的分佈規律卻有著很大的相似性。至於為什麼會出現這種分佈規律,現在還沒有一個統一的解釋。對於齊普夫定律的成因,目前至少有三種解釋:
第一種是齊普夫本人的解釋,他認為這體現了人思維的經濟性,即人類在不影響溝通效率的情況下儘可能的減少記憶詞語的負擔,這導致了某些常用詞彙出現的頻率非常高,已經完全足以應付日常生活中的大多數溝通場景。
第二種觀點認為齊普夫定律是“強者愈強、弱者愈強”這一規律的結果,某些常用詞彙會被使用的越來越多,最終會導致類似於冪律分佈的情況,其表現形式便是齊普夫定律。
第三種觀點:很多學者發現,齊普夫定律不僅在語言領域存在,而且在某些與語言並無關係的領域,如城市人口數排名與其人口的關係也服從齊普夫定律。這使得學者們傾向於相信,齊普夫定律的真正原因恐怕與語言的性質關係不大,而是與某種資料生成的過程有關。如Gabaix(1999)曾經指出只要所有城市人口都以一個同分布的隨機速度增長,那麼最後的城市人口分佈規律就會符合齊普夫定律,這可能是齊普夫定律為什麼會在語言學、經濟學等諸多領域都會出現的深層次原因。
如果有機會,我會在之後的文章對漢字分佈規律之所以如此的統計上的原因進行一些分析,我相信通過對資料生成過程的理解,我們可以撥開資料表層規律的迷霧,而認識其背後的根本原因。
五、參考資料
- Powers, D. M. (1998). Applications and explanations of Zipf’s law. In Proceedings of the joint conferences on new methods in language processing and computational natural language learning (pp. 151–160). Association for Computational Linguistics.
- Gabaix, X. (1999). Zipf’s law for cities: an explanation. The Quarterly Journal of Economics, 114(3), 739–767.
- Li, W. (1992). Random texts exhibit Zipf’s-law-like word frequency distribution. IEEE Transactions on Information Theory, 38(6), 1842–1845.
- Newman, M. E. (2005). Power laws, Pareto distributions and Zipf’s law. Contemporary Physics, 46(5), 323–351.
- Shtrikman, S. (1994). Some comments on Zipf’s law for the Chinese language. Journal of Information Science, 20(2), 142–143.
- Sicilia-Garcia, E. I., Ming, J., & Smith, F. J. (2003). Extension of Zipf’s Law to Word and Character N-grams for English and Chinese. International Journal of Computational Linguistics & Chinese Language Processing, Volume 8, Number 1, February 2003: Special Issue on Word Formation and Chinese Language Processing, 8(1), 77–102.
- Kanter, I., & Kessler, D. A. (1995). Markov processes: linguistics and Zipf’s law. Physical Review Letters, 74(22), 4559.