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