データ関係者の集まる「第六回データ整備人」のデータ可視化と対応分析[,アンケート分析,コレスポンデンス分析,Correspondence analysis]


データ関係者の集まる「[データ整備人](https://analytics-and-intelligence.connpass.com/)」の勉強会にて発表してきました。
(発表内容もいつか記事にするかも)

登壇と直接関係ないですが、登壇側ということで個人情報を除いて(抜いて)分析させていただけることに。

今回は300人を超える参加者でした。
アンケートとして、「職種」と「データとの関わり」が選択項目にあったので、このあたりを質的変数として可視化・分析することで
集まった人の傾向が分かれば面白いかな。と。

#早速


```r
library(tidyverse)

dat_original <- read_csv("https://raw.githubusercontent.com/amazongodman/open_folder/master/job_con.csv", locale = locale(encoding = "cp932"))
dat<-dat_original
nrow(dat)
>308
```

308人の参加でした。


職種はどのくらいの種類があるのか

```r
length(unique(dat$job))
>142
```

142種類の職種がありました。
ある程度職種が被っていそうなので、細かい処理をする必要はなさそう（よかった）

どんな職種があるの？


```r
unique(dat$job)


  [1] "エンジニア"                                                             
  [2] "コンサルタント"                                                         
  [3] "なし"                                                                   
  [4] "財務"                                                                   
  [5] "リレーション&分析"                                                      
  [6] "UXデザイン室"                                                           
  [7] "ICTコンサルタント"                                                      
  [8] "データアナリスト"                                                       
  [9] "企画"                                                                   
 [10] "データエンジニア"  
```


どの職種が被っているか

```r
dat %>% group_by(job) %>% summarise(count=n()) %>% arrange(desc(count))

1 データエンジニア          37
2 エンジニア                28
3 データアナリスト          27
4 データサイエンティスト    22
5 SE                         8
6 コンサルタント             8
7 システムエンジニア         8
8 アナリスト                 6
9 ソフトウェアエンジニア     5
10 データアーキテクト         5
```

このあたりを大分類にする
大分類意外の職種も、大分類に混ぜて良いものがあるのでは？
たとえば、アナリストとデータアナリストは同じ仕事とカウントして合計する

他の職種も確認してみる

```r
count_dat <- dat %>% group_by(job) %>% summarise(count=n()) %>% arrange(desc(count))

count_dat[1:10,]
count_dat[11:20,]



   job                    count
   <chr>                  <int>
 1 社内SE                     4
 2 代表                       4
 3 バックエンドエンジニア     3
 4 営業                       3
 5 開発                       3
 6 研究開発                   3
 7 IT                         2
 8 ITコンサルタント           2
 9 Webディレクター            2
10 ソフトウェア開発           2



sum(count_dat$count)
```

社内SEとかもSEにマージしたい
全角のSEとかもよく見たらあるのでマージしたい

名前を書き換えておなじものにする
完全一致はmatch()
部分一致はgrep()

```r
#[開発] の文字が入る行を表示する
dat[grep("開発", dat$job), ]
```

開発とかソフトウェア開発とか、研究開発とか、正直字面の情報が少ないものは同じ名前にする
上書きされちゃうので、優先的にまとめたいものを先にしておく

```r
dat$job[grep("ソフト", dat$job)]<-"ソフトウェア関係"
dat$job[grep("(開発|技術|研究)", dat$job)] <- "技術・研究・開発関係"
```

そんなのを地道にづづける

```r
dat$job[grep("システム", dat$job)] <- "システム関係"
dat$job[grep("企画", dat$job)] <- "企画関係"
dat$job[grep("(ＳＥ|SE|se)", dat$job)] <- "SE"
```

データ関係とか、データまわり、とかの職業がいる
これはデータサイエンスとかとは別の枠でまとめたい
しかし「データ」を鍵に一致検索すると、データサイエンティストとかぶってしまうので、
データサイエンティスト側の「データ」を一致しないように「でーた」で塗りつぶす

```r
dat$job[grep("アナリスト", dat$job)] <- "アナリスト・でーたアナリスト"
dat$job[grep("分析", dat$job)] <- "アナリスト・でーたアナリスト"
dat$job[grep("Ana", dat$job)] <- "アナリスト・でーたアナリスト"

dat$job[grep("データサイエンティスト", dat$job)] <- "でーたサイエンティスト"
dat$job[grep("データエンジニア", dat$job)] <- "でーたエンジニア"

dat$job[grep("(データ整備人|データアーキテクト)", dat$job)] <- "でーた整備人"

dat$job[grep("(データ|Data|data)", dat$job)] <- "data関係(無所属)"

dat$job[grep("コンサル", dat$job)] <- "コンサルタント"

```


```r
dat_matome <- dat %>% group_by(job) %>% summarise(count=n()) %>% arrange(desc(count))
head(dat_matome,20)


1 アナリスト・でーたアナリスト    43
2 でーたエンジニア                40
3 エンジニア                      28
4 でーたサイエンティスト          24
5 技術・研究・開発関係            18
6 SE                              14
7 システム関係                    13
8 コンサルタント                  12
9 data関係(無所属)                11
10 ソフトウェア関係                11
11 企画関係                         9
12 でーた整備人                     7
13 代表                             4
14 バックエンドエンジニア           3
15 営業                             3
16 IT                               2
17 Webディレクター                  2

```

だいぶまとまった。
データ整備人の7人を区切りとして、それ以外を「その他：other」とする

```r
job_count <- dat_matome[dat_matome$count>=7,]

dat_matome[dat_matome$count<7,]
sonota <- sum(dat_matome$count[dat_matome$count<7])

job_count_sonota = rbind(job_count,c("その他",sonota))
job_count_sonota$count<-as.numeric(job_count_sonota$count)

g <- ggplot(job_count_sonota, aes(x = reorder(job, -count), y = count, fill = job))
g <- g + geom_bar(stat = "identity")
g <- g +   theme(axis.title.x=element_blank(),
                 axis.text.x=element_blank(),
                 axis.ticks.x=element_blank())

g <- g + geom_text(aes(label=count), position=position_dodge(width=0.9), vjust=-0.25)

plot(g)

ggsave(file = "job_count_sonota_bar.png", plot = g)
```


![job_count_sonota_bar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/9fd900cc-59f1-8106-2247-0bc4ad585daa.png)



アナリスト、データエンジニアが多い
データサイエンティストやエンジニアもいる
データ関係は二極化している？

「活用側：アナリスト&サイエンティスト」vs「基盤側：データエンジニア&エンジニア」

データ活用が進む時にはエンジニア側が増えてからサイエンティストが増えるのか？
(第五回までのデータも気になるところ...)


また、SEや開発も多い
システム関係とデータエンジニア・エンジニアあたりは同じ波長の人かもしれない
データ専門でないが、データの今後を考えているSEが参加しているのか？

#アンケート項目「データとの関わり方は？(複数回答)」

それぞれの職業の人がどんな回答をしているのか、関係を見る
文字列操作とクロス集計

```r
library(qdapTools)
check_box_table <- mtabulate(strsplit(gsub(" ", "", dat$relation), ","))

cross_table <- dat[,2] %>% 
  mutate("job_count" = 1)  %>% 
  bind_cols(check_box_table) %>% 
  group_by(job) %>% 
  summarise_all(funs(sum)) %>%
  group_by(job = replace(job, job_count <7, 'other')) %>% 
  summarise_all(funs(sum))

library(reshape2)

melt_cross_table = melt(cross_table,
                        id.vars=c("job", "job_count"),
                        variable.name="check", na.rm=TRUE)


for(i in 1:length(unique(melt_cross_table$job))){
  
melt_gg<- melt_cross_table %>%
  filter(job==unique(job)[i]) %>% 
  mutate("num_x" = c(1:nrow(melt_cross_table%>%filter(job==unique(job)[i])))) 

g  <- ggplot(melt_gg,aes(x =  num_x, y = value, fill=check))+
  geom_bar(stat = "identity", position = "dodge")+
  geom_text(aes(label = value, y = value), size = 9)+
  theme_classic(base_size = 18)+
  labs(title = paste0("job = ",unique(melt_cross_table$job)[i]," number = ", melt_cross_table$job_count[melt_cross_table$job==unique(melt_cross_table$job)[i]][1] ) , x = "", y = "")

  ggsave(file = paste0(i,".png"), plot = g)
  
}
```



<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d0b77981-03b7-d79a-85b3-6f129f24a487.png" width=50%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/563e97c5-1a56-8a42-cde0-513ac204b434.png" width=50%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/b07129e7-f3ce-463e-0635-3a067f507479.png" width=50%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/dc97ccb0-076e-df48-8261-d7c2d645f307.png" width=50%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/ef4d0c03-c9c3-268c-b6db-a135ddf3f1a8.png" width=50%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/3682659c-6ab6-1bcd-2731-53413bf1c8e4.png" width=50%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/f728dd21-a67b-37c3-3a8c-b76c669850cc.png" width=50%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/b960fbb8-2fb7-45fd-9af3-95ff4e4d8ee5.png" width=50%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/a7d08dca-b69d-d60c-6d23-971b4cf05213.png" width=50%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/18ef5f69-1525-e1f6-a7f5-17af35c8544f.png" width=50%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/e282b2d8-16f8-4674-3bb4-b4f4f8cad0fb.png" width=50%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/55b191a4-6bf4-deef-d1b9-6fb651228760.png" width=50%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/5918781a-ab6f-2c1c-a719-aa77e7a0eed9.png" width=50%>




どの回答が多いのか俯瞰する
色が濃いほど回答者が多い

```r
matrix_heat <-as.matrix(cross_table[,3:9])
rownames(matrix_heat) <- unique(cross_table$job)

par(oma = c(20, 10, 3, 2))
heatmap(matrix_heat,col=colorRampPalette(c("gray","black"))(256))
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/57d4c3b6-f016-2bab-597b-7693169f05fa.png)



#対応分析(コレポン)

質的データのクロス集計表に対して、個体の類似性をマッピングする
コレポンの中身は別で説明する(予定)


```r
library("FactoMineR")
library("factoextra")
library("gplots")

dt <- as.table(as.matrix(matrix_heat))

balloonplot(dt, main ="data architect", xlab ="", ylab="",
            label = FALSE, show.margins = FALSE)

#chisq.test(matrix_heat)
```

heatmapとはまた別の方法で。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/60d55ebb-00a5-78c9-5db5-26a55f11aba0.png)






```r
res.ca <- CA(matrix_heat, graph=FALSE,ncp = 2)

fviz_ca_biplot(res.ca, label =c("row","col"))
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/226e566a-e22b-4a9c-1e4d-a6b108b4285f.png)

