UNPKG

js-recommender

Version:

Package implements recommender system based on content collaborative filtering algorithm

1 lines 3.66 kB
var jsrecommender=jsrecommender||{};!function(t){t.copyArray=function(t){for(var e=[],s=0;s<t.length;++s)e.push(t[s]);return e},t.copyMap=function(t){var e={};for(var s in t)e[s]=t[s];return e};var e=function(){this.rowNames=[],this.columnNames=[],this.cells={},this.cellCount=0};e.prototype.cellKey=function(t,e){return(t=t.replace("-",""))+"-"+(e=e.replace("-",""))},e.prototype.getNames=function(t){var e=t.split("-");return{rowName:e[0],colName:e[1]}},e.prototype.addRowIfNotExists=function(t){for(var e=0;e<this.rowNames.length;++e)if(this.rowNames[e]==t)return;this.rowNames.push(t)},e.prototype.addColumnIfNotExists=function(t){for(var e=0;e<this.columnNames.length;++e)if(this.columnNames[e]==t)return;this.columnNames.push(t)},e.prototype.setCell=function(t,e,s){var t=t.replace("-",""),e=e.replace("-",""),r=this.cellKey(t,e),a=this.containsCell(t,e);this.cells[r]=s,a||(this.cellCount++,this.addRowIfNotExists(t),this.addColumnIfNotExists(e))},e.prototype.getCell=function(t,e){var s=this.cellKey(t,e);return this.cells[s]},e.prototype.containsCell=function(t,e){return this.cellKey(t,e)in this.cells},e.prototype.removeCell=function(t,e){this.containsCell(t,e)&&(this.cellCount--,delete this.cells[this.cellKey(t,e)])},e.prototype.makeCopy=function(){var s=new e;return s.rowNames=t.copyArray(this.rowNames),s.columnNames=t.copyArray(this.columnNames),s.cellCount=this.cellCount,s.cells=t.copyMap(this.cells),s},t.Table=e;var s=function(t){(t=t||{}).kDim||(t.kDim=2),t.alpha||(t.alpha=.01),t.lambda||(t.lambda=0),t.iterations||(t.iterations=500),this.kDim=t.kDim,this.alpha=t.alpha,this.lambda=t.lambda,this.iterations=t.iterations};s.prototype.fit=function(t){this.theta={},this.X={},this.columnNames=t.columnNames,this.rowNames=t.rowNames;for(i=0;i<this.columnNames.length;++i){for(var e=[],s=0;s<this.kDim;++s)e.push(Math.random());this.theta[this.columnNames[i]]=e}for(i=0;i<this.rowNames.length;++i){for(var r=[],s=0;s<this.kDim;++s)r.push(Math.random());this.X[this.rowNames[i]]=r}for(var a=0;a<this.iterations;++a){for(var o=this.gradTheta(t,this.theta,this.X),i=0;i<this.columnNames.length;++i)for(var h=this.columnNames[i],s=0;s<this.kDim;++s)this.theta[h][s]=this.theta[h][s]-this.alpha*o[h][s];for(var n=this.gradX(t,this.theta,this.X),i=0;i<this.rowNames.length;++i)for(var l=this.rowNames[i],s=0;s<this.kDim;++s)this.X[l][s]=this.X[l][s]-this.alpha*n[l][s]}return{theta:this.theta,X:this.X,rowNames:this.rowNames,columnNames:this.columnNames,config:{alpha:this.alpha,lambda:this.lambda,iterations:this.iterations}}},s.prototype.gradTheta=function(t,e,s){for(var r={},a=0;a<this.columnNames.length;++a){for(var o=this.columnNames[a],i=[],h=0;h<this.kDim;++h){var n=0;for(var l in t.cells){var m=t.getNames(l),c=m.colName,u=m.rowName;if(o==c){var p=t.cells[l];n+=(this.h(e,s,u,o)-p)*s[u][h]}}n+=this.lambda*e[o][h],i.push(n)}r[o]=i}return r},s.prototype.gradX=function(t,e,s){for(var r={},a=0;a<this.rowNames.length;++a){for(var o=this.rowNames[a],i=[],h=0;h<this.kDim;++h){var n=0;for(var l in t.cells){var m=t.getNames(l),c=m.colName;if(o==m.rowName){var u=t.cells[l];n+=(this.h(e,s,o,c)-u)*e[c][h]}}n+=this.lambda*s[o][h],i.push(n)}r[o]=i}return r},s.prototype.h=function(t,e,s,r){for(var a=0,o=0;o<this.kDim;++o)a+=t[r][o]*e[s][o];return a},s.prototype.transform=function(t){for(var t=t.makeCopy(),e=0;e<t.rowNames.length;++e)for(var s=t.rowNames[e],r=0;r<t.columnNames.length;++r){var a=t.columnNames[r],o=this.h(this.theta,this.X,s,a);t.setCell(s,a,o)}return t},s.prototype.fitAndTransform=function(t){return this.fit(t),this.transform(t)},t.Recommender=s}(jsrecommender);var module=module||{};module&&(module.exports=jsrecommender);