日経XTECH、2019年12月号にて「プログラミング言語人気ランキング」という記事が掲載された。技術者440人に対して、主に次の観点でアンケートし、まとめたものだ。
- どのプログラミング言語を学びたいか、学びたくないか
- 業務現場では、どの言語をどのような用途で使用しているか
ここから収集できるデータを用いて、主成分分析とクラスタリングをしてみた。機械学習で言えば、どちらも「教師なし学習」と呼ばれる機械的な判別、分類方法だ。
特に上記1の観点からの分類では、かなり良好な傾向を見出すことができた。同時に上記2の観点からは、言語の判別、分類よりも使用用途に関する相関が垣間見え、そこから実際の利用用途を察することができる結果が示された。
統計処理にはRを用いた。コードの全文は、投稿末尾に掲載すると同時に、GitHubにもアップロードしている。用いたデータも同様にアップロードしている。
データ収集、整理
日経XTECHのサイトに掲載されているグラフに基づいて、数値情報をExcelにまとめた。結果として出来上がったのが、data.xlsxだ。
投稿末尾にまとめたGitHubへのリンクからダウンロードできる。
スキル磨きと、利用頻度の関係
日経XTECHでは、次の観点から調査していた。
- スキルを磨きたい、磨かなくてもよいと思う言語
- 最も使っている、よく使っている言語
まずこれらの観点を主成分分析する。「最も使用している」、「よく使用している」に相関が見いだせるのは当然だろう。とはいえ「最も使用している」と「スキルを磨きたい」のベクトルは直角に近く、相関は少ない。「スキルを磨きたい」のは「よく使用している」言語だ。
ここに言語をマップすると、興味深い傾向が分かる。各象限を大別すると次のようになる。
第1象限 | 右上 | よく使う領域 |
第2象限 | 右下 | スキルを磨きたい領域 |
第3象限 | 左下 | 使用頻度が低い領域 右寄りなほどスキルを磨きたい 左寄りなほどスキルを磨かなくてよい |
第4象限 | 左上 | スキルを磨かなくてもよいと思う領域 |
これだけでも何かが十分に伝わる読者は多いと思う。次にこれらの言語をクラスタ分析する。2→4→9とクラスタ数を増やしていく毎に、グループごとの特徴が際立ってくるのだ。
次に紹介する各図と見比べると、朧げなストーリーが浮かんできそうな気がする。例えばこんな具合だ。
- JavaやPHP、C#などの基幹開発から、モダンなweb開発へ転身したい
- VB系、COBOL等のレガシーから逃げられない
- 目新しい言語は、それほど使われていないし、それほど学びたいとも思わない、しかしPythonは例外
- Pythonを使っている人の利用頻度は高く、それに対する向上心も旺盛
2グループ
赤 | スキルを磨かなくてもよい |
青 | スキルを磨きたい |
4グループ
紫 | スキルを磨かなくてもよい |
緑 | あまり使わない |
赤 | よく使う 使わざるを得ない |
青 | スキルを磨きたい |
9グループ
唯我独尊 | アセンブラ C/C++ Python |
いわゆる勝ち組 |
レガシー | COBOL FORTLAN |
レガシーから離れたい=学びたくない |
基幹開発 | C# Java VBA |
学習意欲に関わらず、使わざるを得ない |
足抜け | PHP VB.NET |
現在稼働中のシステム ここから脱却したい |
衰退 高ハードル |
Lua Objective-C Perl PL/I Scala Visual Basic |
より今時な言語へ移行したい |
新興 ジャンル限定 |
Go Kotlin R Ruby Swift TypeScript |
使用頻度は低いが将来に見込みがある 特定用途で利用する |
web開発 | HTML/CSS JavaScript SQL |
まさにズバリ 何も言うことなしの組み合わせ |
使用用途
日経XTECHは、各言語の使用用途も調査していた。用途は次の9領域だ。
- 新規開発
- 更改
- 運用
- 基幹系
- 分析
- AI
- web
- 組み込み
- モバイル
- その他
これらの観点からの主成分分析は、相互に相関の強い結果が示された。これはおそらく複数回答可であることの帰結だと推察している。
ここに回答のある言語だけを対象にマップすると、また興味深い傾向が現れる。同時に朧げなストーリーも浮かんでくる。
- Javaは基幹系、web系の業務で用いられており、その更改ではC#が用いられていそうだ。
- 新規開発、組み込み系の相関が強く、そこではC/C++が用いられている。
- 分析用途にVBAが用いられている。おそらくExcelの影響だろう。
参照
コード全文
🔎R code
library(readxl) library(NbClust) library(factoextra) library(Rmisc) library(FactoMineR) library(factoextra) library(corrplot) #PCA myPCA = function(d){ mypca = PCA(d, scale.unit = TRUE, graph = FALSE) print(mypca$eig) fig20 = fviz_pca_var(mypca, col.var = "cos2", gradient.cols = c("blue", "red"), repel = TRUE) fig21 = fviz_pca_var(mypca, col.var = "contrib", gradient.cols = c("blue", "red"), repel = TRUE) multiplot(fig20, fig21, cols = 2) corrplot(t(mypca$var$cos2), addCoef.col = "gray") corrplot(t(mypca$var$contrib), is.corr = FALSE, addCoef.col = "gray") fig22 = fviz_pca_biplot( mypca, col.var = "darkgreen", col.ind = "cos2", gradient.cols = c("blue", "red"), repel = TRUE) fig23 = fviz_pca_biplot( mypca, col.var = "darkgreen", col.ind = "cos2", gradient.cols = c("blue", "red"), repel = TRUE, select.ind = list(cos2 = 0.6)) multiplot(fig22) multiplot(fig23) } #number of cluster mynb = function(d){ myAHCnum = NbClust(d, method = "ward.D", index = "all") myNHCnum = NbClust(scale(d), method = "kmeans", index = "alllong") fig1 = fviz_nbclust(myAHCnum, method = "silhouette") fig2 = fviz_nbclust(myNHCnum, method = "gap_stat", nboot = 100) multiplot(fig1, fig2) } #clustering mycl = function(c, d){ myAHC = hcut(d, k = c, stand = TRUE, graph = FALSE) myNHC = kmeans(scale(d), c, iter.max = 100, nstart = nrow(d)) fig10 = fviz_silhouette(myAHC, label = TRUE, rotate = TRUE, print.summary = FALSE) multiplot(fig10) fig11 = fviz_cluster(myNHC, data = d) multiplot(fig11) } data = read_excel("C:/user/document/Temple University/DTA101/week08/assignment/data.xlsx") # PCA with skill pca_data1 = as.matrix(data[,c(2:5)]) rownames(pca_data1) = data$language myPCA(pca_data1) # PCA with usage pca_data2 = as.matrix(data[,c(6:15)]) rownames(pca_data2) = data$language pca_data2 = pca_data2[c(2:5, 8:10, 12, 14, 16, 18:21, 23:24),] myPCA(pca_data2) # clustering d1 = as.matrix(data[, c(2:5)]) d1 = scale(d1) rownames(d1) = data$language mynb(d1) for (i in c(2, 4, 9)){ mycl(i, d1) }