ฉันจะใช้ SVD ในการกรองร่วมกันได้อย่างไร


30

ฉันสับสนเล็กน้อยเกี่ยวกับวิธีการใช้ SVD ในการกรองร่วมกัน สมมติว่าฉันมีกราฟโซเชียลและสร้างเมทริกซ์คำคุณศัพท์จากขอบจากนั้นใช้ SVD (ลองลืมเกี่ยวกับการทำให้เป็นปกติอัตราการเรียนรู้การเพิ่มประสิทธิภาพการกระจัดกระจาย ฯลฯ ) ฉันจะใช้ SVD นี้เพื่อปรับปรุงคำแนะนำของฉันได้อย่างไร

สมมติว่ากราฟโซเชียลของฉันตรงกับ instagram และฉันได้รับมอบหมายหน้าที่ในการแนะนำผู้ใช้ในบริการโดยใช้กราฟโซเชียลเท่านั้น ฉันจะสร้างเมทริกซ์ adjacency A (m×m) , รับ SVD, A=UsV , เลือกeigenvalues แรกk, แล้วอะไร?

ฉันน่าจะสร้างเมทริกซ์ชุดใหม่: แล้วจะทำอะไรได้บ้าง?

Unewm×ksnewk×kVnewk×m

ฉันได้ดูบนเว็บและลิงค์ส่วนใหญ่มุ่งเน้นไปที่การคำนวณ SVD แต่ไม่มีใครบอกคุณว่าจะทำอย่างไรกับมัน แล้วฉันควรทำอย่างไรดี?


1
สิ่งนี้อาจตอบคำถามของคุณ: datascience.stackexchange.com/a/16523
avli

คำตอบ:


7

อย่างไรก็ตาม: ด้วย vanilla SVD ที่บริสุทธิ์คุณอาจมีปัญหาในการสร้างเมทริกซ์ดั้งเดิมให้คาดการณ์ค่าสำหรับรายการที่หายไปเพียงอย่างเดียว กฎการใช้นิ้วโป้งที่มีประโยชน์ในพื้นที่นี้กำลังคำนวณคะแนนเฉลี่ยต่อภาพยนตร์และลบค่าเฉลี่ยนี้สำหรับผู้ใช้ / ภาพยนตร์แต่ละชุดนั่นคือการลบอคติภาพยนตร์จากผู้ใช้แต่ละคน จากนั้นขอแนะนำให้คุณรัน SVD และแน่นอนว่าคุณจะต้องบันทึกค่าอคติเหล่านี้ที่อื่นเพื่อสร้างเรตติ้งใหม่หรือคาดการณ์ค่าที่ไม่รู้จัก ฉันได้อ่านคำแนะนำของ Simon Funk ใน SVD สำหรับคำแนะนำ - เขาคิดค้นวิธี SVD ที่เพิ่มขึ้นในระหว่างการแข่งขัน Netflix

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

ฉันเดาว่าเมทริกซ์การลดทอน A ก่อน SVD สมเหตุสมผลเนื่องจากลูกพี่ลูกน้อง PCA ที่ใกล้ชิดของ SVD ก็ทำงานในลักษณะเดียวกัน ในแง่ของการคำนวณแบบเพิ่มหน่วย Funk บอกฉันว่าถ้าคุณไม่ดูหมิ่นทิศทางการไล่ระดับสีแรกจะควบคุมส่วนที่เหลือของการคำนวณ ฉันเคยเห็นสิ่งนี้โดยตรงโดยทั่วไปโดยไม่ลดทอนสิ่งที่ไม่ทำงาน


24

ฉันต้องการเสนอความเห็นที่ไม่เห็นด้วย:

ขอบที่หายไปเป็นค่าที่หายไป

ในปัญหาการกรองแบบทำงานร่วมกันการเชื่อมต่อที่ไม่มีอยู่ (ผู้ใช้ไม่ได้ให้คะแนนรายการj , คนxไม่มีเพื่อนที่เป็นมิตรy ) โดยทั่วไปถือว่าเป็นค่าที่หายไปที่คาดการณ์ไว้แทนที่จะเป็นศูนย์ นั่นคือถ้าผู้ใช้ผมยังไม่ได้รับการจัดอันดับรายการJเราต้องการที่จะคาดเดาสิ่งที่เขาอาจจะให้คะแนนถ้าเขาได้รับการจัดอันดับมัน หากบุคคลxไม่ได้เป็นเพื่อนกับyเราต้องการเดาว่าเป็นไปได้อย่างไรที่เขาต้องการเป็นเพื่อนกับเขา คำแนะนำจะขึ้นอยู่กับค่าที่สร้างขึ้นใหม่ijxyijxy

