« Back Issue #489
  • 2021-12-27 01:37 Reported by anirudh95
  • 2022-12-15 15:58 Marked fixed
Status: Marked fixed
Priority: Medium

Hash2Vec for Yioop

anirudh95 2021-12-27 01:37

Enhancing Yioop's Recommendation System with Hash2Vec by creating context for words seen by users to improve scores of threads with similar words that would otherwise not get recommended because of a low tf-idf score.

administrator 2022-03-06 10:04

Hey Anirudh,

Thanks for this patch! I have a new student, Parth Patel, who is going to extend it and get a new patch ready for Yioop.

Best, Chris

patelpa 2022-05-10 17:25

Hi Professor,

I have uploaded a new patch with the refactored code of Anirudh's Hash2Vec approach.

Thanks, Parth

patelpa 2022-05-16 20:54

Hi Professor,

Uploading a new patch with the few changes we discussed.

Thanks, Parth

administrator 2022-07-12 11:25

Hey Parth,

Thanks for your patch! I applied it but then had to back it out because it had numerous issues. Below are my comments. When you have time make a new patch and upload it. In the note you add with your uploaded patch please indicate how you addressed these issues.

Best, Chris

(1) You should as part of the documentation to the recommendation job explain clearly somewhere how the two approaches to computing recommendations are computed rather than just say hash2vec approach. This clarity will help eliminate, unnecessary/bogus stuff in your next patch.

(2) Your patch creates a table USER_ITEM_SIMILARITY_HASH2VEC which is never used.

(3) You should avoid the phrase HASH2VEC in table names USER_TERM_WEIGHTS_HASH2VEC, HASH2VEC_TERM_SIMILARITY. There currently is no table named TERM_SIMILARITY so why not just call it that? Also, if the hash2vec method is being used can we get away with just having the table USER_TERM_WEIGHTS as the first thing you do is copy all of USER_TERM_WEIGHTS into USER_TERM_WEIGHTS_HASH2VEC?

(3) Why isn't there a table ITEM__TERM_WEIGHTS for the has2vec context?

(4) Do not use the vague notion word as part of variable names. Use term instead. So WORD_SPLIT_PATTERN should be TERM_SPLIT_PATTERN.

(5) See how terms are split in PhraseParser and use its mechanism rather make a new one .

(6) In initializeHash2Vec() the SQL code AND LOWER(DESCRIPTION) NOT LIKE '%-0700%' seems very fragile and not likely to work in general.

(7) Write null not NULL

(8) strtolower is not multi-byte safe so will garble non-English text. Use mb_strtolower.

