Làm cách nào để sử dụng SVD trong lọc cộng tác?


30

Tôi hơi bối rối với cách sử dụng SVD trong lọc cộng tác. Giả sử tôi có một biểu đồ xã hội và tôi xây dựng một ma trận kề từ các cạnh, sau đó lấy một SVD (hãy quên việc chính quy hóa, tỷ lệ học tập, tối ưu hóa độ thưa thớt, v.v.), làm cách nào để sử dụng SVD này để cải thiện các đề xuất của tôi?

Giả sử biểu đồ xã hội của tôi tương ứng với instagram và tôi được giao trách nhiệm giới thiệu người dùng trong dịch vụ, chỉ dựa trên biểu đồ xã hội. Trước tiên tôi sẽ xây dựng một ma trận kề, , lấy SVD, , chọn giá trị đầu tiên , sau đó là gì?A (m×m)A=UsVk

Có lẽ tôi sẽ tạo một bộ ma trận mới: thì người ta làm gì?

Unewm×ksnewk×kVnewk×m

Tôi đã xem trên web và hầu hết các liên kết tập trung vào tính toán SVD, nhưng không ai nói cho bạn biết phải làm gì với nó. Vậy tôi phải làm sao?


1
Điều này có thể trả lời câu hỏi của bạn: datascience.stackexchange.com/a/16523
avli

Câu trả lời:


7

Tuy nhiên: Với SVD vanilla thuần túy, bạn có thể gặp vấn đề khi tạo lại ma trận gốc, hãy để một mình dự đoán giá trị cho các mục bị thiếu. Nguyên tắc hữu ích trong lĩnh vực này là tính toán xếp hạng trung bình cho mỗi phim và trừ đi mức trung bình này cho mỗi kết hợp người dùng / phim, nghĩa là trừ đi độ lệch phim từ mỗi người dùng. Sau đó, bạn nên chạy SVD, và tất nhiên, bạn sẽ phải ghi lại các giá trị sai lệch này ở đâu đó, để tạo lại xếp hạng hoặc dự đoán cho các giá trị không xác định. Tôi đã đọc bài đăng của Simon Funk trên SVD để biết các khuyến nghị - anh ấy đã phát minh ra cách tiếp cận SVD gia tăng trong cuộc thi Netflix.

http://sifter.org/~simon/journal/20061211.html

Tôi đoán việc hạ thấp ma trận A trước khi SVD có ý nghĩa, vì người anh em họ thân thiết của SVD cũng hoạt động theo cách tương tự. Về mặt tính toán gia tăng, Funk nói với tôi rằng nếu bạn không hạ thấp, hướng gradient đầu tiên sẽ chi phối phần còn lại của tính toán. Tôi đã thấy điều này đầu tiên, về cơ bản mà không làm giảm mọi thứ không hoạt động.


24

Tôi muốn đưa ra một ý kiến ​​không đồng tình:

Thiếu các cạnh là giá trị thiếu

Trong vấn đề lọc cộng tác, các kết nối không tồn tại (người dùng chưa xếp hạng mục j , người x chưa kết bạn với người y ) thường được coi là các giá trị bị thiếu để dự đoán, thay vì là số không. Nghĩa là, nếu người sử dụng tôi đã không đánh giá mục j , chúng tôi muốn đoán những gì ông có thể đánh giá nó nếu ông đã đánh giá nó. Nếu người x chưa kết bạn với y , chúng tôi muốn đoán như thế nào khả năng nó là anh muốn cho bạn bè anh ấy. Các khuyến nghị được dựa trên các giá trị được xây dựng lại.tôijxytôijxy

Khi bạn lấy SVD của biểu đồ xã hội (ví dụ: cắm nó qua svd()), về cơ bản, bạn đang đưa ra các số không trong tất cả các điểm bị thiếu. Rằng vấn đề này rõ ràng hơn trong thiết lập xếp hạng người dùng để lọc cộng tác. Nếu tôi có một cách đáng tin cậy để điền vào các mục còn thiếu, tôi hoàn toàn không cần sử dụng SVD. Tôi chỉ đưa ra khuyến nghị dựa trên các mục được điền. Nếu tôi không có cách nào để làm điều đó, thì tôi không nên điền vào chúng trước khi tôi làm SVD. *

SVD với các giá trị thiếu

Tất nhiên, svd()hàm không biết cách đối phó với các giá trị bị thiếu. Vì vậy, chính xác những gì bạn phải làm gì? Chà, có một cách để điều chỉnh lại vấn đề như

"Tìm ma trận thứ hạng gần nhất với ma trận gốc"k

Đó thực sự là vấn đề bạn đang cố gắng giải quyết, và bạn sẽ không sử dụng svd()để giải quyết nó. Một cách làm việc cho tôi (trên dữ liệu giải thưởng Netflix) là:

  • Hãy thử để phù hợp với các mục với một mô hình đơn giản, ví . Điều này thực sự làm một công việc tốt.X^tôi,j= =μ+αtôi+βj

  • Chỉ định mỗi người dùng một k -vector u i và mỗi mục j a k -vector v j . (Trong trường hợp của bạn, mỗi người được một k -vector phải và trái ). Cuối cùng, bạn sẽ dự đoán phần dư dưới dạng các sản phẩm chấm: u i m v j mtôikbạntôijkvjkΣbạntôimvjm

  • Sử dụng một số thuật toán để tìm các vectơ thu nhỏ khoảng cách đến ma trận gốc. Ví dụ, sử dụng giấy này

May mắn nhất!

*: Những gì Tenali đang đề xuất về cơ bản là hàng xóm gần nhất. Bạn cố gắng tìm những người dùng tương tự và đưa ra khuyến nghị về điều đó. Thật không may, vấn đề thưa thớt (~ 99% ma trận là các giá trị bị thiếu) khiến bạn khó tìm thấy hàng xóm gần nhất bằng cách sử dụng khoảng cách cosin hoặc độ tương tự jaccard hoặc bất cứ điều gì. Vì vậy, anh ấy khuyên bạn nên thực hiện một SVD của ma trận (với các số 0 được liệt kê ở các giá trị bị thiếu) trước tiên nén người dùng vào một không gian tính năng nhỏ hơn và sau đó so sánh ở đó. Làm SVD - hàng xóm gần nhất là tốt, nhưng tôi vẫn khuyên bạn nên làm SVD đúng cách (ý tôi là ... theo cách của tôi). Không cần phải làm giá trị vô nghĩa!


Đây thực sự là câu trả lời tôi đang tìm kiếm và muốn nghe :) Cảm ơn bạn rất nhiều!
Vishal

Điều kỳ lạ là câu hỏi "Tôi đã xem trên web và hầu hết các liên kết tập trung vào tính toán SVD, nhưng không ai nói cho bạn biết phải làm gì với nó. Vậy tôi nên làm gì?" hoặc cho vấn đề đó, tiêu đề nói, "Làm cách nào để sử dụng SVD trong lọc cộng tác?"
TenaliRaman

Đúng, và câu trả lời của tôi tóm tắt cách tôi sử dụng nó trong lọc cộng tác.
Stumpy Joe Pete

1
+1, theo tôi hiểu, bạn không tính toán ma trận thứ hạng thấp bằng cách sử dụng SVD, mà là một phương pháp lặp để giảm thiểu lỗi bình phương, phải không? Tuy nhiên, nếu tôi muốn sử dụng SVD, thì tôi nên điền vào các mục còn thiếu với một số giá trị trước khi tôi thực hiện nhân tố ma trận, phải không?

1
Vì vậy, khi họ nói rằng họ đã sử dụng svd, họ không có nghĩa là sử dụng để thực hiện nhân tố ma trận? Lý do tại sao họ nói svd, là vì kết quả hoặc ý tưởng cơ bản đằng sau giải pháp lặp này giống với svd? Svd()

14

Lý do không ai nói cho bạn biết phải làm gì với nó là vì nếu bạn biết SVD làm gì, thì có một chút rõ ràng phải làm gì với nó :-).

Vì các hàng và cột của bạn là cùng một tập hợp, tôi sẽ giải thích điều này thông qua một ma trận khác A. Hãy để ma trận A sao cho các hàng là người dùng và các cột là các mục mà người dùng thích. Lưu ý rằng ma trận này không cần phải đối xứng, nhưng trong trường hợp của bạn, tôi đoán nó hóa ra là đối xứng. Một cách nghĩ về SVD như sau: SVD tìm thấy một không gian tính năng ẩn trong đó người dùng và các mục họ thích có các vectơ đặc trưng được liên kết chặt chẽ.

Một= =Bạn×S×VBạnV

Bây giờ, nếu tôi đưa cho bạn hai vectơ từ cùng một không gian tính năng và yêu cầu bạn tìm xem chúng có giống nhau không, điều đơn giản nhất mà bạn có thể nghĩ ra để thực hiện điều đó là gì? Chấm sản phẩm.

