看Github上的開發者是如何更換編程語言的?

YvetteHolid 7年前發布 | 27K 次閱讀 Github

譯者注:你是否曾經想過嘗試換一門語言進行開發,從而挑戰一下自己。本文作者分析了GitHub上面的用戶,從而得到了用戶切換開發語言的相關信息。以下為譯文。

你是否曾經一邊掙扎于項目的混亂,一邊思考著:“我可以用這門語言來做,但是為什么不嘗試換一門語言,看看會不會更有趣呢?”。 埃里克·伯恩哈德森 曾在博客中寫過一篇很好的文章:“ 為什么我們從語言X換成語言Y ”的特征向量,他根據所有與語言變化相關的谷歌查詢做了一個情形分析表。然而,當我讀到它的時候,我忍不住想知道,真正跨行成功的人的比例是多少。因此,越來越多的人開始深入了解這一想法,并了解在GitHub用戶中語言的流行程度是如何變化的。

可用數據集

多虧了數據檢索管道,source{d}可以將數據集開放給用戶,其中包含每年每位GitHub用戶使用不同編程語言編寫的代碼的字節數。在一些圖中,它是:

  • 450萬GitHub用戶
  • 393種不同的語言
  • 總共10TB的源碼

如果你想知道這些存儲庫和語言的細節,我建議你可以看看 Vadim Markovtsev 的博客文章: Spaces or Tabs

為了更好的理解接下來將會發生什么,我發現如果用 甘特圖 的形式將開發語言的使用歷史以可視化的形式進行展示,效果很不錯。

注意,顏色表示每種語言的源碼的比例。我們可以從這個圖中推導出一些信息:

  • 用戶最喜歡的語言是 Scala ,而且只鐘情于它。
  • 用戶嘗試了了 Go語言 ,但沒堅持多久。
  • 他們用 Java 運行了一個重要的項目,但是他們寧愿在Scala中編寫代碼。使用Java可能是完成單個項目的一個約束。

當然,從這張圖中可能會推導出在2014年用戶開始從 Java 切換到 Markdown 。我們希望避免去比較那些沒有可比性的語言。這就是為什么我們將重點放在25個主要編程語言的樣本上。實際上是22個,因為我們沒有關于Lisp、Kotlin和Cobol這三門語言的數據。

量化

你肯定會同意,GitHub的“Hello world”庫并不真正算作是切換到另一種語言。因此,我們決定對數據集中的貢獻值進行量化,以減少干擾。出于這個原因,我們在下面的小節中展示了GitHub每個字節大小的貢獻的分布。

按大小分配GitHub貢獻

正如我們所看到的,它的尾巴很長,大部分的貢獻都是很小的。為了近似分布,我們使用了 核密度估計 ,也就是圖中的橙色曲線。最后,通過將曲線下的面積劃分成10個相等的部分來得到量化。從0開始編號。

在對數據集進行過濾和量化之后,我們可以繼續構建自己的轉移矩陣。

最小費用流問題

對于每一個GitHub用戶,我們聚合年度的矢量;我們將稱它們為反應器,其中每個393個元素代表著當年對應的語言編碼的字節數。在規范化之后,這些反應堆就像直方圖一樣,我們需要相互比較。

在PyEMD中提供了一種優雅的方法,在編碼和計算時間上都是有效的,它提供了一個Python包裝器,用于“ 地球搬運工 ”的距離,它對“Numpy”友好。這個距離度量——比用于直方圖比較的歐氏距離要好的多——特別有趣,因為它是基于 線性規劃 (LP)。事實上,它可以被看作是以下 交通問題 的解決方案,where

運輸問題,供應和需求

我們可以看到,每隔幾年,字節數要么被看作是“供給”,要么是“需求”。

讓我們在這里稍微講一下。首先,邊的“成本”被設為1,以使我們無偏見。其次,為了減少我們的問題到經典的 流量最小化公式 ,我們必須在兩部分圖的兩邊加上一個人工的源和水槽,以確保流體的守恒。這不是一個臨界點, 斯坦福CS97SI 的最后一張幻燈片描述了這個轉變。

轉移矩陣

以下是為特定的GitHub用戶計算連續兩年之間的轉移矩陣的核心代碼。我們使用的主要功能是emd_with_flow,它由PyEMD包提供。

def get_transition_matrix_emd(user, year):

# lang2keep is the list of the 22 programming languages we kept
# stairvalue() is the step function that comes from quantization

# Build user's reactors for year and year+1
reactors = zeros((len(lang2keep),2), order='f')

for ind, code_in_lang in enumerate(dataset[user]):
    lang = code_in_lang[0]

    if lang in lang2keep:
        for y, qtt_coded_year in code_in_lang[1]:
            if y == year:
                reactors[lang2keep.index(lang),0] = stairvalue(qtt_coded_year)

            elif y == year+1:
                reactors[lang2keep.index(lang),1] = stairvalue(qtt_coded_year)