#対応分析の結果


- データウェアハウス&データマート設計
  -  は、**エンジニア・データエンジニア・システム関係・データ整備人**が担当(少しだけSEもそっちより)
  -  これは結構納得の結果

- BIツール&データ抽出
  - は、かなりの人数がチェックを入れていた
  - どの人とも関係のある項目らしい

- データ管理
  - は、コンサルタントが近いかも
  - 管理方針とかかな？
  
- データを利用した意思決定
  - はotherの方向にある...ように見える
、- otherには取締役・CEO,CIO,代表などが確認できたので、それらと関係しているかも
  - otheは複数の回答が混ざっているので信頼は低い

- 分析レポ&意思決定助言
  - 企画系とデータサイエンティストが近くに見られる
  - 企画は納得、経営企画とかはデータをどう使うか考えているのだろう
  - アナリストはどちらかというと抽出と分析の中間？
  - データサイエンティストは分析寄りとして回答しているのか
  - データサイエンティストのなかのどれだけが「意思決定への助言」ができているのかは気になる


#今回の結果から次回に活かせるもの

・とりあえず分析できて楽しかった
・職種の項目は今後分析するなら上記の13項くらいにまとめてもいいかも(表記にばらつきがあると大変)
・その他(自由記入)のほうがフラグとして集計しやすい
・「データとの関係」では、分析,レポーティング,意思決定者への助言　は分けたほうが良かったかも
・エンジニア系,システム系,データエンジニア系が参加人数としても多く、データマート設計に関わっていることから、これから「データ整備人」の会の需要テーマは「データウェアハウスの構築関係」で絞ったほうがリピーター増えるかも
・次にアナリストやデータサイエンティストが多かったので、分析系の人がどんな項目に興味があるのか見つけて新しいテーマの企画をしても楽しそう

気軽に対応分析してみましたが、いろいろわかりそう。
とはいえ、固有値・固有ベクトルからわかるのは推測である
「**如何に尤もらしく経験的根拠からストーリーを作るか**」という面もあるので、何とでも...