Help us understand the problem. What is going on with this article?

プログラミング言語別のおちんぎん分布を調べる (EnliveとIncanter)

More than 5 years have passed since last update.
※ この集計結果には、統計上の誤謬が多く含まれるので、どの言語を勉強すると儲かるかという視点でなく、あくまでもEnliveとIncanterを使うとWeb上のデータを使って簡単に集計プログラムが作れるよという点をお楽しみください。

どのプログラミング言語が儲かるのか、意識の高いエンジニアには気になるネタですよね。

indeed.comという求人サイトがありますが、これはクローラー型求人サイトとよばれるタイプで、各求人サイトからの情報をかき集めて検索ができるようになっています。

IndeedにもAPIはあるのですが、給与レンジをとることは出来なさそうなので、スクレイピングで対応します。Indeedでキーワード検索すると、右下に推定年収が表示されます。これを拾いだしてグラフを書いてみます。

Indeed検索結果ページ

スクレイピングにはJsoupのラッパーとしても使い勝手のよいEnliveを使います。

推定年収のDiv要素を取得するのはこんな感じで書けます。

(with-open [rdr (io/reader "http://jp.indeed.com/%E6%B1%82%E4%BA%BA?l=&q=java")]
  (select (html-resource rdr) [:div (attr= :id "rb_Salary Estimate")])

簡単ですね!

ここから、実際の推定年収を抜き出して、Incanterのデータセットにします。総求人件数にはバラつきがあるので、年収レンジの比率を合わせて計算するようにします(:percentage列)。

(defn salary-range [lang]
  (with-open [rdr (io/reader (str "http://jp.indeed.com/%E6%B1%82%E4%BA%BA?l=&q=" lang))]
    (let [ds (->>
              (-> (select (html-resource rdr) [:div (attr= :id "rb_Salary Estimate")])
                  (select [:li :a]))
              (map #(re-matches #"([\d,]+)万円~ \((\d+)\)" (get-in % [:attrs :title])))
              (map (fn [_] (-> _
                               (update-in [1] #(-> % (.replace "," "") (Long/parseLong)))
                               (update-in [2] #(-> % (.replace "," "") (Long/parseLong))))))
              (dataset [:label :salary :count]))
          total (apply + (sel ds :cols :count))]
      (add-column :percentage ($map #(/ % total) :count ds) ds)
      ds)))

推定年収のレンジは200万円刻みで表示されるようなのですが、残念なことに検索キーワードによって、開始年収に100万円のズレがあります。これはいかんともしがたいので、あきらめてそれぞれのレンジの下限でプロットすることにします。

次にグラフを書くコードです。作ったデータセットをもとにxy-plotを読んでグラフを作るだけです。viewを呼ぶことでSwingのウィンドウが起動してグラフを表示できます。

(defn draw-salary-distribution [words]
  (let [ds (salary-range (first words))
        chart (xy-plot (sel ds :cols :salary)
                       (sel ds :cols :percentage)
                       :legend true
                       :series-label (first words)
                       :x-label "Salary"
                       :y-label "Percentage")]
    (doseq [lang (rest words)]
      (let [ds (salary-range lang)]
        (add-lines chart
                   (sel ds :cols :salary)
                   (sel ds :cols :percentage)
                   :series-label lang)))
    (view chart)))

準備ができました。求人数の比較的多い言語達でグラフを書いてみます。

(draw-salary-distribution ["java" "ruby" "scala" "php" "VB" "C#" "Objective-c" "Node.js"])

気になる結果はコチラ!

language-salary.png

「金が欲しけりゃNodeJSをやれ!」 という結果のようです。

おっと2014年のBest Languageに輝いたClojureが無いではありませんか。

http://jp.indeed.com/clojure%E9%96%A2%E9%80%A3%E3%81%AE%E6%B1%82%E4%BA%BA

… いったい日本はどうしちゃったのでしょうか …

ということでUSのデータを使って同様のグラフを書いてみました。

language-us.png

Scala!!


コード
https://gist.github.com/kawasima/9221666

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした