熱線電話:13121318867

登錄
首頁精彩閱讀數據挖掘:如何尋找相關項
數據挖掘:如何尋找相關項
2016-03-11
收藏

數據挖掘:如何尋找相關項

數據科學家要具備專業領域知識并研究相應的算法以分析對應的問題,而數據挖掘是其必須掌握的重要技術。以幫助創建推動業務發展的相應大數據產品和大數據解決方案。EMC最近的一項調查也證實了這點。調查結果顯示83%的人認為大數據浪潮所催生的新技術增加了數據科學家的需求。本文將為您展示如何基于一個簡單的公式查找相關的項目。請注意,此項技術適用于所有的網站(如亞馬遜),以個性化用戶體驗、提高轉換效率。

查找相關項問題

要想為一個特定的項目查找相關項,就必須首先為這兩個項目定義相關之處。而這些也正是你要解決的問題:

在博客上,你可能想以標簽的形式分享文章,或者對比查看同一個人閱讀過的文章

亞馬遜站點被稱為“購買此商品的客戶還購買了”的部分

一個類似于IMDB(Internet Movie Database)的服務,可以根據用戶的評級,給出觀影指南建議

不論是標簽、購買的商品還是觀看的電影,我們都要對其進行分門別類。這里我們將采用標簽的形式,因為它很簡單,而且其公式也適用于更復雜的情形。

以幾何關系重定義問題

現在以我的博客為例,來列舉一些標簽:


  1. [“API”“Algorithms”“Amazon”“Android”“Books”“Browser”]


好,我們來看看在歐式空間幾何學中如何表示這些標簽。

我們要排序或比較的每個項目在空間中以點表示,坐標值(代表一個標簽)為1(標記)或者0(未標記)。

因此,如果我們已經獲取了一篇標簽為“API”和“Browser”的文章,那么其關聯點是:


  1. [ 1, 0, 0, 0, 0, 1 ]


現在這些坐標可以表示其它含義。例如,他們可以代表用戶。如果在你的系統中有6個用戶,其中2個用戶對一篇文章分別評了3星和5星,那么你就可以針對此文章查看相關聯的點(請注意順序):


  1. [ 0, 3, 0, 0, 5, 0 ]


現在我們可以計算出相關矢量之間的夾角,以及這些點之間的距離。下面是它們在二維空間中的圖像:

歐式幾何空間距離

計算歐式幾何空間兩點之間距離的數學公式非常簡單??紤]相關兩點A、B之間的距離:

兩點之間的距離越近,它們的相關性越大。下面是Ruby代碼:


  1. # Returns the Euclidean distance between 2 points
  2. #
  3. # Params:
  4. #  – a, b: list of coordinates (float or integer)
  5. #
  6. def euclidean_distance(a, b)
  7.   sq = a.zip(b).map{|a,b| (a – b) ** 2}
  8.   Math.sqrt(sq.inject(0) {|s,c| s + c})
  9. end
  10. # Returns the associated point of our tags_set, relative to our
  11. # tags_space.
  12. #
  13. # Params:
  14. #  – tags_set: list of tags
  15. #  – tags_space: _ordered_ list of tags
  16. def tags_to_point(tags_set, tags_space)
  17.   tags_space.map{|c| tags_set.member?(c) ? 1 : 0}
  18. end
  19. # Returns other_items sorted by similarity to this_item 
  20. # (most relevant are first in the returned list)
  21. #
  22. # Params:
  23. #  – items: list of hashes that have [:tags]
  24. #  – by_these_tags: list of tags to compare with
  25. def sort_by_similarity(items, by_these_tags)
  26.   tags_space = by_these_tags + items.map{|x| x[:tags]}
  27.   tags_space.flatten!.sort!.uniq!
  28.   this_point = tags_to_point(by_these_tags, tags_space)
  29.   other_points = items.map{|i|
  30.     [i, tags_to_point(i[:tags], tags_space)]
  31.   }
  32.   similarities = other_points.map{|item, that_point|
  33.     [item, euclidean_distance(this_point, that_point)]
  34.   }
  35.   sorted = similarities.sort {|a,b| a[1] <=> b[1]}
  36.   return sorted.map{|point,s| point}
  37. End


這是一些示例代碼,你可以直接復制運行:


  1. # SAMPLE DATA
  2. all_articles = [
  3.   {
  4.    :article => “Data Mining: Finding Similar Items”,
  5.    :tags => [“Algorithms”“Programming”“Mining”,
  6.      “Python”“Ruby”]
  7.   },
  8.   {
  9.    :article => “Blogging Platform for Hackers”,
  10.    :tags => [“Publishing”“Server”“Cloud”“Heroku”,
  11.      “Jekyll”“GAE”]
  12.   },
  13.   {
  14.    :article => “UX Tip: Don’t Hurt Me On Sign-Up”,
  15.    :tags => [“Web”“Design”“UX”]
  16.   },
  17.   {
  18.    :article => “Crawling the Android Marketplace”,
  19.    :tags => [“Python”“Android”“Mining”,
  20.      “Web”“API”]
  21.   }
  22. ]
  23. # SORTING these articles by similarity with an article 
  24. # tagged with Publishing + Web + API
  25. #
  26. #
  27. # The list is returned in this order:
  28. #
  29. # 1. article: Crawling the Android Marketplace
  30. #    similarity: 2.0
  31. #
  32. # 2. article: “UX Tip: Don’t Hurt Me On Sign-Up”
  33. #    similarity: 2.0
  34. #
  35. # 3. article: Blogging Platform for Hackers
  36. #    similarity: 2.645751
  37. #
  38. # 4. article: “Data Mining: Finding Similar Items”
  39. #    similarity: 2.828427
  40. #
  41. sorted = sort_by_similarity(
  42.     all_articles, [‘Publishing’‘Web’‘API’])
  43. require ‘yaml’
  44. puts YAML.dump(sorted)


