很多人覺得機器學習高不可攀,認爲這是一門只有少數專業學者才瞭解的神祕技術。
畢竟,你是在讓運行在二進制世界裏的機器得出它自己對現實世界的認識。你正在教它們如何思考。然而,本文幾乎不是你所認爲的晦澀難懂、複雜而充滿數學公式的文章。正如所有幫助我們認識世界的基本常識一樣(例如:牛頓運動定律、工作需要去完成、供需關係等等),機器學習最佳的方法和概念也應該是簡潔明瞭的。可惜的是,絕大多數關於機器學習的文獻都充斥着複雜難懂的符號、艱澀晦暗的數學公式和不必要的廢話。正是這給機器學習簡單基礎的思想圍上了一堵厚厚的牆。
現在看一個實際的例子,我們需要在一篇文章的末尾增加一個“你可能喜歡”的推薦功能,那麼我們該如何實現呢?
爲了實現這個想法,我們有一個簡單的解決方案:
- 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 |
假設@words 的值爲:
[“你好”,”內部”,”內部交流”,”讀者”,”博客”,”發佈”]
如果某篇文章的內容是“你好 博客 發佈 讀者”,那麼其對應的數組即爲:
[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)
- 以程序員的角度編寫的書籍(例如:集體智慧編程,黑客機器學習)
- 可汗學院
試一試
如何爲你的項目管理應用推薦標籤?如何設計你的客戶支持工具?或者是社交網絡中用戶如何分組?這些都可以通過簡答的代碼、簡單的算法來實現,是練習的好機會!所以,如果你認爲項目中面臨的問題可以通過機器學習來解決,那爲什麼還要猶豫呢?
機器學習其實比你想象得更簡單!