- 來源 | 願碼(ChainDesk.CN)內容編輯
- 願碼Slogan | 鏈接每一個程序員的故事
- 網站 | http://chaindesk.cn
- 願碼願景 | 打造全學科IT系統免費課程,助力小白用戶、初級工程師0成本免費系統學習、低成本進階,幫助BAT一線資深工程師成長並利用自身優點創造睡後收入。
- 官方公衆號 | 願碼 | 願碼服務號 | 區塊鏈部落
- 免費加入願碼全思惟工程師社羣 | 任一公衆號回覆「願碼」兩個字獲取入羣二維碼
本文閱讀時長:10minhtml
在本文中,咱們將探討如何利用Python的強大功能來收集和處理來自GitHub的數據並使其準備好分析。git
GitHub採用普遍使用的版本控制方法,經過在編程領域實現社交網絡功能,將編碼提高到最高水平。GitHub容許您建立代碼存儲庫並提供多種協做功能,錯誤跟蹤,功能請求,任務管理和維基。它擁有大約2000萬用戶和5700萬個代碼庫(來源:維基百科)。這些統計數據很容易證實這是程序員最具表明性的平臺。它也是幾個開源項目的平臺,這些項目爲軟件開發領域作出了巨大貢獻。假設GitHub使用了最新的編程工具和技術,分析GitHub能夠幫助咱們檢測最流行的技術。存儲庫在GitHub上的受歡迎程度是經過它從社區收到的提交數量來評估的。咱們將在本文中使用GitHub API來收集具備最多提交數量的存儲庫的數據,而後發現其中最流行的技術。程序員
GitHub API容許咱們獲取有關用戶提交的公共代碼存儲庫的信息。它涵蓋了許多開源,教育和我的項目。咱們的重點是找到過去幾個月的趨勢技術和編程語言,並與過去幾年的存儲庫進行比較。咱們將收集有關存儲庫的全部元信息,例如:github
咱們將使用這些數據,定性和定量信息的組合,來識別最新趨勢和微弱信號。該過程能夠經過下圖中顯示的步驟表示:
web
在使用API以前,咱們須要設置受權。API容許您訪問全部公開可用的數據,但某些端點須要用戶權限。您可使用應用程序設置建立具備某些特定範圍訪問權限的新令牌。範圍取決於您的應用程序的需求,例如訪問用戶電子郵件,更新用戶配置文件等。 密碼受權僅在某些狀況下須要,例如用戶受權的應用程序訪問。在這種狀況下,您須要提供用戶名或電子郵件以及密碼。
全部API訪問均經過HTTPS進行,並可從https://api.github.com/ 域訪問。全部數據都以JSON的形式發送和接收。數據庫
GitHub Search API旨在幫助查找特定項(存儲庫,用戶等)。速率限制策略容許每次搜索最多1,000個結果。對於使用基自己份驗證,OAuth或客戶端ID和密鑰的請求,您每分鐘最多能夠發出30個請求。對於未經身份驗證的請求,速率限制容許您每分鐘最多發出10個請求。編程
GitHub提供了一個搜索端點,它返回與查詢匹配的全部存儲庫。隨着咱們的進展,在分析的不一樣步驟中,咱們將更改變量q(查詢)的值。在第一部分中,咱們將檢索自2017年1月1日以來建立的全部存儲庫,而後咱們將比較前幾年的結果。json
首先,咱們初始化一個空列表結果,該結果存儲有關存儲庫的全部數據。其次,咱們使用API所需的參數構建get請求。咱們每一個請求只能得到100個結果,所以咱們必須使用分頁技術來構建完整的數據集。api
results = [] q = "created:>2017-01-01" def search_repo_paging(q): url = 'https://api.github.com/search/repositories' params = {'q' : q, 'sort' : 'forks', 'order': 'desc', 'per_page' : 100} while True: res = requests.get(url,params = params) result = res.json() results.extend(result['items']) params = {} try: url = res.links['next']['url'] except: break
在第一個請求中,咱們必須將全部參數傳遞給請求中的方法。而後,咱們爲每一個下一頁建立一個新請求,能夠在連接中找到包含全部其餘參數的資源的完整連接。這就是咱們清空params詞典的緣由。
GET res.links'next'. res. 網絡
重複該操做,直到字典中沒有下一頁鍵。對於其餘數據集,咱們修改搜索查詢的方式是從前幾年檢索存儲庫。例如,要從2015年獲取數據,咱們定義如下查詢:res.links
q = "created:2015-01-01..2015-12-31"
爲了找到合適的存儲庫,API提供了大量的查詢參數。使用限定符系統能夠高精度地搜索存儲庫。從主搜索參數q開始,咱們有如下選項:
固然,搜索參數q 能夠包含多個限定符組合。
咱們經過GitHub API收集的數據量使其適合內存。咱們能夠直接在pandas數據幀中處理它。若是須要更多數據,咱們建議將其存儲在數據庫中,例如MongoDB。
咱們使用JSON工具將結果轉換爲乾淨的JSON並建立數據幀。
from pandas.io.json import json_normalize import json import pandas as pd import bson.json_util as json_util sanitized = json.loads(json_util.dumps(results)) normalized = json_normalize(sanitized) df = pd.DataFrame(normalized)
數據框df 包含與GitHub API返回的全部結果相關的列。咱們能夠經過輸入如下內容列出它們:
Df.columns Index(['archive_url', 'assignees_url', 'blobs_url', 'branches_url', 'clone_url', 'collaborators_url', 'comments_url', 'commits_url', 'compare_url', 'contents_url', 'contributors_url', 'default_branch', 'deployments_url', 'description', 'downloads_url', 'events_url', 'Fork', 'forks', 'forks_count', 'forks_url', 'full_name', 'git_commits_url', 'git_refs_url', 'git_tags_url', 'git_url', 'has_downloads', 'has_issues', 'has_pages', 'has_projects', 'has_wiki', 'homepage', 'hooks_url', 'html_url', 'id', 'issue_comment_url', 'Issue_events_url', 'issues_url', 'keys_url', 'labels_url', 'language', 'languages_url', 'merges_url', 'milestones_url', 'mirror_url', 'name', 'notifications_url', 'open_issues', 'open_issues_count', 'owner.avatar_url', 'owner.events_url', 'owner.followers_url', 'owner.following_url', 'owner.gists_url', 'owner.gravatar_id', 'owner.html_url', 'owner.id', 'owner.login', 'Owner.organizations_url', 'owner.received_events_url', 'owner.repos_url', 'owner.site_admin', 'owner.starred_url', 'owner.subscriptions_url', 'owner.type', 'owner.url', 'private', 'pulls_url', 'pushed_at', 'releases_url', 'score', 'size', 'ssh_url', 'stargazers_count', 'stargazers_url', 'statuses_url', 'subscribers_url', 'subscription_url', 'svn_url', 'tags_url', 'teams_url', 'trees_url', 'updated_at', 'url', 'Watchers', 'watchers_count', 'year'], dtype='object')
而後,咱們選擇將用於進一步分析的變量子集。咱們跳過與URL、全部者信息或ID 相關的全部技術變量 。其他列包含的信息極可能有助於咱們識別新的技術趨勢:
咱們選擇了衡量存儲庫流行度的標準。此數字表示有多少人對該項目感興趣。 可是,咱們也可使用它給咱們提供有關流行度的略有不一樣的信息。後者表示實際使用代碼的人數,所以它與不一樣的組相關。watchers_count forks_count
在上一步中,咱們構建了原始數據,如今能夠進行進一步分析。 咱們的目標是分析兩種類型的數據:
它們中的每個都須要不一樣的預處理技術。讓咱們看一下Detail 中的每種類型。
對於第一種,咱們必須建立一個包含已清理字符串的新變量。咱們將分三個步驟完成,這些步驟已在前幾章中介紹過:
因爲咱們只處理英語數據,所以咱們應該刪除全部用其餘語言編寫的描述。這樣作的主要緣由是每種語言都須要不一樣的處理和分析流程。若是咱們留下俄語或中文的描述,咱們會獲得很是嘈雜的數據,而這些數據是咱們沒法解釋的。所以,能夠說咱們正在分析英語世界的趨勢。
首先,咱們刪除description列中的全部空字符串。
df = df.dropna(subset=['description'])
爲了刪除非英語描述,咱們必須首先檢測每一個文本中使用的語言。爲此,咱們使用了一個名爲langdetect 的庫,該庫基於 Google語言檢測項目。
from langdetect import detect df['lang'] = df.apply(lambda x: detect(x['description']),axis=1)
咱們建立一個包含全部預測的新列。咱們看到不一樣的語言, 例如en (英語),zh-cn (中文),vi (越南語)或ca (加泰羅尼亞語)。
df['lang'] 0 en 1 en 2 en 3 en 4 en 5 zh-cn
在咱們的數據集中,en佔全部存儲庫的78.7%。咱們如今只選擇那些帶有英文描述的存儲庫:
df = df[df['lang'] == 'en']
在下一步中,咱們將使用預處理的文本數據建立一個新的clean列。咱們執行如下代碼來執行標記化並刪除停用詞:
import nltk from nltk import word_tokenize from nltk.corpus import stopwords def clean(text = '', stopwords = []): #tokenize tokens = word_tokenize(text.strip()) #lowercase clean = [i.lower() for i in tokens] #remove stopwords clean = [i for i in clean if i not in stopwords] #remove punctuation punctuations = list(string.punctuation) clean = [i.strip(''.join(punctuations)) for i in clean if i not in punctuations] return " ".join(clean) df['clean'] = df['description'].apply(str) #make sure description is a string df['clean'] = df['clean'].apply(lambda x: clean(text = x, stopwords = stopwords.words('english'))) Finally, we obtain a clean column which contains cleaned English descriptions, ready for analysis: df['clean'].head(5) 0 roadmap becoming web developer 2017 1 base repository imad v2 course application ple… 2 decrypted content eqgrp-auction-file.tar.xz 3 shadow brokers lost translation leak 4 learn design large-scale systems prep system d...
對於數值數據,咱們將統計檢查值的分佈以及是否存在任何缺失值:
df[['watchers_count','size','forks_count','open_issues']].describe()
咱們看到在全部四個變量中沒有缺失值:watchers_count、size、forks_count和open_issues。watchers_count的值從0到20,792不等,而最小的fork數是33,並上升到2,589。前四分之一的存儲庫沒有開放問題,而前25%的存儲庫有超過12個問題。值得注意的是,在咱們的數據集中,有一個包含458個開放問題的存儲庫。
一旦咱們完成了數據的預處理,咱們的下一步就是分析它,以便從中得到可操做的看法。