안녕하세요. 


오늘은 간단한 개념이지만 헷갈릴수 있는 forecast 와 prediction의 차이에 대해서 알아보겠습니다.


한글로 굳이 번역하자면, prediction(예측), forecast(예상)이 될수 있을 것이라고 생각합니다. 


하지만 헷갈릴수 있으므로 번역은 하지 말고 영어에서 쓰이는 의미로써 prediction과 forecast의 차이에 대해서 고찰해보도록 하겠습니다.


많은 사람들이 혼돈해서 쓰는 경우가 많지만, 보통 데이터 분석하시는 분들은 이 둘의 개념을 중요시 여기십니다.


그래서 데이터 분석에 석학 중에 한분이신 네이트 실버의 신호와 소음이라는 책에는 이 둘의 차이를 정확하게 알려주고 있습니다. 


  "prediction이나 forecast라는 단어는 여러분야에서 다른 의미로 사용된다 몇몇경우에는 동일한 의미로 사용되기도 하지만, 몇몇 분야에서는 철저하게 구분된다 그런데 지질학만큼 두단어의 차이점에 민감한 분야는 없어보인다. 지질학자와 대화를 나눌때는 다음사항을 명심해야 한다. 


1. prediction 은 지진이 언제 그리고 어디에서 일어날 것인지 구체적이고 명시적으로 말하는 것이다. 대규모 지진이 6월 28일에 일본교토를 강타할 것이다가 prediction이다.


2. forecast는 확률적 진술이며, 대개는 장기적 차원의 발상이다. '지진이 30년안에 캘리포니아 남부 지역에서 일어날 확률은 60%다 가 forecast 이다.


따라서 지진을 prediction할수 없어도 forecast할수 잇다는게 미국 지질조사소의 공식 입장이다."


따라서 미래에 일어난 구체적 명시는 prediction, 확률적 진술은 forecast라고 이해하시면 좀 더 정확한 표현을 사용하실수 있을것이라 생각됩니다. 


감사합니다.




 

안녕하세요. DA ryan 입니다. 

데이터 분석에 대한 식견을 가지려면 타인이 분석한 것도 잘 파악해볼 필요가 있습니다. 
그래서 kaggle에 open data set을 가지고 분석한 결과물들중에 괜찮은 것을 함께 알아보려고 합니다 

그래서 처음에 고른 데이터는 멜번 부동산 데이터입니다. 
멜번도 집값이 어마어마하긴 마찬가지인데 데이터를 올린 사람이 아래와 같은 사항이 궁금하다고 합니다.

메인 명제
  1. 멜번에 부동산 가격 트렌드를 파악 혹은 예측 할수 있는가?
  2. 어떤 지역을 사는것이 가장 좋은 선택이 되는것인가?
  3. 어떤 부동산이 가장 가치가 있는 부동산인가?
  4. 어디가 상대적으로 비싼지역이고 어디가 싼 지역인가?
  5. 내가 방2개가 딸린 조건의 집을 사야만 하는가?

위의 명제들에 대한 해답을 가지기 위해서 데이터 제공자는 Domain.com.au 에서 데이터공개된 내용을 다운받아 클린징을 하고 최고의
데이터 셋을 만들기 위해서 노력했다고 합니다. 