if (sum(reactors[:,0]) == 0) or (sum(reactors[:,1]) == 0):
    # no transition to consider
    P = zeros((len(lang2keep), len(lang2keep)))
    return P

else:
    # Normalization of reactors
    for i in [0, 1]:
        reactors[:,i] = [j/sum(reactors[:,i]) for j in reactors[:,i]]

# compute the Earth Mover's distance between the 2 reactors thanks to the emd_with_flow function
distance = np.ones((len(lang2keep), len(lang2keep)))
dist, P = emd_with_flow(reactors[:,0], reactors[:,1], distance)
P = np.asarray(P)

return P

使用Python計算轉移矩陣的函數

最后,在對用戶和過去16年(我們將考慮每年的轉移)的流矩陣求和之后,我們得到了最終的轉移矩陣。現在讓我們將它與埃里克根據Google查詢編譯的情形分析表進行比較。下面的圖是使用埃里克的腳本繪制的。

與埃里克的表相比,我們在轉移矩陣的主對角線上有一些元素。稍后我們將看到如何利用這些元素。然而,盡管我們使用的數據集是不同的,但是我們還是注意到有很多的相似點,并且感知到相同的語言概要。與埃里克的表相比,我們在過渡矩陣的主對角線上有一些元素。稍后我們將看到如何利用它。然而,盡管我們使用的數據集是不同的,我們注意到許多相關的相似點。

GitHub的“語言排行榜”

既然我們有了流矩陣,我們就可以知道哪種語言是最受歡迎的,哪一種最不受歡迎。還可以在表示的圖上計算中心度量,例如特征向量的中心。事實上,這些措施傳達了語言的相對流行程度,在某種程度上也就是反應了人們使用一種語言編碼然后會轉換成另一種語言的可能性。我們將采用計算特征向量中心的方法。如果你需要進一步的解釋,可以閱讀Vadim在他的博客文章中關于 GitHub的貢獻圖表 的PageRank分析。

  • 我們的流矩陣包含嚴格的正元素,這是使其 不可約 的充分條件;總有一種方法可以從任何給定的語言中獲得所有其他語言。因此,根據 perron-fro 定理,我們正在尋找最偉大的特征值及其對應的特征向量。
  • 我們可以使用 冪次迭代 算法來找到最主要的特征向量。然而,除了不可約外,矩陣還需要是隨機的和非周期的。
  • 當移除主對角并使行規格化時,我們的流矩陣就變成了 隨機的 。最大的特征值現在等于1。
  • 最后,為了使我們的矩陣 不受周期 和條件的限制,拉里和謝爾蓋在1998年引入了一個著名的技巧。在 斯坦福的CS246 中有很好的解釋,但是為了縮短它,它主要包括用以下公式更新我們的流動矩陣:

where,

  • β被稱為隨機游走因子,被設為0.85
  • N是語言的數量

冪迭代

在這些步驟之后,我們的良好條件流矩陣包含了在語言之間切換的可能性,我們可以繼續進行冪次迭代。該算法由以下矩陣乘法組成,直到收斂到主特征向量:

在下面的代碼中,您將找到返回所需要的主導特征向量的代碼。

def power_iteration(A, nb_iterations=100, beta=0.85):
u = np.random.rand(len(lang2keep))
u = np.reshape(u, (len(lang2keep), 1))
A = A * beta + ((1 - beta) / len(lang2keep)) * np.ones((len(lang2keep), len(lang2keep)))

for _ in range(nb_iterations):
    u_next = np.dot(A,u)
    u_next_norm = sum(u_next)
    u = u_next / u_next_norm

return u

power_iteration(transition_matrix)

冪迭代算法,Python。

GitHub上面最受歡迎的開發語言

終于!這是獎勵:我們的 馬爾可夫鏈 的平穩分布。這個概率分布是獨立于初始分布的。它給出了語言之間隨機切換過程的穩定性的信息。因此,無論目前的語言有多流行,假設的未來靜止狀態不變。以下是我們在GitHub上使用的22種語言的流行度排名:

根據 centrality measure 在GitHub上,語言的受歡迎程度

Python(16.1%)似乎是最吸引人的語言,緊隨其后的是Java(15.3%)。這尤其有趣,因為GitHub上只有11.3%的源代碼是用Python編寫的。

在埃里克的排名中,Go是最大的贏家,16.4%。由于Erik基于Google查詢的方法,似乎圍繞Go的熱門話題,讓人們在博客中明確地表示,如果他們想要使用這種語言,那么就需要花一點時間來生成在GitHub上有效編寫的項目。

