Tweak feed algorithm

This commit is contained in:
James Grugett 2022-04-30 11:34:53 -04:00
parent 54221f623c
commit 43a0fc6581
3 changed files with 47 additions and 22 deletions

View File

@ -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):

View File

@ -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 () => {

View File

@ -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) {