데이터셋을 클린징 했다는 이야기는 결손값 (즉 데이터 내용이 없는 것들)을 제거하고 그리고 outliner(즉 이상치, 특이하게 평균보다 멀어서 평균을 높으거니 낮추는 것이라고 생각하시면 됩니다. 트랜드를 파악하기 위해서는 단순히 모든 데이터를 다 집어 넣고 분석하는 것도 좋을수 있지만, 주로 잘 일어나지 않을 것같은 이상치값은 빼고 분석하는게 좀더 정확하게 파악될수 있습니다. 마치 각 반의 학생들의 키를 확인할 때 최홍만 선수가 끼어 있으면 평균이 확올라가므로 최홍만 선수의 키값은 빼고 계산하면 어느정도 그 반의 키  평균이 정확히 파악되는 것과 같은 문제가 됩니다. 

이렇게 데이터 클린징 작업이 끝났으면 각 데이터의 열을 파악하는 것이 중요합니다. 
즉 데이터 내의 종류를 파악해서 각각의 데이터 종류를 파악하는 것이 좋습니다. 

그래서 열을 확인해보면 

Suburb: 도시 외곽지역 이름 
Address: 주소
Rooms: 방의 갯수
Price: 호주 달러 가격

여기서 잠깐 호주 부동산 거래방법에 대한 알아볼 필요가 있습니다. 호주에서는 크게 우리가 하는 계약, 그리고 경매를 통해 부동산을 넘기는 경우가 있습니다. 부동산 경매는 우리나라에서는 부동산을 가진 사람이 보통 망한 경우에만 사용하는 경우가 빈번한데, 호주에서는 특별히 망하지 않고 보통 특정시기에는 꼭 팔아야 겠다 하고 생각되면 바로 경매에 넣는다고 합니다. 

Method: S - property sold(부동산 판매완료)
            SP - property sold prior(부동산 경매전 판매완료)
            PI - property passed in(부동산 경매 유찰됨 즉 경매에 내놓았는데 팔리지 않음)
            PN - sold prior not disclosed(경매 이전 비공개 판매완료)
            SN - sold not disclosed(비공개 판매완료)
            NB - no bid(팔리지 않으나 경매에 내놓지 않음, 역자추정)
            VB - vendor bid(경매관리인 경매 후 판매)
            W - withdrawn prior to auction(경매중 팔림)
            SA - sold after auction(경매 후 팔림)
            SS - sold after auction price not disclosed. (경매후 비공개판매)
            N/A - price or highest bid not available.

Type: br - bedroom(s) 침실만 렌트
          h - house,cottage,villa, semi,terrace(집 구매)
          u - unit, duplex(복층 구조)
          t - townhouse(타운하우스)
         dev site - development site(개발 지역, 데이터샘플내 없음)
         res - other residential(기타 )

SellerG: Real Estate Agent(부동산 중계인 이름)
Date: Date sold(거래된 날짜)
Distance: Distance from CBD( C.B.D.)(시내로 부터 떨어진 거리)



import pandas as pd
import numpy as np
%matplotlib inline
import seaborn as sns
import matplotlib.pyplot as plt
dataframe =  pd.read_csv("Melbourne_housing_extra_data.csv")
dataframe.head()  ##<-데이터 확인

dataframe["Date"] = pd.to_datetime(dataframe["Date"],dayfirst=True)
## 글자형태의 날짜 데이터를 날짜 데이터로 바꿈 , dayfirst는 영국 및 유럽국가의 중 날짜 먼저쓰는 방식인지 물어보는 것에 true를 적어준것)

len(dataframe["Date"].unique())/4
##len은 리스트 사이즈 구함, .unique() 중복 방지를 의미 . 중복되지 않은 날짜 갯수를 구하고 4로 나눔

var = dataframe[dataframe["Type"]=="h"].sort_values("Date", ascending=False).groupby("Date").std()
var
##데이터 중에 Type이 h 즉 보통 하우스 만 간추려서, Date기준으로 내림차순하여 표준편차를 구하고 그것을 화면에 출력


위와같은 화면이 나옵니다. 

count = dataframe[dataframe["Type"]=="h"].sort_values("Date", ascending=False).groupby("Date").count()
mean = dataframe[dataframe["Type"]=="h"].sort_values("Date", ascending=False).groupby("Date").mean()
#같은 형태로 날짜기준으로 수량, 평균을 구하였습니다.

mean["Price"].plot(yerr=var["Price"],ylim=(400000,1500000))
#가격의 평균값을 날짜별로 그리고, 표준편차를 그림에 표현하여 봤습니다. 




mean["Price"].plot(ylim=(1000000,1500000))
#이번에는 표준편차를 빼고 평균 가격만 날짜별로 정렬하였습니다.


이표를 보았을때는 근교지역이라도 평균 거래 금액이 1년동안 증가되는 추세가 보입니다. 
그리고 특히 2월 8월이 비수기에 속하고 연말이 성수기에 속한다고 할수도 있을 것이라 봅니다. 
하지만 5년정도의 가격 트랜드를 보아야 더 정확하게 이야기 할수 있을것 같습니다. 
이것은 그냥 1년단위므로 일단 그런정도라고 생각하면 될 듯합니다.

means = dataframe[(dataframe["Type"]=="h") & (dataframe["Distance"]<13)].dropna().sort_values("Date", ascending=False).groupby("Date").mean()
#이것은 집 형태가 h이고 시내와 거리가 13키로 이내이며, 결손값은 버린값들만 평균을 내보겠습니다.

errors = dataframe[(dataframe["Type"]=="h") & (dataframe["Distance"]<13)].dropna().sort_values("Date", ascending=False).groupby("Date").std()
#이것은 집 형태가 h이고 시내와 거리가 13키로 이내이며, 결손값은 버린값들만 표준편차을 내보겠습니다.


means["Price"].plot(yerr=errors["Price"])
# 집 형태가 h이고 시내와 거리가 13키로 이내인 집들을 날짜 기준으로 가격평균, 그리고 가격 표준편차를 그래프로 그려보았습니다.


이표를 보면 시내에서 13키로 이내인 집들의 거래 가격이 점점 높아져가고 있다고 보입니다.

pd.set_eng_float_format(accuracy=1, use_eng_prefix=True)
dataframe[(dataframe["Type"]=="h") &
          (dataframe["Distance"]<14) &
          (dataframe["Distance"]>13.7)
          #&(dataframe["Suburb"] =="Northcote")
         ].sort_values("Date", ascending=False).dropna().groupby(["Suburb","SellerG"]).mean()
# 이번에는 지역별, 부동산 중개인별 , 13.7키로 초과 14키로 미만 인 거리의 집들 가격만 평균을 내봤습니다. 다음과 같습니다.





sns.kdeplot(dataframe[(dataframe["Suburb"]=="Northcote")
         & (dataframe["Type"]=="u")
         & (dataframe["Rooms"] == 2)]["Price"])
#kdeplot은 도수분포도를 볼수 있는 그래프를 그려줍니다. 
#따라서 위의 명령어로는 지역이 Northcote이고, 집 타입이 복층형인 방2개인 집의 가격 도수분포도를 볼수 있게 됩니다.


위의 표를 보았을때 가장 많이 일어나는 가격은 60000 호주달러이고 그 기준에 따라서 표준정규 분포를 비슷하게 따른다는 것을 볼수 있게 됩니다.

sns.kdeplot(dataframe["Price"][((dataframe["Type"]=="u") &
                                (dataframe["Distance"]>3) &
                                (dataframe["Distance"]<10) &
                                (dataframe["Rooms"] > 2)#&
                                #(dataframe["Price"] < 1000000)
                               )])
#이번에는 3키로 초과 10키로 미만인 방3개이상인 집들 중 100만 호주 달러 미만의 집들의 가격분포도를 그려봅니다.

3키로 초과 10키로 미만인 방3개이상인 집들 중 100만 호주 달러 미만의 집들의 가격분포도를 보면
평균가격은  7만호주달러가 있고 그 이상으로 거래 했을 경우에는 비싸다 , 그 이하로 거래했을 경우에는 저렴하다고 이야기 할수 
있을것 같습니다. 


sns.lmplot("Distance","Price",dataframe[(dataframe["Rooms"]<=4) &
                                         (dataframe["Rooms"]> 2) &
                                        (dataframe["Type"]=="h") &
                                        (dataframe["Price"]< 1000000)
                                       ].dropna(),hue="Rooms", size=6)

#lmplot은 산포도에 직선을 그어서 추세선을 확인할수 있게 만들어 줍니다. 
#위의 코드는 보통의 집 타입에서, 가격이 100만호주달러 미만이고,
#방의 숫자가 3개와, 4개인 데이터의 가격과 거리 기준으로 산포도를 그린후에 추세선을 그려보아라는 명령어입니다.


위의 그래프는 보통의 집 타입에서, 가격이 100만호주달러 미만이고,
방의 숫자가 3개와, 4개인 데이터의 가격과 거리 기준으로 산포도를 그린후에 추세선을 그린 것입니다.

거리가 멀수록 가격이 싸지는 것은 당연한 이치이고
시내랑 가까울경우에는 방이 3개든 4개든 큰차이가 없음을 시사해줍니다.
따라서 시내 가까운곳일수록 긑은 예산으로 4개의 방을 구해봄도 괜찮을 듯 합니다.



데이터,코드 출처 사이트 :


포스팅은 아래 영문 블로그의 코드를 구현해보고 , 내용을 요약 발췌하여 작성함을 알려드립니다.

따라서 포스팅에 올려지는 모든 그림과 도표 등의 내용은 아래 영문 링크를 들어가셔도 동일하게 보실 있습니다.


Part 1에서 indeed API의 데이터 과학자 및 데이터 분석가 포지션의 정보를 수집하고, jobbR 패키지를 이용해서 간단한 정보비교를 해보았습니다. 
급여는 데이터 과학자가 분석가에 비해 많이 받는것을 알게 되었습니다. 급여 격차를 감안할때 , 각 직군이 요구하는 직무의 차이를 확인할수 있을까요?
만약 가능하다면, 데이터 과학자 역할을 직무설명으로 부터 추출해서 무엇인지를 예측할수 있을까요? 본 포스팅은 이부분을 간단한 자연어 처리를 이용해서 확인해보는 것으로 진행해보도록 하겠습니다. 


데이터 수집

데이터 추출은 part1에서 하였던 것과 유사하게 진행합니다. Indeed API에서 런던의 모든 데이터 과학자 및 데이터 분석가 작업을 추출한다음 , 주니어와 시니어 포지션을 걸러내고 남은 부분을 분석합니다.
본질적으로 part1의 반복이므로 많은 고민을 하지 않고 바로 처리할수 있습니다. 

>install.packages("devtools")
>library(devtools)
>install_github("dashee87/jobbR")
>install.packages("plotly")
>install.packages("dplyr")

우선 아래 코드를 직접 확인하기 위해서는  위와같이 R studio에 입력하여서 패키지를 설치하여야 합니다.


## if you haven't already installed jobbR
# devtools::install_github("dashee87/jobbR")
## loading the packages we'll need

 library(jobbR)
 library(dplyr)
 library(rvest)
 library(stringr)
 library(plotly)

# collecting data scientist jobs from the Indeed API
dataScientists <- jobSearch(publisher = "publisherkey", query = "data+scientist", country = "uk", location = "london", all = TRUE)

# collecting data analyst jobs from the Indeed API
dataAnalysts <- jobSearch(publisher = "publisherkey", query =  "data+analyst", country = "uk", location = "london", all = TRUE)

# removing junior and senior roles
dataScientists <- dataScientists[grepl(
  "data scientist", dataScientists$results.jobtitle,ignore.case = TRUE) &
    !grepl("senior|junior|lead|manage|intern|analyst|graduate|chief",
          dataScientists$results.jobtitle,ignore.case = TRUE),]

dataAnalysts <- dataAnalysts[grepl(
  "data analyst", dataAnalysts$results.jobtitle,ignore.case = TRUE) &
    !grepl("senior|junior|lead|manage|intern|scientist|graduate|chief",
          dataAnalysts$results.jobtitle,ignore.case = TRUE),]

dataScientists <- dataScientists[!duplicated(dataScientists$results.jobkey),]
dataAnalysts <- dataAnalysts[! duplicated(dataAnalysts$results.jobkey),]

install.packages("selectr")
library("selectr")

# scrape job description webpages
ds_job_descripts <- unlist(lapply(dataScientists$results.url,
                              function(x){read_html(x) %>%
                                  html_nodes("#job_summary") %>%
                                  html_text() %>% tolower()}))

da_job_descripts <- unlist(lapply(dataAnalysts$results.url,
                                  function(x){read_html(x) %>%
                                      html_nodes("#job_summary") %>%
                                      html_text() %>% tolower()}))

위의 내용을 실행하시면, 두개의 직무기술서에 대한 벡터를 얻을수 있습니다. 하나의 벡터 내에 있는 element는 단지 여러줄의 단어 나열이나 문장들로 구성되어 있습니다.


# an example data scientist job description
# I picked 49 as it's one of the shorter ones
ds_job_descripts[49]


# [1] "data scientist, python x2\ncentral london\n\n£doe\n\ndata scientists are required by a leading data insights company, based in the city.\n\nthese data scientist opportunities requires those who are able to perform early stage research and development for our clients internal data, in order to help perform discovery and proof of concept in house.\n\nalong with these data scientist positions you<U+0092>ll be expected to design and build software products in python and sql. those who are able to provide a generous like for like comparison will prove highly successful in their application. any agile experience will also be a huge advantage.\n\nto apply for these data scientist roles please send your cv to imogen morpeth at arc it recruitment or call for a consultation\n\ndata scientist, python, sql, proof of concept, data driven research, data stories, numpy, scikit-learn, matplotlib, pandas, statsmodels, seaborn"

위와같이 하나의 element를 뽑아서 보면 단순한 문장과 단어들로 구성되어 있어서 이것을 직접적으로 분석하기에는 무리가 있습니다. 

따라서 여기에서 인사이트를 얻고자 한다면 우리는  bag-of-words 모델을 이용하야합니다. 



간단히 설명하면, 문자열을 특정 관심 단어로 줄이고 각문자열에서 각 단어의 수를 계산합니다. 따라서 이것을 하기 위해 특정 관심단어를 정해야 합니다. 
여기서는 skill이라는 데이터 프레임을 만들었기 때문에 skill내에 존재하는 요소를 48개로 정리해보았습니다. 이것을 아래와 같이 
title에 정리하였고, regex ( regular expression) 는 title에 정리한 열과 유사한 설명들을 적어놓았습니다. 그리하여 regex에 포함된 단어들이 발견되었을 경우에는 
title에 정리된 단어로 count할수 있게끔 정리를 한것입니다. 예를 들면 math는 maths혹은 mathematics와 동일한 것으로 보고 count를 하게끔 한 것입니다.


skills=data.frame(
  title=c("R", "Python", "SQL", "Excel", "Powerpoint", "KPI", "Dashboard",
          "Matlab", "Tableau", "Qlikview", "D3", "SAS", "SPSS", "BI", "C++",
          "Java", "Javascript", "Ruby", "Scala", "Php", "VBA",
          "Machine Learning", "Big Data", "Modelling", "Communication",
          "Stakeholder", "Masters", "PhD", "Hadoop", "Spark", "Map Reduce",
          "Pig", "Hive", "NoSQL", "MongoDB", "Cassandra", "Mahout",
          "Google Analytics", "Adobe", "API", "NLP", "Maths", "Statistics",
          "Physics", "Computer Science", "Engineering", "Economics",
          "Finance"),
  regex=c("r", "python|numpy|pandas|scikit", "sql|mysql|sql server|mssql",
          "excel","powerpoint|power point", "dashboards?", "kpis?",
          "matlab", "tableau", "qlikview", "d3", "sas", "spss",
          "bi|business intelligence", "c\\+\\+|c/c\\+\\+", "java",
          "javascript", "ruby", "scala", "php", "vba?|visual basic",
          "machine learning", "big data", "modelling|modeling",
          "communication", "stakeholders?", "masters?|msc","phd", "hadoop",
          "spark", "map reduce|mapreduce|map/reduce", "pig", "hive", "nosql",
          "mongodb", "cassandra", "mahout","google analytics|GA|big query",
          "adobe", "apis?", "nlp|natural language", "math?s|mathematics",
          "statistics|biostatistics", "physics", "computer science",
          "engineering", "economics", "finance"),
  stringsAsFactors = FALSE)

# count number of occurences of each word in the skills dataframe in
# the data science job descriptions
ds_occurs <- matrix(unlist(lapply(skills$regex,
                                function(x){str_count(ds_job_descripts,
                                                      paste0("\\b", x, "\\b"))})),
                  length(ds_job_descripts), length(skills$title))

# count number of occurences of each word in the skills dataframe in
# the data analyst job descriptions
da_occurs <- matrix(unlist(lapply(skills$regex,
                                function(x){str_count(da_job_descripts,
                                                      paste0("\\b", x, "\\b"))})),
                  length(da_job_descripts), length(skills$title))



그리하여 ds_occurs는 데이터 사이언티스트의 빈도수, da_occurs는 데이터 분석가의 빈도수를 측정하였습니다.
그래서 각 string에 해당되는 내용중에 math의 빈도수를 기록하여서 48개의 열에 그 빈도수를 기록하였습니다. 
하지만 한 string에서 math가 5번 나왔다고 math의 중요도가 높아지는 것은 아니므로, 
각 string에서 출현을 했다 혹은 안했다로만 확인하기 위해서 이진 행렬 (bineary matrix)로 바꿔야 합니다. 
그 작업은 아래와 같이 진행합니다. 


ds_occurs <- ifelse(ds_occurs>1, 1, ds_occurs)
da_occurs <- ifelse(da_occurs>1, 1, da_occurs)

그리하여 각 string별 skill 출현 빈도에 대한 그래프를 아래와 같이 그릴수 있습니다. 


plot_ly(rbind(data.frame(job = "Data Scientist",
                        skills = skills$title,
                        prop = round(
                          100*apply(ds_occurs, 2, sum)/nrow(ds_occurs), 2)),
              data.frame(job = "Data Analyst",
                        skills = skills$title,
                        prop = round(
                          100*apply(da_occurs, 2, sum)/nrow(da_occurs), 2))),
        x = ~skills, y = ~prop, color= ~job, type = 'bar') %>%
  layout(margin = list(b = 109),
        xaxis = list(title = "", tickfont = list(size = 12)),
        yaxis = list(title =
                        "<b>Appearance in Job Description (% Job Postings)</b>",
                      titlefont = list(size = 16)),
        title = "<b>Job Description Skills: Data Scientist v Data Analyst</b>",
        titlefont = list(size=17)) %>%
  layout(legend=list(font = list(size = 16))) %>%
  layout(autosize = F, width = 1200, height = 800)

\



그래프를 확인해보면 데이터 과학자와 데이터 분석가의  skill 에 대한 내용이 크게 다르다는 것을 알수 있습니다. . 파이썬과 R을 데이터 과학자들에게 가장 일반적으로 요구되는 skill로 나타나는 것이 흥미 롭습니다.
Excel은 데이터 분석가가 가장 많이 사용하는 기술이며 SQL을 밀접하게 따르고 있습니다. 사실, SQL은 두 가지 직종 모두에서 비교적 높은 빈도로 나타납니다.
 
따라서 데이터 과학 / 분석을 배우려는 경우 SQL을 먼저 배워보는 것도 좋은 선택이라고 할수 있을 것입니다. 

또한 위의 그래프를 보면 막대 그래프는 일반적으로 데이터 분석가 그룹에서 훨씬 작은 횟수로 나타납니다.
즉 우리가 정의한 48가지 skill set에 해당되는 내용이 데이터 분석가 그룹의 내용에는 상대적으로 적은 횟수로 나타났다는 것입니다. 이것은 아래와 같이 직업 설명별로 언급 된
다양한 skill의 가짓수를 누적 분포를 통해 그래프를 그려볼수 있습니다. 

ggplot(rbind(data.frame(type = "Data Scientist",
                        num_skills = apply(ds_occurs,1,sum)),
            data.frame(type = "Data Analyst",
                        num_skills = apply(da_occurs,1,sum))),
      aes(num_skills, colour = type)) + stat_ecdf(size = 1) +
  geom_text(size=8, aes(20, .3, label = "Data Analyst", color = "Data Analyst")) +
  geom_text(size=8, aes(20, .2, label = "Data Scientist", color= "Data Scientist")) +
  labs(title = "# Skills in Job Description: Data Analysts vs Data Scientists",
      x = "Number of Skills", y = "Cumulative Proportion") +
  theme(axis.title = element_text(size = 14,face = "bold"),
        plot.title = element_text(size = 16,face = "bold"), legend.position = "none",
        axis.text = element_text(size = 11))

아래 그래프를 확인하면 데이터 분석가는 5개 미만의 skill만 가지고 있어도 70%의 구인광고에 지원을 해볼수 있겠지만,
데이터 과학자는 5개의 skill로는 고작 15%의 구인광고에 지원을 해볼수 있게 됩니다. 즉 데이터 과학자에게 요구하는 수준이 상대적으로 데이터 분석가보다 많다는 것을 나타내는 그래프라고 할수 있습니다. 







안녕하세요.

github에서는 매우 훌륭한 코드와 이를 공개해주신 많은 훌륭하신 분들이 계시는데요, 오늘은 그분들 중에 

dashee87 유저명을 쓰시는 David Sheehan께서 만드신 indeed API를 활용한 데이터 크롤링 R함수를 분석해보도록하겠습니다. 

우선 Rstudio에서 아래와 같이 패키지를 설치하셔야 합니다. 


>install.packages("devtools")
>library(devtools)
>install_github("dashee87/jobbR")


이후에 R 스튜디오 에서 jobsearch라는 함수를 보시면 api를 이용해서 데이터 크롤링을 할수 있는 함수를 직접확인하실수 있습니다. 


> jobSearch
function (publisher, query, country = "us", location = "", radius = 25,
    sort = c("relevance", "date"), start = 0, limit = 10, all = FALSE,
    latlong = "", fromAge = "", st = "", jt = "", filter = "",
    userip = "1.2.3.4", version = 2, userAgent = "Mozilla/%2F4.0%28Firefox%29",
    callback = "", highlight = "", chnl = "")
{
    sort <- match.arg(sort)
    if (!all) {
        url <- paste0("http://api.indeed.com/ads/apisearch?publisher=",
            publisher, "&q=", query, "&l=", location, "&latlong=",
            latlong, "&userip=", userip, "&useragent=", userAgent,
            "&format=json&start=", start, "&radius=", radius,
            "&st=", st, "&jt=", jt, "&fromage=", fromAge, "&limit=",
            limit, "&highlight=", highlight, "&filter=", filter,
            "&callback=", callback, "&co=", country, "&sort=",
            sort, "&chnl=", chnl, "&v=", version)
        as.data.frame(jsonlite::fromJSON(httr::content(httr::GET(url),
            as = "text", encoding = "UTF-8")))
    }
    else {
        url <- paste0("http://api.indeed.com/ads/apisearch?publisher=",
            publisher, "&q=", query, "&l=", location, "&latlong=",
            latlong, "&userip=", userip, "&useragent=", userAgent,
            "&format=json&start=", 0, "&radius=", radius, "&st=",
            st, "&jt=", jt, "&fromage=", fromAge, "&limit=",
            25, "&highlight=", highlight, "&filter=", filter,
            "&callback=", callback, "&co=", country, "&sort=",
            sort, "&chnl=", chnl, "&v=", version)
        first_jobs <- jsonlite::fromJSON(httr::content(httr::GET(url),
            as = "text", encoding = "UTF-8"))
        jobs_lists <- lapply(seq(0, max(first_jobs$totalResults),
            25), function(x) {
            url <- gsub("start=0", paste0("start=", x), url)
            as.data.frame(jsonlite::fromJSON(httr::content(httr::GET(url),
                as = "text", encoding = "UTF-8")))
        })
        jsonlite::rbind.pages(jobs_lists)
    }
}
<environment: namespace:jobbR>


보시다싶이 데이터 크롤링을 하기 위한 agent로 파이어폭스를 이용하였습니다. 따라서 파이어 폭스를 설치하시지 않으면 위의 함수는 작동하지 않습니다. 
또한 나머지 규격은 indeed api가 정해놓은 규격대로 설정을 했습니다. 


에 들어가셔서 api를 위한 id를 만들고 그것을 publisher로 등록하면 publisher key를 발급해줍니다. 



ID를 만들고 로그인을 하게 되면 아래와 같은 화면을 확인하실수 있습니다. 




여기서 드래그를 하다보면 아래와 같이 publisher key발급한 내용을 확인하실수 있습니다. 

총 16자리 숫자로 그숫자를 이용하여서 자료를 긁어올수 있도록 할수 있습니다. 



따라서 위와같이 publisher key를 발급하고, 파이어폭스를 설치하시면 아래와 같이 jobsearch라는 함수를 이용해서 아래와 같이 데이터를 크롤링할수 있습니다. 


> dataScientists <- jobSearch(publisher = "XXXXXXXXX582", query = "data+scientist", country = "uk", location = "london",all = TRUE)

##  XXXXXXXXX582 대신하여 여러분의 키값을 넣으세요 



확인하시고 다른 사이트의 API를 이용해서 데이터를 가지고 오실때 참조하시면 좋을 것같습니다. 

감사합니다. 


데이터 과학자 VS 데이터 분석가



포스팅은 아래 영문 블로그의 내용을 요약 발췌하여 작성함을 알려드립니다.

따라서 포스팅에 올려지는 모든 그림과 도표 등의 내용은 아래 영문 링크를 들어가셔도 동일하게 보실 있습니다.

http://www.kdnuggets.com/2016/11/data-scientists-vs-data-analysts-part-1.html


 빅데이터 분야에서 데이터 과학자와 데이터 분석가에 대한 구분은 끊임없이 존재하였으나, 부분을 명확하게 나누어 이야기 하는 사람은 많지 않았습니다. 그래서 David Sheehan 작성한 블로그 내용을 기반으로 데이터 과학자와 데이터 분석가에 대한 구분을 해보도록 하겠습니다


데이터 과학자의 일반적인 기술이라고 하면 파이썬과 R 대표적으로 이야기 할수 있습니다. 하지만 데이터 과학자의 업무와 유사한 데이터 분석가의 업무에 대해서 어떻게 차이가 나는지 정량적인 분석을 통해 비교를 해보려고 합니다.

정량적인 분석을 위해서 해외 구직사이트 indeed 사이트의 데이터를 분석하고자 합니다. Indeed 무료이며 간단한 api 가지고 있습니다 이름과 이메일만 있다면 API 쿼리 하는 것은 크게 어렵지 않다고 합니다.

David Sheehan 런던의 데이터 과학자와 데이터 분석가의 직업을 아래와 같이 비교하였습니다.

---------------------------------------------------------------

## if you haven't already installed jobbR

# devtools::install_github("dashee87/jobbR")


## loading the packages we'll need

require(jobbR)

require(ggplot2)


# collecting data scientist jobs in London from the Indeed API

dataScientists <- jobSearch(publisher = "yourpublisherID", query = "data+scientist",

country = "uk", location = "london", all = TRUE)


# collecting data analyst jobs in London from the Indeed API

dataAnalysts <- jobSearch(publisher = "yourpublisherID", query = "data+analyst",

country = "uk", location = "london", all = TRUE)

---------------------------------------------------------------

이렇게 indeed데이터를 api 통해서 긁어오면 모든 데이터가 데이터 과학자 혹은 데이터 분석가 있는 것은 아닙니다.

철자의 유사성으로 인해서 연구과학자 (research Scientist) 등과 초급 증군 인턴등의 자리 또한 제외할수 있도록 프로그램을 작성해봅니다.

---------------------------------------------------------------

# removing junior and senior roles

dataScientists <- dataScientists[grepl("data scientist",dataScientists$results.jobtitle,

ignore.case = TRUE) & !grepl("senior|junior|lead|manage|intern|analyst|graduate",

dataScientists$results.jobtitle,ignore.case = TRUE),]


dataAnalysts <- dataAnalysts[grepl("data analyst", dataAnalysts$results.jobtitle,

ignore.case = TRUE) & !grepl("senior|junior|lead|manage|intern|scientist|graduate",

dataAnalysts$results.jobtitle,ignore.case = TRUE),]

---------------------------------------------------------------

API 문서에 의해 중복문서가 없다고 예상할 있지만, 데이터의 품질을 높이기 위해서 데이터를 중복 제거하도록 후처리 해봅니다.

---------------------------------------------------------------

dataScientists <- dataScientists[! duplicated(dataScientists$results.jobkey),]
dataAnalysts <- dataAnalysts[! duplicated(dataAnalysts$results.jobkey),]

---------------------------------------------------------------

결과를 정리해서 아래와 같이 수량을 우선 나타내어 봅니다.

---------------------------------------------------------------

# number of job posts per role
lapply(list(dataScientists, dataAnalysts), nrow)

--------------------------------------------------------------------------

## [[1]]
## [1] 188
##
## [[2]]
## [1] 202


새롭게 대두된 데이터 과학자가 어렵고 기술적이기 때문에 아주 많이 차이가 것이라고 예상했음에도 불구하고,

위의 결과는 데이터 과학자와 데이터분석가보다 조금 적게 나왔음을 확인할 있습니다. 데이터 과학자의 구인이 생각보다 많다는 것을 확인했다고 할수 있습니다.


월급비교


Indeed APi 월급에 대한 정보를 제공하지 않습니다. 그래서 JobbR 패키지를 활용해서 직업설명에 나타나 있는 월급여 설명 부분을 긁어모아서 데이터를 모아보았습니다.

물론 어떠한 광고도 정확한 월급을 적어놓지는 않았지만 대략적인 파악은 가능하다고 생각하고 데이터를 모았습니다.

---------------------------------------------------------------
# get salary figures for all data scientist positions
dsSalary <- lapply(dataScientists$results.url, function(x)getSalary(x,"GBP"))
dsSalary <- do.call(rbind, dsSalary)
# get salary figures for all data analyst positions
daSalary <- lapply(dataAnalysts$results.url, function(x)getSalary(x,"GBP"))
daSalary <- do.call(rbind, daSalary)
# quick look at our salary dataset
head(daSalary)
---------------------------------------------------------------
##      status  period currency minSal maxSal
## 1 Permanent    year      GBP  27000  30000
## 2   unknown unknown      GBP     NA     NA
## 3 Permanent    year      GBP  32042  36548
## 4   unknown unknown      GBP     NA     NA
## 5   unknown unknown      GBP     NA     NA

## 6 Permanent    year      GBP  45000  50000



프로그래밍이 완벽하지 않아서 데이터 결손치 NA 많이 있음을 확인할수 있습니다. 따라서 결손치를 제외하고 연봉부분만 발췌하면 아래와 같이 결과를 확인할수 있습니다.

---------------------------------------------------------------
# filtering out jobs with no advertised salary or retaining those with annual salaries
dsSalary <- dsSalary[! is.na(dsSalary$minSal) & dsSalary$period=="year",]
daSalary <- daSalary[! is.na(daSalary$minSal) & daSalary$period=="year",]
# number of positions with an advertised annual salary
lapply(list(dsSalary, daSalary), nrow)
---------------------------------------------------------------
## [[1]]
## [1] 69
##
## [[2]]
## [1] 75




또한 연봉의 최저값과 최고값의 범위를 광고하는 구인광고가 많으므로 , 중간값을 대표값으로 지정하여 데이터를 분석하고자 합니다.

dsSalary$Sal <- mapply(function(x,y){(x+y)/2}, dsSalary$minSal, dsSalary$maxSal)
daSalary$Sal <- mapply(function(x,y){(x+y)/2}, daSalary$minSal, daSalary$maxSal)


모든 데이터가 확보된 상태라서 아래와 같이 기본적인 그래프를 그려보았습니다.

.

dsSalary$type <- "Data Scientist"
daSalary$type <- "Data Analyst"
ggplot(rbind(dsSalary, daSalary), aes(Sal, colour = type)) + stat_ecdf(size = 1) +
geom_text(size=8, aes(100000, .3, label = "Data Analyst", color = "Data Analyst")) +
geom_text(size=8, aes(100000, .2, label = "Data Scientist", color= "Data Scientist")) +
labs(title = "Annual Salary: Data Analysts vs Data Scientists",
x = "Annual Salary (GBP)", y = "Cumulative Proportion") +
theme(axis.title = element_text(size = 14,face = "bold"),
plot.title = element_text(size = 16,face = "bold"), legend.position = "none",
axis.text = element_text(size = 11))


아래 그림은 누적 분포도를 표현한것이며, 도표를 보면 데이터 분석가가 데이터 과학자보다 적은 연봉을 받는다는 것을 확인할수 있습니다.


특히 데이터 과학자 중간지점은 6만파운드 가르키는데 반면, 데이터 분석과는 3만파운드 미만을 지나고 있어 월급차이가 극명하게 난다고 이야기 할수 있습니다.


Indeed API (jobbR 패키지 사용)에서 작업 데이터를 추출하고 정리하여 간단한 그래프를 작성하여 데이터 과학자와 데이터 분석가 간의 급여 격차를 보여주었습니다.

 2 부에서는 직무 기술에 초점을 두고 자연어 처리기술을 사용하여 자신의 광고 기술 세트를 기반으로 데이터 과학자 데이터 분석가 위치를 예측하고자 합니다.


블로그 포스팅 저작자의 사이트는 아래와 같습니다.

https://dashee87.github.io/data%20science/data-scientists-vs-data-analysts-part-1



해외 블로거의 포스트를 기반으로 간단한 분석과 데이터를 이용해서 그래프를 그린 것을 보고 흥미롭다는 생각을 하게 됩니다.

R 적재적소에 쓰는 모습이 타의 귀감이 되어서 저에게 의미가 되었던 글이 아니었나 싶습니다.


+ Recent posts