เมื่อคุณใช้ SVD ของกราฟโซเชียล (เช่นเสียบผ่าน svd() ) คุณจะใส่ศูนย์ในจุดที่หายไปทั้งหมด นี่เป็นปัญหาที่ชัดเจนมากขึ้นในการตั้งค่าผู้ใช้รายการคะแนนสำหรับการกรองร่วมกัน หากฉันมีวิธีที่จะกรอกข้อมูลในรายการที่หายไปอย่างน่าเชื่อถือฉันไม่จำเป็นต้องใช้ SVD เลย ฉันแค่ให้คำแนะนำตามรายการที่กรอกไว้ ถ้าฉันไม่มีวิธีทำเช่นนั้นฉันไม่ควรเติมพวกเขาก่อนที่ฉันจะทำ SVD *

SVD พร้อมค่าที่หายไป

แน่นอนsvd()ฟังก์ชั่นไม่ทราบวิธีจัดการกับค่าที่หายไป ดังนั้นสิ่งที่คุณควรทำคืออะไร? มีวิธีที่จะเปลี่ยนปัญหาเป็น

"ค้นหาเมทริกซ์ของอันดับซึ่งใกล้เคียงกับเมทริกซ์ดั้งเดิม"k

นั่นเป็นปัญหาที่คุณพยายามแก้ไขและคุณจะไม่ใช้svd()เพื่อแก้ปัญหา วิธีการทำงานสำหรับฉัน (บนข้อมูลรางวัล Netflix) คือ:

  • Xฉัน, J = μ + α ฉัน + βเจ มันใช้งานได้ดีจริง ๆX^i,j=μ+αi+βj

  • ikuijkvjkuimvjm

  • ใช้อัลกอริทึมเพื่อค้นหาเวกเตอร์ที่ลดระยะห่างจากเมทริกซ์ดั้งเดิม ตัวอย่างเช่นใช้กระดาษนี้

ขอให้โชคดี!

*: สิ่งที่ Tenali แนะนำคือเพื่อนบ้านที่อยู่ใกล้ที่สุด คุณพยายามค้นหาผู้ใช้ที่มีลักษณะคล้ายกันและให้คำแนะนำเกี่ยวกับสิ่งนั้น น่าเสียดายที่ปัญหาการกระจัดกระจาย (ประมาณ 99% ของเมทริกซ์คือค่าที่หายไป) ทำให้การค้นหาเพื่อนบ้านที่ใกล้ที่สุดโดยใช้ระยะทางโคไซน์หรือความคล้ายคลึงกันของ Jaccard หรืออะไรก็ตาม ดังนั้นเขาแนะนำให้ทำ SVD ของเมทริกซ์ (โดยมีศูนย์ที่ใส่ค่าที่หายไป) เพื่อบีบอัดผู้ใช้ในพื้นที่ที่มีขนาดเล็กกว่าก่อนแล้วจึงทำการเปรียบเทียบที่นั่น การทำ SVD- เพื่อนบ้านที่ใกล้เคียงนั้นดี แต่ฉันขอแนะนำให้ทำ SVD อย่างถูกวิธี (ฉันหมายถึง ... ทางของฉัน) ไม่จำเป็นต้องใส่ค่าที่ไร้สาระ!


นี่เป็นคำตอบที่ฉันต้องการและต้องการที่จะได้ยิน :) ขอบคุณมาก!
Vishal

คำถามที่ถามผิดปกติ "ฉันดูเว็บแล้วและลิงก์ส่วนใหญ่มุ่งเน้นไปที่การคำนวณ SVD แต่ไม่มีใครบอกคุณว่าต้องทำอะไรกับมันฉันควรทำอย่างไรดี" หรือสำหรับเรื่องที่ชื่อกล่าวว่า "ฉันจะใช้ SVD ในการกรองร่วมกันได้อย่างไร"
TenaliRaman

ใช่และคำตอบของฉันสรุปว่าฉันจะใช้มันอย่างไรในการกรองร่วมกัน
Stumpy Joe Pete

1
+1, as I understand it, you're not compute the low rank matrix using SVD, but a iterative method to minimize the squared error, right? However, if I do want to use SVD, then I should fill in the missing entries with some values before I do the matrix factorization, right?
avocado

1
So when they say they used svd, they didn't mean using svd() to do the matrix factorization? The reason why they say svd, is because the result or the basic idea behind this iterative solution resembles svd?
avocado

14

The reason no one tells you what to do with it is because if you know what SVD does, then it is a bit obvious what to do with it :-).

Since your rows and columns are the same set, I will explain this through a different matrix A. Let the matrix A be such that rows are the users and the columns are the items that the user likes. Note that this matrix need not be symmetric, but in your case, I guess it turns out to be symmetric. One way to think of SVD is as follows : SVD finds a hidden feature space where the users and items they like have feature vectors that are closely aligned.

So, when we compute A=U×s×V, the U matrix represents the feature vectors corresponding to the users in the hidden feature space and the V matrix represents the feature vectors corresponding to the items in the hidden feature space.

Now, if I give you two vectors from the same feature space and ask you to find if they are similar, what is the simplest thing that you can think of for accomplishing that? Dot product.

So, if I want to see user i likes item j, all I need to do is take the dot product of the ith entry in U and jth entry in V. Of course, dot product is by no means the only thing you can apply, any similarity measure that you can think of is applicable.