(9) Code like if (C\RECOMMENDATION_TYPE == 1) { is mysterious. Nobody will know what 1 means. Make a constant for each possible recommendation type.

(10) The start of generateVectors' code is excessively complicated for what it is doing. For example, six lines of code is used to create a fixed (always same) array $context_distance_vector whose only use is to compute a variable $standard_deviation. Try to just use a closed formula for the fixed standard deviation in question. This would also eliminated the need for the function calculateStandardDeviation.

(11) The wordToId code seems fragile/method name doesn't adequately indicate the method's side-effects.

(12) Yioop has a LinearAlgebra class which contains dot products, etc which should be used rather than to rewrite these methods.

(13) normalizeVectors computes an L1 norm. Is that what was intended or did you want an L2 norm?

patelpa 2022-11-24 18:58

Hi Professor,

I am uploading a new patch, that contains the code for recommendation job updated to replace old recommendation mechanism for Groups and Threads, add recommendation support for Wiki Resources.

Note: Before apply this patch please apply the patch for this issue - https://www.seekquarry.com/mantis/view.php?id=252

recommendation.patch

patelpa 2022-11-28 15:41

Hi Professor,

Uploading updated patch to address the patch update for issue - https://www.seekquarry.com/mantis/view.php?id=252.

recommendation-2.patch

patelpa 2022-11-29 19:46

Hi Professor,

Uploading the patch with the changes we discussed today.

recommendation-3.patch

administrator 2022-11-29 23:05

Hi Parth,

Thanks for you patch. It has been applied and pushed to the git repository. The old recommendation tables had indexes on some of their columns to speed up querying. The two new tables have no indexes. Can look into if it makes sense to add indexes on some columns, and if so, make a patch with the appropriate CREATE INDEX commands.

Best, Chris

administrator 2022-12-01 17:10

HI Parth,

I tried testing your code out on the Yioop site. Postgres does not have a blob type. I fixed that by checking and using BYTEA instead. However, currently your code runs outs of memory after it tries to compute Item Embeddings. You seem to be trying to read in the whole RECOMMENDATION_ITEM_EMBEDDING into memory. I doubt that will work. Can you fix your code under the assumption that many of the database tables will be too large to fit in memory?

Chris

patelpa 2022-12-01 17:34

Hi Professor,

I am reading the entire table data in order to preserve the embeddings for items not calculated during the current run.

To avoid the memory issues due of reading all the values from DB, can we instead of deleting all the item embeddings only delete those existing item beddings which are updated in current run using IN operator on ID and providing list containing IDs of updated item embeddings?

administrator 2022-12-01 17:59

That sounds like it could work.

Best, Chris

patelpa 2022-12-01 18:03

Okay will try it and update the patch once done.

Thanks, Parth

patelpa 2022-12-01 19:56

Hi Professor,

Uploading a patch that tries to fix the out of memory. Please let me know if the fix worked for Yioop site or not.

Best, Parth

recommendation_fix.patch

administrator 2022-12-01 20:14

Applied and pushed that patch. It still fails with out of memory errors. For reference if dies at line 890 in computeWikiTermEmbeddings.

Chris

patelpa 2022-12-01 20:22

Thanks for the update. Should we meet to discuss more about it?

Best, Parth

administrator 2022-12-01 20:27

I am on Skype now if you want to do a short chat.

patelpa 2022-12-10 13:29

Hi Professor,

I have created a patch with the method we discussed regarding using LRU cache and pack-unpack method. Also created indices on GROUP_ITEM_RECOMMENDATION and GROUP_RESOURCE_RECOMMENDATION tables, did not create index for other table because they have primary keys defined on the columns which are used for lookup.

I tested this code by duplicating 3 times the resources created by ManyUserExperiment which totals to around 450 resources. The max memory usage reported while running recommendation job was 12616104. Not sure about the unit of this number. Also while writing pack binary strings to DB for items was created DB insert errors so had to unpack it to array and serialize for inserting.

recommendation_fix_cache.patch

administrator 2022-12-10 21:52

Hi Parth,

I get a lot of warnings where I try to run your patch such as:

Warning: pack(): 1 arguments unused in /Applications/MAMP/htdocs/git/yioop/src/library/media_jobs/RecommendationJob.php on line 384 PHP Warning: Undefined array key 0 in /Applications/MAMP/htdocs/git/yioop/src/library/media_jobs/RecommendationJob.php on line 378

Switch d to E for the pack format. It looked like you had sqlite3 and mysql specific SQL code, but Yioop uses Postgres. Is there a way to avoid this, or can you push it into the datasource manager? Have you tested the recommendations after the change? When I looked at the embeddings after this patch, I was getting just blank strings. I also wasn't sure on the issue of needing to do serialize, but I was worried that these might be connected. Finally, I couldn't understand what the intent of the line: $embedding = serialize(unpack("E$this->size", $embedding)); was. It seems to me that in the database it should be a packed string. If you are worried about putting binary data, i don't think it should cause a problem, but you could try base64 encoding if it was.

patelpa 2022-12-11 11:23

Hi Professor,

I tested the patch on fresh copy of Yioop and it worked without any issue for my machine having Sqlite3 DB.

Will switch d to E for pack formatting. For $embedding = serialize(unpack("E$this->size", $embedding)); - I had to do this because directly writing binary string to DB for item_embeddings was giving DB errors, not exactly sure why because the same thing for term embeddings worked without any error. I will try to revise the patch and upload it once done.

administrator 2022-12-11 13:20

Its got to work cross platform to be considered working. The warnings I get are on a fresh copy of Yioop. Did you make sure to turn on error reporting in the configure activity so you can see all errors? Did you check that it is making non-zero embeddings after the change? (What I am getting). I would switch to base64 for storage into DB rather than serialize if this is really necessary.

patelpa 2022-12-11 13:53

Hi Professor,

I just turned on the errors reporting and now I see the warnings you mentioned. Also I am getting the zero embeddings. Working again on the pack and unpack thing.

patelpa 2022-12-11 16:56

Hi Professor,

When you tested last time, where all the embedding values zero or it had values at few index?

administrator 2022-12-11 17:09

I just checked, a few were non zero.

patelpa 2022-12-11 17:28

One reason could be fresh copy of Yioop does not have proper thread data, which could lead to zero embedding vectors for terms. I created 10 threads with around 50 terms in each and I could see more non-zero values in term embeddings.

Let me know if you think this could be the reason and I will create a patch and upload here.

administrator 2022-12-11 17:36

It probably is the reason, go ahead and create a new patch and I'll try it out. Just make sure it gets rid of the warnings.

Best, Chris

patelpa 2022-12-11 17:39

Yeah I got rid of all PHP warnings. Did you face any DB errors when you tested?

Best, Parth

administrator 2022-12-11 18:10

I haven't pushed it to the Postgres site (YIoop), because I was worried about the other issues first. You should avoid having Sqlite and Mysql specific code though.

patelpa 2022-12-11 19:23

Hi Professor,

Uploading the revised patch. Used base64 encoding - decoding for writing to DB. Also tried to use general SQL code, but not 100% sure if something is not supported by Postgres.

Best, Parth

recommendation_fix_cache-2.patch

administrator 2022-12-11 20:28

This patch seems not to give warnings which is good. It seems to be taking a while to process recommendation, during which time it is not giving any log messages. Can you do a git pull and see how I've added a couple L\crawlTimeoutLog messages in a nested for situation which might run more than 30 seconds. Can you add L\crawlTimeoutLog's in other places where this might happen? I am still waiting for my current test to complete.

Best,

Chris

patelpa 2022-12-11 20:45

Sure adding it. Are you testing on fresh copy of Yioop or live site?

Best, Parth

administrator 2022-12-11 20:45

It took much longer for it to die. But it still gives an out of memory error at line 903.

administrator 2022-12-11 20:48

Testing on pollett.org, which is a smaller live site.

patelpa 2022-12-11 20:51

Oh no, so now what else can we try?

administrator 2022-12-11 20:56

Maybe we just reduce the size of the LRU cache to 500 and see if it works.

patelpa 2022-12-11 21:01

Yeah we can try reducing cache size. Other thing is we can limit the number of resources to process in a single run just like group items?

administrator 2022-12-11 21:04

Yeah, we should do that too.

patelpa 2022-12-11 21:07

Okay will upload new patch with these changes.

patelpa 2022-12-11 22:23

Hi Professor,

Created patch with below changes 1. Reduced cache size to 500 2. Added limit of 200 resources to process at a time 3. Added timeout logs

Best, Parth

recommendation_fix_cache-3.patch

administrator 2022-12-12 00:36

So it doesn't crash now! It is giving databased locked errors when it does it first set of inserts into a sqlite db. I will probably investigate tomorrow.

patelpa 2022-12-15 08:50

Hi Professor,

Uploading a patch with changes to RECOMMENDATION_TERM_EMBEDDING table where ID column is now VARCHAR(16) to store canonicalTerm as id instead of integer id.

canonical_term.patch

administrator 2022-12-15 15:58

Thanks Parth, Anirudh, for your work on this issue. A version that doesn't give errors for SQLITE, MYSQL, and Postgres commited with 9cde4c6ecc76e. The last issue with database locking in Sqlite resolved by processing group items in batches. Thanks Parth, for the switch to using canonicalTerm for term_id's.

anirudh95 2022-12-15 15:58
X