tôijtôiBạnj


Hai câu hỏi: 1) Bạn có điền các giá trị bị thiếu bằng 0 (mục j không được người dùng i xem xét trước khi chạy SVD không? 2) Làm thế nào để bạn tính toán nếu một người dùng mới sẽ thích mục j?
B_Miner

1
@B_Miner Xin chào, xin lỗi vì phản hồi chậm. Các câu trả lời: 1) Vâng, vâng, chúng tôi thường điền các giá trị còn thiếu bằng 0 trước khi chạy SVD. Tuy nhiên, tôi thường khuyên bạn nên điền nó với xếp hạng khác không - ví dụ: bạn có thể điền các giá trị còn thiếu bằng xếp hạng trung bình mà người dùng đã đưa ra cho đến nay. 2) Cách tiếp cận dựa trên SVD chỉ dành cho người dùng đã biết và các mục đã biết. Nó không thể xử lý người dùng mới hoặc các mặt hàng mới. Và làm sao có thể, nếu một người dùng mới bước vào, chúng tôi không biết gì về anh ta trong khung này để dự đoán.
TenaliRaman

1
@B_Miner Nếu bạn muốn làm việc với người dùng / vật phẩm mới, chúng tôi phải giả định rằng chúng tôi có quyền truy cập vào một số tính năng người dùng và tính năng mục. Sau đó, bạn có thể sử dụng một mô hình phức tạp hơn như PDLF (Mô hình nhân tố tiềm ẩn rời rạc dự đoán). Điều này sẽ cho phép bạn xử lý người dùng / mục mới vì nó hoạt động với không gian tính năng đã biết.
TenaliRaman

@TenaliRaman Không chắc chắn nếu bạn sẽ thấy điều này, nhưng ở đây đi. Vì vậy, tôi đã sử dụng các mô hình chủ đề (LDA) để xây dựng các tính năng cho người dùng (nghĩa đen là người dùng) dựa trên các tài liệu họ đã đọc. Tôi chỉ lấy trung bình các vectơ chủ đề để có được "vectơ chủ đề người dùng". Tôi muốn làm một cái gì đó tương tự với SVD (hoặc ALS có thể). Giả sử tôi tính toán SVD bằng dữ liệu mục người dùng đã biết và sau đó tôi có người dùng mới "truy cập" một số mục đã biết. Trong trường hợp này, vectơ vật phẩm được biết nhưng vectơ người dùng không xác định. Tôi có thể sử dụng các vectơ vật phẩm để tính toán vectơ người dùng hay tôi cần phải tính toán lại SVD bằng cách sử dụng tất cả dữ liệu?
thecity2

câu trả lời tuyệt vời tenali. rất hữu ích để hiểu khái niệm
Nihal

3

Điều này là để thử và trả lời phần "làm thế nào" của câu hỏi cho những người muốn thực hiện thực tế các đề xuất SVD thưa thớt hoặc kiểm tra mã nguồn để biết chi tiết. Bạn có thể sử dụng một phần mềm FOSS có sẵn để mô hình hóa SVD thưa thớt. Ví dụ, vowpal wabbit, libFM, hoặc redsvd.

vowpal wabbitcó 3 triển khai thuật toán "giống như SVD" (mỗi thuật toán có thể chọn bằng một trong 3 tùy chọn dòng lệnh). Nói một cách chính xác những thứ này nên được gọi là "xấp xỉ, lặp, nhân tố ma trận" chứ không phải là "SVD" cổ điển thuần túy nhưng chúng có liên quan chặt chẽ với SVD. số không) ma trận.

Đây là một công thức đầy đủ, hoạt động để thực hiện các đề xuất phim theo phong cách Netflix với tùy chọn vowpal wabbit"bậc hai xếp hạng thấp" ( --lrq) có vẻ phù hợp nhất với tôi:

Tệp định dạng tập dữ liệu ratings.vw(mỗi xếp hạng trên một dòng theo người dùng và phim):

5 |user 1 |movie 37
3 |user 2 |movie 1019
4 |user 1 |movie 25
1 |user 3 |movie 238
...

Trong đó số thứ nhất là xếp hạng (1 đến 5 sao) theo sau là ID của người dùng đã xếp hạng và ID phim được xếp hạng.

Dữ liệu thử nghiệm có cùng định dạng nhưng có thể (tùy chọn) bỏ qua cột xếp hạng:

 |user 1 |movie 234
 |user 12 |movie 1019
...

