JavaScript implementation recommendation algorithm based on collaborative filtering

The following source code into a js file, such as naming: index.js;

1. Installation depends: npm i lodash --save // ​​this is a formatted data repository

2. When introduced to: import {RecommendUserService, RecommendGoodsService} from index.js // sets algorithm, based on a set of users, based on an article

3. Two similar algorithm used:

A user-based algorithm (RecommendUserService), there are three parameters data, userId, n // first two parameters mandatory, optional third

data format [{userId: 1, goodsId: 11}, {userId: 2, goodsId: 222} ...] // This data item is inverted user table, that is, each user has to purchase a product generates a one data

userId is a string or a number, it is to generate personalized recommendations for the user ID

n is a positive integer, is to take the highest similarity before n users, this value is not fixed, the current site of big data is the most accurate 10

Use: const = recommendUserService new new RecommendUserService (Data, the userId, n-)

     const result = recommendUserService.start()

     // result is the result returned is a one-dimensional array: [goodsId1, goodsId2 ......], users of commodities of interest in the reverse order of the commodity ID, user interest is goodsId1 is the highest commodity ID, to such push

Second, the algorithm article (RecommendGoodsService) based on the three parameters are data, userId, n // mandatory first parameter, the last two optional

data format [{userId: 1, goodsId: 11}, {userId: 2, goodsId: 222} ...] // This data item is inverted user table, there is a commodity to be purchased for each user generates a one data for a

userId is a string or a number, it is to generate personalized recommendations for the user ID

n is a positive integer, is to take the highest similarity of the first n commodities, this value is not fixed, the current site of big data is the most accurate 10

Use: const = recommendGoodsService new new RecommendGoodsService (Data, the userId, n-) // generate personalized recommendations

     const result = recommendGoodsService.start()

     // result is the result returned is a one-dimensional array: [goodsId1, goodsId2 ......], users of commodities of interest in the reverse order of the commodity ID, user interest is goodsId1 is the highest commodity ID, to such push

     // subsystem, calculates the most similar merchandise goods goodsId first n

     const recommendGoodsService = new RecommendGoodsService(data, userId, n)

     // userId is empty only to calculate the similarity of goods, not empty then exclude bought their own goods; goodsId was calculated target

     const result = recommendGoodsService.getGoodsGrade(userId,  goodsId) 

     // result is the result returned is a one-dimensional array: [goodsId1, goodsId2 ......], id is the list of the most similar to the first n items goodsId

 

The following is the source -------- -------

the require _ = const ( 'lodash')
// recommended to the user based on
const RecommendUserService class RecommendUserService = {
/ **
* constructor
* @param {* reverse lookup data array composed of all Data}
* @param {* User ID} userId
* @param {* highest similarity to the first n n}
* /
constructor (Data, the userId, n) {
this.data = Data
this.userId the userId =
this.n = n
// similarity molecule
this.top = undefined
// similarity denominator
this.bottom = undefined
// other than the user's own record, all other users ID
this.userArray = []
// as the intermediate value, ongoing record of other users list of items
this.userGoodsTemp = []
// record the final user similarity list
this.similarityList = []
// first n records in the user similarity purchase of goods and user of the present product does not overlap
this.targetGoods = []
// record the degree of each item of interest to the user screened
this.interestedGrade = [];
// record the final results returned
this.result = []
}
/ **
* entry
* /
Start () {
// similarity is calculated , to conclude that the user and all other users similarity score
this.getUserArray ()
this.similarityList.sort ((a, B) => {
return b.grade - a.grade
})
// calculate the target product
this.getTargetGoods ()
// this time the target product already exists this.targetGoods, and then go heavy
this.targetGoods = [... new Set (this.targetGoods )]

// user level of interest is calculated for each item
for (the let goodsId of this.targetGoods.values ()) {
this.getInterestedGrade (goodsId)
}
// calculate the final list of items and decommitment
this.getFinalResult ()
return the this. Result
}
/ **
* calculated final list of items and decommitment
* /
getFinalResult () {
this.interestedGrade.sort ((A, B) => {
return b.grade - a.grade
})
for (the let of the this obj. interestedGrade.values ()) {
this.result.push (obj.goodsId)
}
}
/ **
* calculation of the level of interest the user product
* @param {*} goodsId commodity ID
* /
getInterestedGrade (goodsId) {
// user selected commodity goodsId used behavior
let array = new Set ()
for (obj of the let this.data.values ()) {
IF (obj.goodsId === goodsId) {
array.add (obj.userId)
}
}
const Users = [... Array]
// calculate the degree of interest
Grade 0 = the let
for (the userId of the let users.values ()) {
for (the let I = 0; I <this.n; I ++) {
IF (this.similarityList the userId === [I] .userId) {
const RES this.getUserSimilarity = (the userId, this.similarityList [I] .userId)
Grade = RES +
}
}
}
// added to the final result
this.interestedGrade.push ({
goodsId: goodsId,
Grade: Grade
})
}
/ **
* obtain the target product array
* /
getTargetGoods () {
This.n //> this.similarityList.length this.n = this.similarityList.l:? This.n = this.n
// Up to now, in order to obtain reverse order an array of user similarity, to obtain the following first n Similarly all the merchandise purchased by the user is not present the user bought
for (the let index = 0; index <this.n; index ++) {
const Element this.similarityList = [index]
_.filter (this.data, obj => {
IF (obj.userId == element.userId) {
this.targetGoods.push (obj.goodsId)
}
return obj.userId == element.userId
})
}
// remove the product itself, to give the final target product array
this.duplicateRemovalGoods ()

}
/ **
* product itself removed to give the final product certain array
* /
duplicateRemovalGoods () {
// Get current user commodity bought
const = userGoods _.filter (this.data, obj => {
return obj.userId = this.userId =
})
// remove this user bought goods
for (obj of the let userGoods.values ()) {
IF (this.targetGoods.includes (obj.goodsId)) {
this.targetGoods.splice (this.targetGoods .indexOf (obj.goodsId),. 1)
}
}
}
/ **
* Get the user's own user ID to all other things except
* /
getUserArray () {
const = _.filter Data (this.data, obj => {
return obj .userId! == this.userId
})
// Get all other user ID
the let arrayTemp = []
for (index in the let Data) {
arrayTemp.push (the Data [index] .userId)
}
this.userArray = [... (new new the Set (arrayTemp))]
// avoid this.n beyond the boundaries of
this.n> this.userArray.length? this.n = this.userArray.length: this.n = this.n
traverse // calculate the similarity of each user
for (index in the let this.userArray) {
this.getUserSimilarity (this.userId, this.userArray [index])
}
}
/ **
* calculated similarity of two users
* @param {*} the userId user ID
* @param {*} otherUserId another user ID
* /
getUserSimilarity (the userId, otherUserId) {
const = userSelfGoods _.filter (the this. Data, obj => {
return the userId == obj.userId
})
this.filterUserGoods (otherUserId)
// similarity is calculated denominator
= the Math.sqrt this.bottom (userSelfGoods.length * this.userGoodsTemp.length)
// record the number of similar goods
the let COUNT = 0
userSelfGoods.forEach (ELE => {
for (index in the let this.userGoodsTemp) {
IF ( == this.userGoodsTemp ele.goodsId [index] .goodsId) {
// penalty popular product, calculated penalty parameter
const this.filterGoodsById = log (ele.goodsId)
// weight weights may be added here, weight * log
COUNT + log =
}
}
})
this.top COUNT =
const {obj =
the userId: otherUserId,
Grade: this.top / this.bottom
}
this.similarityList.push (obj)
return obj.grade
}
/ **
* filtered user otherUserId item list
* @param {} otherUserId user ID
* /
filterUserGoods (otherUserId) {
this.userGoodsTemp = _.filter (this.data, obj => {
return obj.userId == otherUserId
})
}
/ **
* filtered list of items of commodities goodsId
* @param {ID} goodsId commodity
* /
filterGoodsById (goodsId) {
const = _.filter goods (this.data, obj => {
return obj.goodsId == goodsId
})
return. 1 / The Math.log (+ goods.length. 1)
}
}
// based article recommended
const RecommendGoodsService class RecommendGoodsService = {
/ **
* constructor
* @param {* reverse lookup array of all the data data}
* @param {*} goodsId commodity ID
* @param {*} the userId user ID
* @param { * the highest similarity first k k}
* /
constructor (Data, the userId, k, goodsId) {
this.data = Data
this.goodsId = goodsId
this.userId the userId =
// before screening the k ?????? Product ?????? a means for
the this = K .K
// save the product list to be calculated is a means for ······ ······
this.goodsList = []
// save the current list of merchandise the purchaser for ······ a module ······
this.users = []
// save the current product listing ?????? means for a similarity ······
this.simpleList = []
// open a second sub- system - module II
// save the current favorite products list
this.userPerferList = []
// save the current product list who have never bought a
this.goodsMayPerferList = []
// save the results and recommend ordering
this.resultRank = []
// The end result
this.result = []
}

/ **
* entry
* /
Start () {
// Get the data to be calculated
this.getInitialData ()
// user does not start to commodity bought the level of interest
for (let goodsId of this.goodsMayPerferList.values () ) {
this.getUserInterest RES = const (goodsId)
this.resultRank.push (RES)
}
// decommitment
this.resultRank.sort ((A, B) => {
return b.grade - a.grade
})
// Get the final results
this.result this.resultRank.reduce = ((Array, obj) => {
Array.push (obj.goodsId)
return Array
}, [])
return this.result
}
/ **
sense of users of the product is calculated * the level of interest
* @param {*} goodsId commodity ID
* /
getUserInterest (goodsId) {
// get the list of items similar goodsId
const = Simple this.getGoodsGrade (to false, goodsId)
the let Grade = 0
for (the let [index, obj] of simple.entries ()) {
IF (this.userPerferList.includes (obj.goodsId ) && index <this.k) {
Grade + = obj.grade
}
}
return {goodsId, Grade}
}
/ **
* Get the data to be calculated
* /
getInitialData () {
// get the current record's favorite
this.userPerferList = this.data.reduce ((Array, obj) => {
IF (obj.userId === this.userId &&! array.includes (obj.goodsId)) {
Array.push (obj.goodsId)
}
return Array
}, [])
// get the current user list of items not bought
this.goodsMayPerferList = this.data.reduce ((array, obj ) => {
IF (! array.includes (obj.goodsId) &&! this.userPerferList.includes (obj.goodsId)) {
Array.push (obj.goodsId)
}
return Array
}, [])
}
/ **
* Calculation commodity goodsId similar to the first k product list, a module ······ ······
* * @param {own associated merchandise if removed isDelSelf}
* * @param {} goodsId commodity ID
* /
getGoodsGrade (isDelSelf, goodsId) {
this.simpleList = []
this.goodsId = goodsId
// Get a list of goods to be calculated
this.getGoodsList ()
// get the current list of goods purchaser
this.users = this.getGoodsUserNum (this.goodsId)
// calculation similarity
for (the let goodsId of this.goodsList.values ()) {
this.getGoodsSimple (goodsId)
}
// sorted according to the similarity
this.simpleList.sort ((a, b) = > {
// descending
return b.grade - a.grade
})
// if exclude itself
IF (isDelSelf) {
this.getNotSelfGoods ()
}
// normalized similarity
this.gradeNormalization ()
return this.simpleList
}
/ **
* acquisition target product array
* /
getGoodsList () {
// filter commodity in addition to this data
const goodsArray this.data.reduce = ((array, obj) => {
IF (obj.goodsId! == this.goodsId ) {
Array.push (obj.goodsId)
}
return array
}, [])
// array and go deconstruction weight
const goods = [... the Set new new (goodsArray)]
// get the list of the target product
this.goodsList = goods
}
/ **
* remove the goods have been bought, to give the desired product array
* /
getNotSelfGoods () {
// The current user bought goods screening
const userGoods this.data.reduce = ((Array, obj) => {
IF (obj.userId === this.userId) {
Array.push (obj.goodsId )
}
return Array
}, [])
// remove this user bought goods
for (the let [index, obj] of this.simpleList.entries ()) {
IF (userGoods.includes (obj.goodsId)) {
the this. simpleList.splice (index,. 1)
}
}
}
/ **
* Get a list of goods similarity
* @param {} goodsId commodity ID
* /
getGoodsSimple (goodsId) {
const = this.getGoodsUserNum Users (goodsId)
// similarity calculation denominator
const bottom = Math.sqrt (this.users.length * users.length)
the let COUNT = 0
// number of common users two goods is calculated to give the degree of molecular met
for (users.values of the let Val ()) {
IF (this.users.includes (Val)) {
// penalty active user
count + = this. getSimpleElememt (Val)
}
}
// save result objects, including the product ID and the similarity
const RES = {
goodsId,
Grade: COUNT / bottom
}
this.simpleList.push (RES)
}
/ **
* boosting algorithm, to punish active users, similarity is calculated molecular
* @param {*} the userId user ID
* /
getSimpleElememt (the userId) {
// find the number of items the user bought
const goodsNum this.data.reduce = ((Array, obj) => {
IF (obj. === the userId the userId) {
Array.push (obj.goodsId)
}
return Array
}, [])
const COUNT = [... the Set new new (goodsNum)]. length
Element. 1 = const / The Math.log (COUNT +. 1)
return Element
}
/ **
* acquired commodity purchaser
* @param {*} goodsId commodity ID
* /
getGoodsUserNum (goodsId) {
// get the goods purchaser
const users this.data.reduce = ((Array, obj) => {
IF (obj.goodsId === goodsId) {
Array.push (obj.userId)
}
return Array
}, [])
return [the Set new new ... ( Users)];
}
/ **
* normalized similarity
* /
gradeNormalization () {
// takes the maximum value
const this.simpleList = max [0] .grade
for (index of the let this.simpleList.keys ()) {
this.simpleList [index] = .grade this.simpleList [index] .grade / max
}
}
}

module.exports = { RecommendUserService, RecommendGoodsService }

Guess you like

Origin www.cnblogs.com/dreamsnow/p/12545723.html