最近想了解下程序員可以做什么副業,我抓取了各大網站關於程序員搞副業的文章,但抓取的文章較多,為了將相似的文章歸攏到一起,我用聚類算法將文章划分到不同的主題。下面我就來介紹一下分析的結論以及過程。文末回復關鍵字即可獲取本次分析源碼。
本次分析的文章是從博客園、CSDN、知乎、今日頭條和微信上抓取,共140篇,聚類得到的主題如下:
-
接私活:主要是在碼市、程序員客棧等網站接項目做外包,對於接私活的評價大家褒貶不一,有的人決定接私活能夠鍛煉技術,但有的人覺得是重復勞動,可積累性差。我自己也接過私活,不建議程序員接私活,因為它相當於是工作時間的延伸,並沒有給你帶來其他的可能性
-
寫作:反對接私活的一部分人就提出來走寫作這條路,因為寫作一來可以有深度的思考,二來也可以沉淀技術,最后通過輸出的內容變現
-
出書和錄視頻:看書和看視頻也是我們學習技術的主要途徑,錄視頻是對技術能力和表達能力有更高的要求,相對而言寫書會容易一些。對於程序員來說如果經常寫原創博客,會有出版社的人員主動聯系你。如果自己有時間、有能力的話可以考慮寫本書,既可以賺錢還能提高個人影響力。我去年就寫了一本小冊,這個過程中確實需要付出很多時間和精力
-
小項目:這個相對於外包來說會好一些,原文作者舉了個例子,通過網上爬取公開的個人信息和聯系方式,包裝成軟件出售,獲得了不菲的收入
-
公眾號:通過公眾號積累流量,接廣告賺錢
-
投資學習:通過聚類分析發現有些文章的觀點畫風比較清奇,認為程序員最大的副業是投資自己。這也是一條很好的路子,不斷地拓寬自己的知識廣度、打穿知識深度,能夠在主營業務上創造出獨一無二的成果也是一種副業
當然還有一些的關於討論程序員應不應該搞副業的主題也能聚在一起,這里就不舉例了,有興趣朋友可以看詳細的分析數據。
下面來介紹下分析過程
數據抓取:需求比較明確,第一步找到文章搜索的入口,第二步找到文章詳情的入口。實現方案有兩種,第一種是請求接口;第二種是解析網頁HTML代碼。在本次分析中這兩種方案都有涉及,其中微信公眾號的數據抓取比較困難,我用的是開源的項目wechatsogou,這個項目直接用也是有各種問題,但我都解決了,需要注意的問題在源代碼中都有說明。由於這次抓取的網站比較多,抓取這一步花費了60%的時間。數據清洗:主要目的是為了保證我們后續分析的數據是干凈的,且沒有噪音。這里我主要做了兩步,第一步限制文章的title包含“程序員”和“副業”,保證文章內容是可靠的;第二步通過BeautifulSoup取出HTML標簽,保證正文干凈
# 過濾文章 def article_filter(article): title = article['title'] if '副業' in title and '程序員' in title: return True return False # 清洗正文,去掉html標簽 def content_clean(content): content_bs = BeautifulSoup(content) content_text = content_bs.get_text() content_text = re.sub('\n|\xa0', '', content_text) return content_text
特征提取:因為我們是作文本分析,所以我們要將文本轉化成計算機能識別的數字特征。轉化的方式有兩種,第一種詞袋空間VSM(vector space model),簡單來說它將一篇文章存儲為一個數組,數組第n位的元素值代表該文章中第i個詞出現的頻次。然后通過TF-IDF計算第i個詞在這篇文章的權重。如果某個詞是文章的關鍵詞,那么它的權重比其他詞就大。所以如果兩篇表達的是同一個主題,那么它倆的詞分布以及詞的權重會很像,做聚類的時候自然就能聚到一起;另一種方式是將文檔轉化成向量,即:Doc2Vector。這里主要介紹第一種方式,關於第二種源代碼也有涉及,有興趣的朋友可以自行看源碼。
# 計算tf-idf 作為每個詞的權重 from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer # 統計詞頻 vectorizer = CountVectorizer(token_pattern=r"(?u)\b\w+\b") # 計算tf-idf transformer = TfidfTransformer() tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus)) # 權重矩陣, 二位數組,每行是一篇文章,每列是一個詞 weight_matrix = tfidf.toarray() # 特征詞,數據,每個元素是一個詞,也是weight_matrix第i列的詞 word = vectorizer.get_feature_names()
聚類分析:關於聚類的算法有很多,比如:K-Means、Birch、LDA和DBSCAN。本次分析中我用到了K-Means和Birch,這里主要介紹K-Means的代碼。K-Means的思想比較簡單,就是將兩個距離較近的文章聚成一類。前面我們已經將文章轉成向量了,所以可以計算文章之間的距離。
# Kmeans 聚類 from sklearn.cluster import KMeans # 聚成 15 類 kmeans = KMeans(n_clusters=15) kmeans.fit(weight_matrix) # 聚類結果,存放第i篇文章屬於第幾類 kmeans.labels_
K-Means的用法也比較簡單,只需指定要最終聚出的類數量(n_clusters)即可。
效果評估:主要用來評估聚在一起的文章是否真的是同一類,或者同一類的文章是否聚在了一起。因為之前我們計算了TF-IDF,我們能獲取每篇文章的關鍵詞,所以我把每篇文章所在的類別、標題、以及關鍵詞輸出到文件,來進行評估
# 提取每篇文章最關鍵的5個詞 # keywords def get_key_words(weight, words): topk_weight = sorted(weight, reverse=True)[:5] min_weight = topk_weight[-1] max_weight = topk_weight[0] key_words = [] for index, x in enumerate(weight): if x >= min_weight: key_words.append(words[index]) return " ".join(key_words) f = open("cluster_res.txt", "w", encoding='utf-8') for index, label in enumerate(kmeans.labels_): kws = get_key_words(weight_matrix[index], word) raw = '%d\t%d\t%s\t%s\t%s\t%s\n' % (index,label, kws, attrs[index][0], attrs[index][1], attrs[index][2]) f.write(raw)
下面貼幾個case,聚類的效果還可以
類別3是接私活相關的文章,類別6是投資學習的文章,類別7是出書和視頻的文章。本次分析過程就介紹到這里,其實這次分析具體到每個步驟可能沒做那么細,比如:數據清洗、模型優化等,但整個流程還算比較完整。如果各位有興趣可以自行深入研究。
希望這次分析能對你有用,歡迎公眾號「渡碼」。公眾號回復關鍵字 副業 即可獲得完整源碼。