feat(home): 크리에이터 랭킹 점수 정책을 변경한다
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
package kr.co.vividnext.sodalive.v2.ranking.domain
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.databind.SerializationFeature
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import java.time.LocalDateTime
|
||||
|
||||
data class CreatorRankingScoreDetail(
|
||||
val scorePolicyVersion: String = CreatorRankingScoreSpec.SCORE_POLICY_VERSION,
|
||||
val formula: String = CreatorRankingScoreSpec.FORMULA,
|
||||
val metrics: Metrics,
|
||||
val tieBreakers: TieBreakers
|
||||
) {
|
||||
fun toJson(): String = objectMapper.writeValueAsString(this)
|
||||
|
||||
data class Metrics(
|
||||
val liveRevenue: Metric,
|
||||
val contentRevenue: Metric,
|
||||
val followIncrease: Metric,
|
||||
val aiChat: Metric
|
||||
)
|
||||
|
||||
data class Metric(
|
||||
val rawValue: Long,
|
||||
val rank: Int,
|
||||
val rankScore: Double,
|
||||
val weight: Double,
|
||||
val weightedScore: Double
|
||||
)
|
||||
|
||||
data class TieBreakers(
|
||||
val creatorDebutAt: LocalDateTime?,
|
||||
val creatorId: Long
|
||||
)
|
||||
|
||||
companion object {
|
||||
private val objectMapper: ObjectMapper = jacksonObjectMapper()
|
||||
.registerModule(JavaTimeModule())
|
||||
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||
}
|
||||
}
|
||||
@@ -1,49 +1,24 @@
|
||||
package kr.co.vividnext.sodalive.v2.ranking.domain
|
||||
|
||||
class CreatorRankingScorePolicy {
|
||||
fun calculateContentLiveScore(
|
||||
liveCanAmount: Long,
|
||||
contentPurchaseCanAmount: Long
|
||||
): Double {
|
||||
return (liveCanAmount * CreatorRankingScoreSpec.CONTENT_LIVE_CAN_WEIGHT) +
|
||||
(contentPurchaseCanAmount * CreatorRankingScoreSpec.CONTENT_PURCHASE_CAN_WEIGHT)
|
||||
fun calculateRankScore(rawValue: Long, rank: Int): Double {
|
||||
if (rawValue <= 0L) return 0.0
|
||||
return (100 - (5 * (rank - 1))).coerceAtLeast(0).toDouble()
|
||||
}
|
||||
|
||||
fun calculateEngagementScore(
|
||||
contentLikeCount: Long,
|
||||
contentCommentCount: Long
|
||||
): Double {
|
||||
return (contentLikeCount * CreatorRankingScoreSpec.CONTENT_LIKE_COUNT_WEIGHT) +
|
||||
(contentCommentCount * CreatorRankingScoreSpec.CONTENT_COMMENT_COUNT_WEIGHT)
|
||||
}
|
||||
|
||||
fun calculateSupportScore(
|
||||
channelDonationCanAmount: Long,
|
||||
channelDonationCount: Long,
|
||||
fanTalkCount: Long
|
||||
): Double {
|
||||
return (channelDonationCanAmount * CreatorRankingScoreSpec.CHANNEL_DONATION_CAN_WEIGHT) +
|
||||
(channelDonationCount * CreatorRankingScoreSpec.CHANNEL_DONATION_COUNT_WEIGHT) +
|
||||
(fanTalkCount * CreatorRankingScoreSpec.FAN_TALK_COUNT_WEIGHT)
|
||||
}
|
||||
|
||||
fun calculateFanLoyaltyScore(
|
||||
finalFollowerCount: Long,
|
||||
followIncrease: Long
|
||||
): Double {
|
||||
return (finalFollowerCount * CreatorRankingScoreSpec.FINAL_FOLLOWER_COUNT_WEIGHT) +
|
||||
(followIncrease * CreatorRankingScoreSpec.FOLLOW_INCREASE_WEIGHT)
|
||||
fun normalizeFollowIncrease(value: Long): Long {
|
||||
return value.coerceAtLeast(0L)
|
||||
}
|
||||
|
||||
fun calculateFinalScore(
|
||||
contentLiveScore: Double,
|
||||
engagementScore: Double,
|
||||
supportScore: Double,
|
||||
fanLoyaltyScore: Double
|
||||
liveRevenueRankScore: Double,
|
||||
contentRevenueRankScore: Double,
|
||||
followIncreaseRankScore: Double,
|
||||
aiChatRankScore: Double
|
||||
): Double {
|
||||
return (contentLiveScore * CreatorRankingScoreSpec.CONTENT_LIVE_SCORE_WEIGHT) +
|
||||
(engagementScore * CreatorRankingScoreSpec.ENGAGEMENT_SCORE_WEIGHT) +
|
||||
(supportScore * CreatorRankingScoreSpec.SUPPORT_SCORE_WEIGHT) +
|
||||
(fanLoyaltyScore * CreatorRankingScoreSpec.FAN_LOYALTY_SCORE_WEIGHT)
|
||||
return (liveRevenueRankScore * CreatorRankingScoreSpec.LIVE_REVENUE_WEIGHT) +
|
||||
(contentRevenueRankScore * CreatorRankingScoreSpec.CONTENT_REVENUE_WEIGHT) +
|
||||
(followIncreaseRankScore * CreatorRankingScoreSpec.FOLLOW_INCREASE_WEIGHT) +
|
||||
(aiChatRankScore * CreatorRankingScoreSpec.AI_CHAT_WEIGHT)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,12 @@
|
||||
package kr.co.vividnext.sodalive.v2.ranking.domain
|
||||
|
||||
object CreatorRankingScoreSpec {
|
||||
const val CONTENT_LIVE_CAN_WEIGHT = 0.7
|
||||
const val CONTENT_PURCHASE_CAN_WEIGHT = 0.3
|
||||
const val SCORE_POLICY_VERSION = "CREATOR_WEEKLY_POPULARITY_V2"
|
||||
const val FORMULA = "liveRevenueRankScore * 0.6 + contentRevenueRankScore * 0.2 + " +
|
||||
"followIncreaseRankScore * 0.1 + aiChatRankScore * 0.1"
|
||||
|
||||
const val CONTENT_LIKE_COUNT_WEIGHT = 0.5
|
||||
const val CONTENT_COMMENT_COUNT_WEIGHT = 0.5
|
||||
|
||||
const val CHANNEL_DONATION_CAN_WEIGHT = 0.6
|
||||
const val CHANNEL_DONATION_COUNT_WEIGHT = 0.2
|
||||
const val FAN_TALK_COUNT_WEIGHT = 0.2
|
||||
|
||||
const val FINAL_FOLLOWER_COUNT_WEIGHT = 0.7
|
||||
const val FOLLOW_INCREASE_WEIGHT = 0.3
|
||||
|
||||
const val CONTENT_LIVE_SCORE_WEIGHT = 0.35
|
||||
const val ENGAGEMENT_SCORE_WEIGHT = 0.3
|
||||
const val SUPPORT_SCORE_WEIGHT = 0.25
|
||||
const val FAN_LOYALTY_SCORE_WEIGHT = 0.1
|
||||
const val LIVE_REVENUE_WEIGHT = 0.6
|
||||
const val CONTENT_REVENUE_WEIGHT = 0.2
|
||||
const val FOLLOW_INCREASE_WEIGHT = 0.1
|
||||
const val AI_CHAT_WEIGHT = 0.1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user