mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IJPL-235909 ML in SE: Convert feature names on prediction / Fix regression
Following the renaming of features to follow FUS recommendations, the feature mapper used by our ML models no longer worked as intended, given that most feature names have changed. This commit introduces a temporary conversion layer that, until new models are trained, converts the feature names back to the old names. (cherry picked from commit 1bf999feb62e1bbb90ca567b5fe60f672fc335e4) IJ-CR-192893 GitOrigin-RevId: 188f66fb074f262a999d8f12fde9fd3c09a6cbd3
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c49593a948
commit
a963b2cab7
+41
@@ -0,0 +1,41 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.searchEverywhereMl.ranking.core.model
|
||||
|
||||
// This conversion is required while bundled models still expect legacy camelCase names.
|
||||
// It can be removed after models are re-trained with snake_case feature names.
|
||||
private val LEGACY_FEATURE_NAME_ALIASES = mapOf(
|
||||
"action_plugin_type" to "pluginType",
|
||||
"is_in_library" to "isFromLibrary",
|
||||
"max_usage_se" to "maxUsageSE",
|
||||
"min_usage_se" to "minUsageSE",
|
||||
)
|
||||
|
||||
internal fun withLegacyFeatureNameAliases(features: Map<String, Any?>): Map<String, Any?> {
|
||||
val featuresWithLegacyAliases = HashMap<String, Any?>(features.size * 2)
|
||||
for ((featureName, value) in features) {
|
||||
featuresWithLegacyAliases[featureName] = value
|
||||
featuresWithLegacyAliases.putIfAbsent(toLegacyFeatureName(featureName), value)
|
||||
}
|
||||
return featuresWithLegacyAliases
|
||||
}
|
||||
|
||||
internal fun toLegacyFeatureName(featureName: String): String {
|
||||
return LEGACY_FEATURE_NAME_ALIASES[featureName] ?: featureName.snakeCaseToCamelCase()
|
||||
}
|
||||
|
||||
private fun String.snakeCaseToCamelCase(): String {
|
||||
if (indexOf('_') < 0) return this
|
||||
|
||||
val result = StringBuilder(length)
|
||||
var uppercaseNext = false
|
||||
for (char in this) {
|
||||
if (char == '_') {
|
||||
uppercaseNext = true
|
||||
continue
|
||||
}
|
||||
|
||||
result.append(if (uppercaseNext) char.uppercaseChar() else char)
|
||||
uppercaseNext = false
|
||||
}
|
||||
return result.toString()
|
||||
}
|
||||
+1
-1
@@ -12,7 +12,7 @@ import com.intellij.searchEverywhereMl.ranking.core.features.SearchEverywhereFil
|
||||
internal abstract class SearchEverywhereRankingModel(protected val model: DecisionFunction) {
|
||||
abstract fun predict(features: Map<String, Any?>): Double
|
||||
protected fun rawModelPredict(features: Map<String, Any?>): Double {
|
||||
return model.predict(buildArray(model.featuresOrder, features))
|
||||
return model.predict(buildArray(model.featuresOrder, withLegacyFeatureNameAliases(features)))
|
||||
}
|
||||
|
||||
private fun buildArray(featuresOrder: Array<FeatureMapper>, features: Map<String, Any?>): DoubleArray {
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.intellij.searchEverywhereMl.ranking.core.model
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
|
||||
@RunWith(JUnit4::class)
|
||||
internal class SearchEverywhereFeatureNameConverterTest {
|
||||
@Test
|
||||
fun `snake case name is converted to camelCase`() {
|
||||
assertEquals("queryLength", toLegacyFeatureName("query_length"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `non trivial legacy names are taken from lookup table`() {
|
||||
assertEquals("pluginType", toLegacyFeatureName("action_plugin_type"))
|
||||
assertEquals("isFromLibrary", toLegacyFeatureName("is_in_library"))
|
||||
assertEquals("maxUsageSE", toLegacyFeatureName("max_usage_se"))
|
||||
assertEquals("minUsageSE", toLegacyFeatureName("min_usage_se"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `aliases are added and existing keys are preserved`() {
|
||||
val features = mapOf(
|
||||
"query_length" to 7,
|
||||
"queryLength" to 3,
|
||||
"is_in_library" to true,
|
||||
)
|
||||
|
||||
val featuresWithAliases = withLegacyFeatureNameAliases(features)
|
||||
|
||||
assertEquals(7, featuresWithAliases["query_length"])
|
||||
assertEquals(3, featuresWithAliases["queryLength"])
|
||||
assertEquals(true, featuresWithAliases["is_in_library"])
|
||||
assertEquals(true, featuresWithAliases["isFromLibrary"])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user