tùy chọn vì để đánh giá / kiểm tra dự đoán, chúng tôi cần xếp hạng để so sánh dự đoán. Nếu chúng tôi bỏ qua xếp hạng, vowpal wabbitvẫn sẽ dự đoán xếp hạng nhưng sẽ không thể ước tính lỗi dự đoán (giá trị dự đoán so với giá trị thực trong dữ liệu).

Để đào tạo, chúng tôi yêu cầu vowpal wabbittìm một tập hợp các Nyếu tố tương tác tiềm ẩn giữa người dùng và phim họ thích (hoặc không thích). Bạn có thể nghĩ về điều này khi tìm các chủ đề phổ biến trong đó những người dùng tương tự đánh giá một tập hợp con phim theo cách tương tự và sử dụng các chủ đề phổ biến này để dự đoán người dùng sẽ đánh giá phim như thế nào.

vw tùy chọn và đối số chúng ta cần sử dụng:

  • --lrq <x><y><N> tìm thấy các yếu tố tiềm ẩn "bậc hai thấp".
  • <x><y>: "um" có nghĩa là vượt qua các không gian tên u [sers] và m [ovie] trong tập dữ liệu. Lưu ý rằng chỉ có chữ cái đầu tiên trong mỗi không gian tên được sử dụng với --lrqtùy chọn.
  • <N>: N=14bên dưới là số lượng các yếu tố tiềm ẩn mà chúng tôi muốn tìm
  • -f model_filename: viết mô hình cuối cùng vào model_filename

Vì vậy, một lệnh đào tạo đầy đủ đơn giản sẽ là:

    vw --lrq um14 -d ratings.vw -f ratings.model

Khi chúng ta có ratings.modeltệp mô hình, chúng ta có thể sử dụng nó để dự đoán xếp hạng bổ sung trên tập dữ liệu mới more_ratings.vw:

    vw -i ratings.model -d more_ratings.vw -p more_ratings.predicted

Các dự đoán sẽ được ghi vào tập tin more_ratings.predicted.

Sử dụng demo/movielenstrong vowpalwabbitcây nguồn, tôi nhận được ~ 0,693 MAE (Lỗi tuyệt đối trung bình) sau khi đào tạo trên 1 triệu xếp hạng người dùng / phim ml-1m.ratings.train.vwvới 14 yếu tố tiềm ẩn (có nghĩa là ma trận giữa SVD là ma trận cột 14x14 hàng x) và thử nghiệm độc lập thiết lập thử nghiệm ml-1m.ratings.test.vw. 0,69 MAE tốt như thế nào? Đối với phạm vi đầy đủ của các dự đoán có thể, bao gồm cả trường hợp chưa được đánh giá (0) [0 đến 5], sai số 0,69 là ~ 13,8% (0,69 / 5,0) của phạm vi đầy đủ, nghĩa là độ chính xác khoảng 86,2% (1 - 0,138).

Bạn có thể tìm thấy các ví dụ và bản demo đầy đủ cho một tập dữ liệu tương tự (Movielens) với tài liệu trong vowpal wabbitcây nguồn trên github:

Ghi chú:

  • Các movielensbản demo sử dụng một vài lựa chọn Tôi bỏ qua (vì đơn giản) từ ví dụ của tôi: đặc biệt --loss_function quantile, --adaptive--invariant
  • Việc --lrqthực hiện trong vwnhanh hơn nhiều --rank, đặc biệt là khi lưu trữ và tải các mô hình.

Tín dụng:

  • --rank tùy chọn vw được thực hiện bởi Jake Hofman
  • --lrq tùy chọn vw (với tùy chọn bỏ học) đã được Paul Minero triển khai
  • vowpal wmus (aka vw) là đứa con tinh thần của John Langford

1

Tôi sẽ nói rằng tên đó SVDlà sai lệch. Trong thực tế, SVDphương pháp trong hệ thống đề xuất không sử dụng trực tiếp nhân tố SVD. Thay vào đó, nó sử dụng gốc dốc ngẫu nhiên để huấn luyện các thiên vị và vectơ nhân tố.

Các chi tiết SVDSVD++thuật toán cho hệ thống đề xuất có thể được tìm thấy trong Phần 5.3.15.3.2của cuốn sách Francesco Ricci, Lior Rokach, Bracha Shapira, and Paul B. Kantor. Recommender Systems Handbook. 1st edition, 2010.

Trong Python, có một gói được thiết lập tốt đã triển khai các thuật toán có tên surprise. Trong tài liệu của mình , họ cũng đề cập đến các chi tiết của các thuật toán này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.