機器學習其實比你想的更簡單
很多人覺得機器學習高不可攀,認為這是一門只有少數專業學者才了解的神秘技術。
畢竟,你是在讓運行在二進制世界里的機器得出它自己對現實世界的認識。你正在教它們如何思考。然而,本文幾乎不是你所認為的晦澀難懂、復雜而充滿數學公式的文章。正如所有幫助我們認識世界的基本常識一樣(例如:牛頓運動定律、工作需要去完成、供需關系等等),機器學習最佳的方法和概念也應該是簡潔明了的。可惜的是,絕大多數關于機器學習的文獻都充斥著復雜難懂的符號、艱澀晦暗的數學公式和不必要的廢話。正是這給機器學習簡單基礎的思想圍上了一堵厚厚的墻。
現在看一個實際的例子,我們需要在一篇文章的末尾增加一個“你可能喜歡”的推薦功能,那么我們該如何實現呢?
為了實現這個想法,我們有一個簡單的解決方案:
- 1.獲得當前文章的標題并將其分割成獨立的單詞(譯者注:原文是英文,只需要依據空格分割即可,中文分詞需要用到分詞器)
- 2.獲取除當前文章以外的所有文章
- 3.將這些文章依據其內容與當前文章標題的重合程度進行排序
1 2 3 4 5 6 7 8 9 | def similar_posts(post) title_keywords = post.title.split(' ') Post.all.to_a.sort |post1, post2| post1_title_intersection = post1.body.split(' ') & title_keywords post2_title_intersection = post2.body.split(' ') & title_keywords post2_title_intersection.length <=> post1_title_intersection.length end[0..9] end |
采用這種方法去找出與博文“支持團隊如何提高產品質量”相似的文章,我們由此得到下列相關度前十的文章:
- 如何著手實施一個經過驗證的方案
- 了解你的客戶是如何做決策的
- 設計首次運行界面以取悅你的用戶
- 如何招聘設計師
- 圖標設計的探討
- 對歌手Ryan的采訪
- 通過內部交流對客戶進行積極支持
- 為什么成為第一并不重要
- 對Joshua Porter的采訪
- 客戶留存、群組分析與可視化
正如你所看到的,標桿文章是關于如何有效率地進行團隊支持,而這與客戶群組分析、討論設計的優點都沒有太大的關系,其實我們還可以采取更好的方法。
現在,我們嘗試用一種真正意義上的機器學習方法來解決這個問題。分兩步進行:
- 將文章用數學的形式表示;
- 用K均值(K-means)聚類算法對上述數據點進行聚類分析。
1.將文章用數學的形式表示
如果我們可以將文章以數學的形式展示,那么可以根據文章之前的相似程度作圖,并識別出不同簇群:
如上圖所示,將每篇文章映射成坐標系上的一個坐標點并不難,可以通過如下兩步實現:
- 找出每篇文章中的所有單詞;
- 為每篇文章建立一個數組,數組中的元素為0或者1,用于表示某單詞在該文章中是否出現了,每篇文章數組元素的順序都是一樣的,只是其值有差異。
Ruby代碼如下:
1 2 3 4 5 6 7 8 9 10 11 | @posts = Post.all @words = @posts.map do |p| p.body.split(' ') end.flatten.uniq @vectors = @posts.map do |p| @words.map do |w| p.body.include?(w) ? 1 : 0 end end |
[email protected] 的值為:
[“你好”,”內部”,”內部交流”,”讀者”,”博客”,”發布”]
如果某篇文章的內容是“你好 博客 發布 讀者”,那么其對應的數組即為:
[1,0,0,1,1,1]
當然,我們現在沒法使用簡單的工具像二維坐標系一樣展示這個六維度的坐標點,但是這其中涉及的基本概念,例如兩點之間的距離都是互通的,可以通過二維推廣到更高維度(因此使用二維的例子來說明問題還是行得通的)。
2.用K均值(K-means)聚類算法對數據點進行聚類分析
現在我們得到了一系列文章的坐標,可以嘗試找出相似文章的群簇。這里我們采用使用一個相當簡單聚類算法-K均值算法,概括起來有五個步驟:
- 設定一個數K,它表示群簇中對象的數目;
- 從所有數據對象中隨機選擇K個對象作為初始的K個群簇中心;
- 遍歷所有對象,分別將它們指派到離自己最近的一個群簇中;
- 更新群簇中心,即計算每個群簇中對象的均值,并將均值作為該群簇的新中心;
- 重復3、4步驟,直到每個群簇中心不再變化。
我們接下來用圖的形式形象化地展示這些步驟。首先我們從一系列文章坐標中隨機選擇兩個點(K=2):
我們將每篇文章指派到離它最近的群簇中:
我們計算各個群簇中所有對象的坐標均值,作為該群簇新的中心。
這樣我們就完成了第一次的數據迭代,現在我們將文章根據新的群簇中心重新指派到對應的群簇中去。
至此,我們找到了每篇文章對應的群簇!很明顯,即使繼續進行迭代群簇中心不會改變,每篇文章對應的群簇也不會改變了。
上述過程的Ruby代碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | @cluster_centers = [rand_point(), rand_point()] 15.times do @clusters = [[], []] @posts.each do |post| min_distance, min_point = nil, nil @cluster_centers.each.with_index do |center, i| if distance(center, post) < min_distance min_distance = distance(center, post) min_point = i end end @clusters[min_point] << post end @cluster_centers = @clusters.map do |post| average(posts) end end |
下面是由這個方法得到的與博文“支持團隊如何提高產品質量”相似性排在前十位的文章:
- 你對此更了解了還是你更聰明了
- 客戶反饋的三個準則
- 從客戶獲取你所要的信息
- 產品交付只是一個開始
- 你覺得功能擴展看起來像什么
- 了解你的用戶群
- 在正確的信息和正確的時間下轉換客戶
- 與你的客戶溝通
- 你的應用有消息推送安排嗎
- 你有試著與客戶溝通嗎
結果不言自明。
我們僅僅用了不到40行的代碼以及簡單的算法介紹就實現了這個想法,然而如果你看學術論文你永遠不會知道這本該有多簡單。下面是一篇介紹K均值算法論文的摘要(并不知道K均值算法是誰提出的,但這是首次提出“K均值”這個術語的文章)。
如果你喜歡以數學符號去表達思想,毫無疑問學術論文是很有用處的。然而,其實有更多優質的資源可以替換掉這些繁雜數學公式,它們更實際、更平易近人。
- Wiki百科(例如:潛在語義索引,聚類分析)
- 開源機器學習庫的源代碼(例如:Scipy’s K-Means,Scikit’s DBSCAN)
- 以程序員的角度編寫的書籍(例如:集體智慧編程,黑客機器學習)
- 可汗學院
試一試
如何為你的項目管理應用推薦標簽?如何設計你的客戶支持工具?或者是社交網絡中用戶如何分組?這些都可以通過簡答的代碼、簡單的算法來實現,是練習的好機會!所以,如果你認為項目中面臨的問題可以通過機器學習來解決,那為什么還要猶豫呢?
機器學習其實比你想象得更簡單!