大數據時代,哪些課程最受歡迎?
大數據時代,數據的體量結構、獲取方式、挖掘處理、分析呈現等等方面都發生了變化,由此衍生出大數據技術,包括數據的採集、存取、清洗、挖掘、可視化等等,產生了新的人才需 求,並且處於緊缺狀態,來自麥肯錫全球研究所的另一項調查顯示,預計到2018年,美國將面臨大約150萬大數據專家的短缺,據國內大數據權威專家估算,5年內,大數據人才缺口也將高達130萬左右。巨大的人才需求、仍處於上升階段的職業前景也導致了大數據培訓的火熱,目前在在線課堂、論壇、線下機構紛紛開設大數據方向的培訓課程,且應者如雲。那麼哪些課程或者哪些方向最受歡迎呢?本文以ppv課(國內領先的大數據學習社區)網站為例,該網站的免費課程頻道有著較為齊全課程分類(見圖1),並且積累了一定的用戶學習數據。通過python軟體(3.X版本)爬取所有課程的學習人數、時長、類別等網路數據(見圖2),可以一窺當前大數據時代學習群體的培訓需求。
圖1 ppv課免費課程
圖2 每個課程的信息
採用p ython的xpath查詢和處理 HTML / XML 文檔,針對網頁鏈接與翻頁特點,構建函數以及數據清洗等,最終獲取如下數據:
圖3 最終獲取的數據形式
再通過數據截取、封裝、可視化處理,得到了每一課程類目下的平均學習人數(類目下所有課程學習人數相加/該類目課程數量),見下圖:
圖4 每一課程類目的平均學習人數
如圖,概率與統計課程的平均學習人數最多,達到3000以上,這說明學習者對大數據的基礎統計理論的學習需求較大;其次是R語言、Mysql、SPSS等,說明了大數據常用的軟體與資料庫的學習需求也較高。
分類比較,比如在大數據統計軟體方面的平均學習人數上,由上圖可以看出,R語言>SPSS>Python>SAS>Excel>Matlab,後三者在大數據統計技術上已稍顯落後(spss在開發出數據挖掘模塊),且R、Python是目前大數據分析下最火的兩大統計軟體,相應的學習需求也高;資料庫方面:Mysql>Nosql>Sql>Oracle,Mysql平均學習人數最多且遠遠超過其他資料庫,作為大數據目前最常用的資料庫存儲工具,因此會獲得如此高的關注度;理論方面:概率統計>機器學習>數據挖掘,說明學習者對基礎理論的需求還是比較高,由於大數據技術是計算機與數據統計等內容的結合,很多計算機從業者缺乏統計理論知識以及初學者也要從最基礎的理論學起,這導致概率與統計的學習需求遙遙領先,從側面也說明了在大數據領域統計理論的缺失或不足較為明顯。對於大數據里較火的軟體平台——Hadoop,平均學習人數處於不高不低的狀態,這是由於大多數大數據學習者還處於初級水平,對Hadoop這一高級應用技術還缺乏了解,所以學習需求沒那麼高。
我們還可以獲取到每一課程類目下的所有課程的學習人數,如SAS類目所有的課程學習人數:
圖5 SAS類目所有的課程學習人數
從上圖可以看出,關於初級、入門類的課程需求還是最高。
那麼,課程學習人數與課程時長有無關聯?構造所有課程學習人數與學習時長的散點圖:
圖6 課程學習人數與學習時長的散點圖
可以看到二者並無明顯的相關關係。
我們還可以將所有課程按照職業方向、難以程度來分類,獲取相關信息,如不同職業方向平均課程學習人數的佔比情況:
圖7 不同職業方向平均課程學習人數的佔比情況
數據分析師、大數據工程師、數據挖掘工程師三大方向的學習需求並無明顯差異,其中數據分析師略佔優勢,說明對於數據分析的學習需求較高。
綜合看來,大數據時代學習者對於初級、入門課程的關注度還是比較高,對於常用的軟體R、Python以及統計、數據分析的學習需求相對集中。
附:對網頁抓取的流程與代碼:
(1)導入相關庫並構建網頁解析函數
裝入網頁解析、多線程、數值計算、數據可視化等python安裝庫,並構造網頁解析函數,在函數中設置模仿瀏覽器登錄的head方式:
import urllib.request
from lxml importetreeimport pandas as pdfrom multiprocessing.dummy import Poolas threadspoolimport urllib,re,timeimport numpy as npimport matplotlib.pyplot as plt
start_url=選課中心 - PPV課大數據培訓專家url_host = 選課中心 - PPV課大數據培訓專家def url_open(url):#構建網頁解析函數 req = urllib.request.Request(url) req.add_header(User-Agent,Mozilla/5.0(Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22Safari/537.36 SE 2.X MetaSr 1.0) page = urllib.request.urlopen(req)#模仿瀏覽器登錄 txt = page.read().decode(utf-8) htm = etree.HTML(txt)return htm(2)構建每一類目鏈接獲取函數
獲取每個類目的鏈接,也就是圖1中機器學習、數據挖掘等14個類目的鏈接,構建每個類目鏈接獲取的函數:
def get_class_link(url):#獲取每個類目的鏈接 htm = url_open(url) class_topics = htm.xpath(/html/body/div[2]/div[1]/div[1]/dl[1]/dd/a/text())[1:-1]#對課程類目的網址進行解析,並且去除一頭一尾「全部」與「會員課程」 class_link =[] for class_topic in class_topics: class_link.append(url_host + urllib.parse.quote(class_topic))#主要解決部分網址包含中文字元無法解碼的問題 return class_link
在免費課程主頁:選課中心 - PPV課大數據培訓專家,點擊對應的課程類目右鍵審查元素就可以獲取相應的鏈接,該網站課程類目鏈接採取這樣的方式:http://www.ppvke.com/class/select?topicid=機器學習,即在主頁的基礎上加入topicid=的形式。在這裡需要注意,部分類目包含中文字元,如機器學習、數據挖掘、R語言等,在python網頁解析中會出現「ASCII碼無法識別的問題」,導致程序運行不出,這時需要加入urllib.parse.quote命令進行編碼,使得中文字元識別出來,(英文字元在此命令下不受影響)。
(3)構建全部鏈接獲取函數,解決翻頁問題
再次,構建全部鏈接抓取函數。由於部分課程類目不止一頁,需要對翻頁的鏈接進行抓取,這時候我們需要解決兩個問題:一是每個類目有多少翻頁?二是翻頁鏈接的形式是什麼樣的,有無規律可循?在課程的底端可以看到每個類目的頁數:
對於多頁的課程類目鏈接形式為(以Excel為例):
選課中心 - PPV課大數據培訓專家
可以看到在課程類目的鏈接上加入了「&job=&grade=&page=&page=」這種形式。根據這兩個問題的表現形式我們找到了解決方案,對於每個類目的頁數問題,通過抓取「上一頁」、「下一頁」這個框中的列表長度來判斷,如只有第一頁保持原有鏈接不變,如有2個以上頁面,則在原始鏈接的列表中加入page=2/3….的鏈接形式。最後封裝成一個列表。
def get_all_links(class_link):#每個課程類目有不止一頁,因此鏈接也有多個,因此基於類目鏈接構建全部鏈接函數 htm = url_open(class_link) page_num=htm.xpath(/html/body/div[2]/div[1]/div[2]/div[3]/div/a/text()) urls = [class_link] if len(page_num)>2: for i in range(2,len(page_num)): urls.append(class_link + &job=&grade=&page=&page=+str(i))#將翻頁鏈接依次加入類目鏈接中 else: pass return urls
(4)構建抓取信息函數
接下來就開始抓取每個頁面的信息,並採用pandas.DataFrame的數據框,採用Xpath方式抓取。
def get_info(url):#抓取每個鏈接的信息,包括課程名稱、時長、學習人數、類目 htm = url_open(url) titles = htm.xpath(/html/body/div[2]/div[1]/div[2]/div[2]/ul/li/h3/a/text()) times= htm.xpath(/html/body/div[2]/div[1]/div[2]/div[2]/ul/li/p[1]/text()) numbers = htm.xpath(/html/body/div[2]/div[1]/div[2]/div[2]/ul/li/p[1]/span/text()) topic = htm.xpath(/html/body/div[2]/div[1]/div[1]/dl[1]/dd[@class="cur"]/a/text()) topics = topic * len(titles) #獲取每個課程的類目變數,並且與每個課程一一對應,最好與其他變數在同一頁面一起抓取 frame = pd.DataFrame([topics,titles,times,numbers], index=[topics,titles,times,numbers])#轉入數據列表DataFrame frame = frame.T return frame
(5)導入網頁,爬取信息
構造完相關函數後,將參數代入,爬取所有類目下所有課程的數據信息:
if __name__ == __main__: time.sleep(2) class_links = get_class_link(start_url)#獲取類目鏈接 pool = threadspool(2) urls = list(map(get_all_links,class_links))#多線程抓取每個類目的所有鏈接 url_links = [] for x in urls: url_links.extend(x) #將所有鏈接裝進一個list frame_list = list(map(get_info,url_links))#數據框列表 a,b,c,d = [], [], [], [] [(a.extend(x[topics])) for x in frame_list] [(b.extend(x[titles])) for x in frame_list] [(c.extend(x[times])) for x in frame_list] [(d.extend(x[numbers])) for x in frame_list] c1 = [int(re.findall(r"d+" ,txt)[0]) for txt in c] d1 = [int(re.findall(r"d+" ,txt)[0]) for txt in d] #採用正則表達式提取數字,並轉化為整型,也算是數據清洗 frame = pd.DataFrame([a,b,c1,d1], index=[topics,titles,times,numbers])#將數據整合 frame = frame.T
(6)數據截取、分組及可視化
通過數據截取、分組計算、畫圖就可以得到每個類目平均的學習人數:
ppv = frame.loc[:,[topics,numbers]]#獲取部分數據,即數據切片ppv1 = ppv.groupby(topics).sum()print(ppv1)ppv2 = ppv.groupby(topics).count()ppv3 = ppv1/ppv2print(ppv3)ppv3.plot(kind=bar)#直方圖,注意中文變數剛開始無法在圖形中顯示,需要設置python的輸入法庫plt.show()frame1 = frame.set_index(topics)ax = frame1.loc[SAS, [titles, numbers]]bx = ax.plot(kind=barh)bx.set_yticklabels(ax[titles], rotation=0)plt.show()frame.plot(x=times, y=numbers, kind=scatter, color=g)plt.show()
與上面類似,我們也可以抓取大數據職業方向方面課程的學習情況:
job_urls = []for job in [1,3,8]: for page in range(1,14): list_view = http://www.ppvke.com/class/select?topicid=&job={}&grade=&page={}.format(str(job),str(page)) page = urllib.request.urlopen(list_view) txt = page.read().decode(utf-8) if txt.find(暫無課程) == -1:#直接設置一定的頁面鏈接,通過頁面顯示的信息有誤來篩選鏈接 job_urls.append(list_view) else: passdef get_info1(url): page = urllib.request.urlopen(url) txt = page.read().decode(utf-8) htm = etree.HTML(txt) titles = htm.xpath(/html/body/div[2]/div[1]/div[2]/div[2]/ul/li/h3/a/text()) times = htm.xpath(/html/body/div[2]/div[1]/div[2]/div[2]/ul/li/p[1]/text()) numbers = htm.xpath(/html/body/div[2]/div[1]/div[2]/div[2]/ul/li/p[1]/span/text()) topic = htm.xpath(/html/body/div[2]/div[1]/div[1]/dl[2]/dd[@class="cur"]/a/text()) topics = topic * len(titles) frame = pd.DataFrame([topics, titles, times, numbers], index=[topics, titles, times, numbers]) frame = frame.T time.sleep(2) return frame
在這裡與前邊不同的是,在抓取全部頁面的時候,沒有採用上面以頁面底端的「上一頁」、「下一頁」信息來判斷頁面數量並構造鏈接,而是輸入一個能涵蓋每一類別最大頁數的數字(如14,這裡是翻遍類目最後頁數確定下來的),再通過解析頁面信息是否存在課程數據來篩選,採用了if txt.find(暫無課程) == -1:的條件循環。
frame_list = list(map(get_info1,job_urls))a,b,c,d = [], [], [], [][(a.extend(x[topics])) for x in frame_list][(b.extend(x[titles])) for x in frame_list][(c.extend(x[times])) for x in frame_list][(d.extend(x[numbers])) for x in frame_list]c1 = [int(re.findall(r"d+" ,txt)[0]) for txt in c]d1 = [int(re.findall(r"d+" ,txt)[0]) for txt in d] #採用正則表達式提取數字,並轉化為整型frame = pd.DataFrame([a,b,c1,d1], index=[topics,titles,times,numbers])frame = frame.Tjob_study = frame.loc[:, [topics, numbers]]job_study1 = job_study.groupby(topics).sum()job_study2 = job_study.groupby(topics).count()job_study3 = job_study1/job_study2print(job_study2)print(job_study3)job_study = frame.loc[:, [topics, numbers]]job_study1 = job_study.groupby(topics).sum()job_study2 = job_study.groupby(topics).count()job_study3 = job_study1/job_study2print(job_study2)print(job_study3)job_study3.plot(subplots=True,kind = pie,colors=[r, g, b],autopct=%.2f,fontsize=10, figsize=(5,5))plt.legend(loc =lower left)plt.show()
推薦閱讀: