Tweak feed algorithm
This commit is contained in:
		
							parent
							
								
									54221f623c
								
							
						
					
					
						commit
						43a0fc6581
					
				| 
						 | 
					@ -119,21 +119,27 @@ export const getWordScores = (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const factor =
 | 
					      const factor =
 | 
				
			||||||
        -1 * Math.log(viewCount + 1) +
 | 
					        -1 * Math.log(viewCount + 1) +
 | 
				
			||||||
        3 * Math.log(clickCount + 1) +
 | 
					        10 * Math.log(betCount + clickCount / 4 + 1)
 | 
				
			||||||
        10 * Math.log(betCount + 1)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return _.mapValues(wordsTfIdf, (tfIdf) => tfIdf * factor)
 | 
					      return _.mapValues(wordsTfIdf, (tfIdf) => tfIdf * factor)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const wordScores = Object.values(contractWordScores).reduce(addObjects, {})
 | 
					  const wordScores = Object.values(contractWordScores).reduce(addObjects, {})
 | 
				
			||||||
 | 
					  const minScore = Math.min(...Object.values(wordScores))
 | 
				
			||||||
  console.log(
 | 
					  const maxScore = Math.max(...Object.values(wordScores))
 | 
				
			||||||
    'your word scores',
 | 
					  const normalizedWordScores = _.mapValues(
 | 
				
			||||||
    _.sortBy(_.toPairs(wordScores), ([, score]) => -score).slice(0, 10)
 | 
					    wordScores,
 | 
				
			||||||
 | 
					    (score) => (score - minScore) / (maxScore - minScore)
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return wordScores
 | 
					  // console.log(
 | 
				
			||||||
 | 
					  //   'your word scores',
 | 
				
			||||||
 | 
					  //   _.sortBy(_.toPairs(normalizedWordScores), ([, score]) => -score).slice(0, 100),
 | 
				
			||||||
 | 
					  //   _.sortBy(_.toPairs(normalizedWordScores), ([, score]) => -score).slice(-100)
 | 
				
			||||||
 | 
					  // )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return normalizedWordScores
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function getContractScores(
 | 
					export function getContractScores(
 | 
				
			||||||
| 
						 | 
					@ -149,10 +155,23 @@ export function getContractScores(
 | 
				
			||||||
      return wordFreq * weight
 | 
					      return wordFreq * weight
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return [contract.id, score] as [string, number]
 | 
					    return [contract, score] as [Contract, number]
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return _.fromPairs(scorePairs)
 | 
					  /*
 | 
				
			||||||
 | 
					  const questionPairs = _.sortBy(
 | 
				
			||||||
 | 
					    scorePairs.map(
 | 
				
			||||||
 | 
					      ([contract, score]) => [contract.question, score] as [string, number]
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    ([, score]) => -score
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  console.log('score', questionPairs.slice(0, 100), questionPairs.slice(-100))
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return _.fromPairs(
 | 
				
			||||||
 | 
					    scorePairs.map(([contract, score]) => [contract.id, score])
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Caluculate Term Frequency-Inverse Document Frequency (TF-IDF):
 | 
					// Caluculate Term Frequency-Inverse Document Frequency (TF-IDF):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,10 @@ async function updateFeed() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const contracts = await getValues<Contract>(firestore.collection('contracts'))
 | 
					  const contracts = await getValues<Contract>(firestore.collection('contracts'))
 | 
				
			||||||
  const feedContracts = await getFeedContracts()
 | 
					  const feedContracts = await getFeedContracts()
 | 
				
			||||||
  const users = await getValues<User>(firestore.collection('users'))
 | 
					  const users = await getValues<User>(
 | 
				
			||||||
 | 
					    firestore.collection('users')
 | 
				
			||||||
 | 
					    //.where('username', '==', 'JamesGrugett')
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  await batchedWaitAll(
 | 
					  await batchedWaitAll(
 | 
				
			||||||
    users.map((user) => async () => {
 | 
					    users.map((user) => async () => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ import { batchedWaitAll } from '../../common/util/promise'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const firestore = admin.firestore()
 | 
					const firestore = admin.firestore()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const MAX_FEED_CONTRACTS = 60
 | 
					const MAX_FEED_CONTRACTS = 75
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const updateUserFeed = functions.pubsub
 | 
					export const updateUserFeed = functions.pubsub
 | 
				
			||||||
  .schedule('every 60 minutes')
 | 
					  .schedule('every 60 minutes')
 | 
				
			||||||
| 
						 | 
					@ -119,9 +119,14 @@ function getActivityScore(contract: Contract, viewTime: number | undefined) {
 | 
				
			||||||
    lastCommentTime && (!viewTime || lastCommentTime > viewTime)
 | 
					    lastCommentTime && (!viewTime || lastCommentTime > viewTime)
 | 
				
			||||||
  const newCommentScore = hasNewComments ? 1 : 0.5
 | 
					  const newCommentScore = hasNewComments ? 1 : 0.5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const timeSinceLastComment = Date.now() - (lastCommentTime ?? createdTime)
 | 
				
			||||||
 | 
					  const commentDaysAgo = timeSinceLastComment / DAY_MS
 | 
				
			||||||
 | 
					  const commentTimeScore =
 | 
				
			||||||
 | 
					    0.25 + 0.75 * (1 - logInterpolation(0, 3, commentDaysAgo))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const timeSinceLastBet = Date.now() - (lastBetTime ?? createdTime)
 | 
					  const timeSinceLastBet = Date.now() - (lastBetTime ?? createdTime)
 | 
				
			||||||
  const daysAgo = timeSinceLastBet / DAY_MS
 | 
					  const betDaysAgo = timeSinceLastBet / DAY_MS
 | 
				
			||||||
  const betTimeScore = 1 - logInterpolation(0, 3, daysAgo)
 | 
					  const betTimeScore = 0.5 + 0.5 * (1 - logInterpolation(0, 3, betDaysAgo))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let prob = 0.5
 | 
					  let prob = 0.5
 | 
				
			||||||
  if (outcomeType === 'BINARY') {
 | 
					  if (outcomeType === 'BINARY') {
 | 
				
			||||||
| 
						 | 
					@ -134,14 +139,12 @@ function getActivityScore(contract: Contract, viewTime: number | undefined) {
 | 
				
			||||||
  const frac = 1 - Math.abs(prob - 0.5) ** 2 / 0.25
 | 
					  const frac = 1 - Math.abs(prob - 0.5) ** 2 / 0.25
 | 
				
			||||||
  const probScore = 0.5 + frac * 0.5
 | 
					  const probScore = 0.5 + frac * 0.5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const { volume24Hours, volume7Days, volume } = contract
 | 
					  const { volume24Hours, volume7Days } = contract
 | 
				
			||||||
  const combinedVolume =
 | 
					  const combinedVolume = Math.log(volume24Hours + 1) + Math.log(volume7Days + 1)
 | 
				
			||||||
    Math.log(volume24Hours + 1) +
 | 
					  const volumeScore = 0.5 + 0.5 * logInterpolation(4, 20, combinedVolume)
 | 
				
			||||||
    Math.log(volume7Days + 1) +
 | 
					 | 
				
			||||||
    Math.log(volume + 1)
 | 
					 | 
				
			||||||
  const volumeScore = 0.5 + 0.5 * logInterpolation(7, 35, combinedVolume)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const score = newCommentScore * betTimeScore * probScore * volumeScore
 | 
					  const score =
 | 
				
			||||||
 | 
					    newCommentScore * commentTimeScore * betTimeScore * probScore * volumeScore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Map score to [0.5, 1] since no recent activty is not a deal breaker.
 | 
					  // Map score to [0.5, 1] since no recent activty is not a deal breaker.
 | 
				
			||||||
  const mappedScore = 0.5 + 0.5 * score
 | 
					  const mappedScore = 0.5 + 0.5 * score
 | 
				
			||||||
| 
						 | 
					@ -160,11 +163,11 @@ function getLastViewedScore(viewTime: number | undefined) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (daysAgo < 0.5) {
 | 
					  if (daysAgo < 0.5) {
 | 
				
			||||||
    const frac = logInterpolation(0, 0.5, daysAgo)
 | 
					    const frac = logInterpolation(0, 0.5, daysAgo)
 | 
				
			||||||
    return 0.5 * frac
 | 
					    return 0.5 + 0.25 * frac
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const frac = logInterpolation(0.5, 14, daysAgo)
 | 
					  const frac = logInterpolation(0.5, 14, daysAgo)
 | 
				
			||||||
  return 0.5 + 0.5 * frac
 | 
					  return 0.75 + 0.25 * frac
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function getRecentBetsAndComments(contract: Contract) {
 | 
					async function getRecentBetsAndComments(contract: Contract) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user