你是否留意到我們之前選擇的數據存在一個缺陷?前兩篇文章對于標簽“[“Publishing”, “Web”, “API”]”有著相同的歐氏幾何空間距離。

為了更加形象化,我們來看看計算第一篇文章所用到的點:


  1. [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
  2. [1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1]


只有四個坐標值不同,我們再來看看第二篇文章所用到的點:


  1. [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
  2. [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]


與第一篇文章相同,也只有4個坐標值不同。歐氏空間距離的度量取決于點之間的差異。這也許不太好,因為相對平均值而言,有更多或更少標簽的文章會處于不利地位。

余弦相似度

這種方法與之前的方法類似,但更關注相似性。下面是公式:

下面是Ruby代碼:


  1. def dot_product(a, b)
  2.   products = a.zip(b).map{|a, b| a * b}
  3.   products.inject(0) {|s,p| s + p}
  4. end
  5. def magnitude(point)
  6.   squares = point.map{|x| x ** 2}
  7.   Math.sqrt(squares.inject(0) {|s, c| s + c})
  8. end
  9. # Returns the cosine of the angle between the vectors 
  10. #associated with 2 points
  11. #
  12. # Params:
  13. #  – a, b: list of coordinates (float or integer)
  14. #
  15. def cosine_similarity(a, b)
  16.   dot_product(a, b) / (magnitude(a) * magnitude(b))
  17. end


對于以上示例,我們對文章進行分類得到:


  1. – article: Crawling the Android Marketplace
  2.   similarity: 0.5163977794943222
  3. – article: “UX Tip: Don’t Hurt Me On Sign-Up”
  4.   similarity: 0.33333333333333337
  5. – article: Blogging Platform for Hackers
  6.   similarity: 0.23570226039551587
  7. – article: “Data Mining: Finding Similar Items”
  8.   similarity: 0.0


這種方法有了很大改善,我們的代碼可以很好地運行,但它依然存在問題。

示例中的問題:Tf-ldf權重

我們的數據很簡單,可以輕松地計算并作為衡量的依據。如果不采用余弦相似度,很可能會出現相同的結果。

Tf-ldf權重是一種解決方案。Tf-ldf是一個靜態統計量,用于權衡文本集合中的一個詞在一個文檔中的重要性。

根據Tf-ldff,我們可以為坐標值賦予獨特的值,而并非局限于0和1.

對于我們剛才示例中的簡單數據集,也許更簡單的度量方法更適合,比如Jaccard index也許會更好。

皮爾遜相關系數(Pearson Correlation Coefficient)

使用皮爾遜相關系數(Pearson Correlation Coefficient)尋找兩個項目之間的相似性略顯復雜,也并不是非常適用于我們的數據集合。

例如,我們在IMDB中有2個用戶。其中一個用戶名為John,對五部電影做了評級:[1,2,3,4,5]。另一個用戶名為Mary,對這五部電影也給出了評級:[4, 5, 6, 7, 8]。這兩個用戶非常相似,他們之間有一個完美的線性關系,Mary的評級都是在John的基礎上加3。

計算公式如下:

代碼如下:


  1. def pearson_score(a, b)
  2.   n = a.length
  3.   return 0 unless n > 0
  4.   # summing the preferences
  5.   sum1 = a.inject(0) {|sum, c| sum + c}
  6.   sum2 = b.inject(0) {|sum, c| sum + c}
  7.   # summing up the squares
  8.   sum1_sq = a.inject(0) {|sum, c| sum + c ** 2}
  9.   sum2_sq = b.inject(0) {|sum, c| sum + c ** 2}
  10.   # summing up the product
  11.   prod_sum = a.zip(b).inject(0) {|sum, ab| sum + ab[0] * ab[1]}
  12.   # calculating the Pearson score
  13.   num = prod_sum – (sum1 *sum2 / n)
  14.   den = Math.sqrt((sum1_sq – (sum1 ** 2) / n) * (sum2_sq – (sum2 ** 2) / n))
  15.   return 0 if den == 0
  16.   return num / den
  17. end
  18. puts pearson_score([1,2,3,4,5], [4,5,6,7,8])
  19. # => 1.0
  20. puts pearson_score([1,2,3,4,5], [4,5,0,7,8])
  21. # => 0.5063696835418333
  22. puts pearson_score([1,2,3,4,5], [4,5,0,7,7])
  23. # => 0.4338609156373132
  24. puts pearson_score([1,2,3,4,5], [8,7,6,5,4])
  25. # => -1


曼哈頓距離算法

沒有放之四海而皆準的真理,我們所使用的公式取決于要處理的。下面我們簡要介紹一下曼哈頓距離算法。

曼哈頓距離算法計算兩點之間的網格距離,維基百科中的圖形完美詮釋了它與歐氏幾何距離的不同:

紅線、黃線和藍線是具有相同長度的曼哈頓距離,綠線代表歐氏幾何空間距離。

數據分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