此外,C(9.2%)的表現與埃里克的14.3%的評分是一致的,盡管這是由于在GitHub上用C編碼的項目數量。

盡管在GitHub上的代碼行數比Ruby多10倍,但它們的靜態分布是相同的。

Go(3.2%)出現在第9位,這在很大程度上是值得尊敬的,因為在GitHub上托管的項目中有一小部分(0.9%)。例如,相同比例的項目是用Perl編寫的,但是這種語言并沒有真正激起激情(2%的流行)。

堅持使用一種語言

如果我們在應用冪次迭代之前保留了轉換矩陣的主對角線,我們得到的結果會略有不同。它主要減少了高級語言的流行,同時也提高了小語種的知名度。事實上,似乎有理由相信,那些把時間花在掌握其他語言的開發人員身上的開發人員,往往會堅持他們的觀點,而不像那些受歡迎的人。

在剩下的文章中,我們將考慮我們的第一個特征向量的表示。

回到轉移矩陣

埃里克的轉移矩陣是排序的,因此最流行的語言出現在底部。我們用同樣的順序來比較它們:

這是我們的矩陣,獨立排序:

source{d}的有序轉換矩陣,原始順序

  • 在最流行的5種語言(Java、C、C++、PHP、Ruby)中編寫代碼的開發人員最有可能用approx切換到Python。平均22%的幾率。
  • 此外,根據埃里克的矩陣,人們從Ojective-C轉換到Swift和返回的可能性更大——24%和19%。
  • 類似地,一個Visual Basic開發人員有更多的機會(24%)轉移到C#,而Erik在這個轉換過程中幾乎肯定會有92%的機會。
  • 最重要的是,Scala的用戶更愿意使用Scala,分別是22、29和40%。
  • 使用數字和統計環境的人,如Fortran(36%),Matlab(33%)或R(40%)最可能轉向Python,與Erik的矩陣相反,這是C語言的未來語言。
  • 我在埃里克的研究結果中發現了一個共同點,那就是Go吸引了那些放棄研究Rust的人。

過去的16年

正如我們前面提到的,在對轉換矩陣進行求和之前,我們現在考慮特定的年份,并研究這些年矩陣是怎樣的。他們是否表達相同的語言資料?自2000年初以來,它是如何演變的?以下是來自不同時間軸的4個矩陣的樣本:

轉變矩陣的時間演化

最后,隨著時間的推移,這些矩陣的演化似乎是仿射的,我們每年都觀察同一種語言。因此,為了突出這個語言概要文件的時間線,我們將冪迭代應用到每個矩陣。在過去的16年里,我們的平均分配是固定的,但是現在我們看它的時間順序。在堆棧區域圖中給出了一系列的主要特征向量的序列。

在過去的16年里,語言的平穩分布

每個帶的厚度對應于占主導特征向量的值。這些帶按我們之前計算過的平均受歡迎程度排序。

  • 前兩種語言,Python和Java具有相同的配置文件。他們已經取代C的位置已經15年了。事實上,前三層的聚合給出了一個直的。
  • 2008年,當Java或Ruby等語言開始快速增長時,C++的吸引力顯著下降。然而,自這一時期以來,它一直保持著它的受歡迎程度。
  • 我絕對支持Erik的結論:Perl正在消亡。
  • 蘋果在2014年的WWDC大會上展示了Swift,而該公司本應取代Obj-C。因此,在此事件之后,Obj-C的采用應該開始減少,但是這兩種語言的總和應該保持不變。看看這個數字,這個假設是正確的。
  • 從2007年開始,Ruby似乎已經有了6年的榮耀。這也許可以用web框架Ruby on Rails(RoR)的發布來解釋,當蘋果宣布將在10月份發布Mac OS X v10.5“Leopard”時,它達到了一個里程碑。
  • 至于Go,它的受歡迎程度相對較低。然而,這一動態顯然是積極的。

變化

在發表這篇文章后,我看見有的讀者在語言冗長性方面有些偏見。任何事情都是公平的:全球量化方案可能會給像Java這樣的冗長的語言帶來優勢,而比如像Haskell這樣的濃縮的語言可能就沒有。我分別對每種語言進行了量化,并重新運行了其余部分的分析。正如在下面的表格中所看到的,沒有什么真正的變化;Ruby和C++交換了位置,但是它們的級別非常接近。最后看起來完全一樣。

結論

把埃里克的情形分析表看作是語言分布問題的二階導數,而我們的流轉換就像一階導數一樣,這更合適。也就是說,首先你先要google查詢,然后試著編寫一個OSS項目,最后導致了語言的分布變化。

 

來自:http://www.iteye.com/news/32554

 

 本文由用戶 YvetteHolid 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!