Two questions: 1) Do you fill missing values with zero (item j not reviewed by user i) before running SVD? 2) How do you compute if a new user will like item j?
B_Miner

1
@B_Miner Hi, sorry for the delayed response. The answers: 1) Well, yes, we usually fill the missing values with zero before running SVD. However, I usually recommend to fill it with non-zero rating - for example, you can fill the missing values by the average rating that the user has given so far. 2) SVD-based approach is for only known users and known items. It cannot handle new users or new items. And how can it, if a new user comes in, we don't know anything about him in this framework to predict.
TenaliRaman

1
@B_Miner If you want to work with new users/items, we have to assume that we have access to some user features and item features. Then, you can use a more sophisticated model like PDLF (Predictive Discrete Latent Factor model). This will allow you to handle new users/items because it works with a known feature space.
TenaliRaman

@TenaliRaman Not sure if you'll see this, but here goes. So I've been using topic models (LDA) to build features for users (literally users) based on documents they've read. I just average the topic vectors to get a "user-topic vector". I want to do something similar with SVD (or ALS possibly). Let's say I compute SVD using known user-item data, and then I have new users that "visit" several known items. In this case the item vectors are known but the user vectors are unknown. Can I use the item vectors to calculate the user vector or do I need to compute SVD again using all data?
thecity2

great answer tenali. very helpful for understanding the concept
Nihal

3

This is to try and answer the "how to" part of the question for those who want to practically implement sparse-SVD recommendations or inspect source code for the details. You can use an off-the-shelf FOSS software to model sparse-SVD. For example, vowpal wabbit, libFM, or redsvd.

vowpal wabbit has 3 implementations of "SVD-like" algorithms (each selectable by one of 3 command line options). Strictly speaking these should be called "approximate, iterative, matrix factorization" rather than pure "classic "SVD" but they are closely related to SVD. You may think of them as a very computationally-efficient approximate SVD-factorization of a sparse (mostly zeroes) matrix.

Here's a full, working recipe for doing Netflix style movie recommendations with vowpal wabbit and its "low-ranked quadratic" (--lrq) option which seems to work best for me:

Data set format file ratings.vw (each rating on one line by user and movie):

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

Where the 1st number is the rating (1 to 5 stars) followed by the ID of user who rated and and the movie ID that was rated.

Test data is in the same format but can (optionally) omit the ratings column:

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

optionally because to evaluate/test predictions we need ratings to compare the predictions to. If we omit the ratings, vowpal wabbit will still predict the ratings but won't be able to estimate the prediction error (predicted values vs actual values in the data).

To train we ask vowpal wabbit to find a set of N latent interaction factors between users and movies they like (or dislike). You may think about this as finding common themes where similar users rate a subset of movies in a similar way and using these common themes to predict how a user would rate a movie he hasn't rated yet.

vw options and arguments we need to use:

  • --lrq <x><y><N> finds "low-ranked quadratic" latent-factors.
  • <x><y> : "um" means cross the u[sers] and m[ovie] name-spaces in the data-set. Note that only the 1st letter in each name-space is used with the --lrq option.
  • <N> : N=14 below is the number of latent factors we want to find
  • -f model_filename: write the final model into model_filename

So a simple full training command would be:

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

Once we have the ratings.model model file, we can use it to predict additional ratings on a new data-set more_ratings.vw:

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

The predictions will be written to the file more_ratings.predicted.

Using demo/movielens in the vowpalwabbit source tree, I get ~0.693 MAE (Mean Absolute Error) after training on 1 million user/movie ratings ml-1m.ratings.train.vw with 14 latent-factors (meaning that the SVD middle matrix is a 14x14 rows x columns matrix) and testing on the independent test-set ml-1m.ratings.test.vw. How good is 0.69 MAE? For the full range of possible predictions, including the unrated (0) case [0 to 5], a 0.69 error is ~13.8% (0.69/5.0) of the full range, i.e. about 86.2% accuracy (1 - 0.138).

You can find examples and a full demo for a similar data-set (movielens) with documentation in the vowpal wabbit source tree on github:

Notes:

  • The movielens demo uses several options I omitted (for simplicity) from my example: in particular --loss_function quantile, --adaptive, and --invariant
  • The --lrq implementation in vw is much faster than --rank, in particular when storing and loading the models.

Credits:

  • --rank vw option was implemented by Jake Hofman
  • --lrq vw option (with optional dropout) was implemented by Paul Minero
  • vowpal wabbit (aka vw) is the brain child of John Langford

1

I would say that the name SVD is misleading. In fact, the SVD method in recommender system doesn't directly use SVD factorization. Instead, it uses stochastic gradient descent to train the biases and factor vectors.

The details of the SVD and SVD++ algorithms for recommender system can be found in Sections 5.3.1 and 5.3.2 of the book Francesco Ricci, Lior Rokach, Bracha Shapira, and Paul B. Kantor. Recommender Systems Handbook. 1st edition, 2010.

In Python, there is a well-established package implemented these algorithms named surprise. In its documentation, they also mention the details of these algorithms.

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.