import { useState , useEffect } from 'react' ; import { isClassificationEvaluateResponse , ClassificationEvaluateResponse , ConfusionMatrix , ResultsSearchQuery , ANALYSIS_CONFIG_TYPE , ClassificationMetricItem , } from '../../../../common/analytics' ; import { isKeywordAndTextType } from '../../../../common/fields' ; import { getDependentVar , getPredictionFieldName , loadEvalData , loadDocsCount , DataFrameAnalyticsConfig , } from '../../../../common' ; import { isTrainingFilter } from './is_training_filter' ; function getEvalutionMetricsItems ( evalMetrics ? ) { if ( evalMetrics === undefined ) return [ ] ; const accuracyMetrics = evalMetrics . accuracy ?. classes || [ ] ; const recallMetrics = evalMetrics . recall ?. classes || [ ] ; const metricsMap = accuracyMetrics . reduce ( ( acc , accuracyMetric ) => { acc [ accuracyMetric . class_name ] = { className : accuracyMetric . class_name , accuracy : accuracyMetric . value , } ; return acc ; } , { } as Record < string , ClassificationMetricItem > ) ; recallMetrics . forEach ( ( recallMetric ) => { if ( metricsMap [ recallMetric . class_name ] !== undefined ) { metricsMap [ recallMetric . class_name ] = { recall : recallMetric . value , ... metricsMap [ recallMetric . class_name ] , } ; } else { metricsMap [ recallMetric . class_name ] = { className : recallMetric . class_name , recall : recallMetric . value , } ; } } ) ; return Object . values ( metricsMap ) ; } export const useConfusionMatrix = ( jobConfig , searchQuery ) => { const [ confusionMatrixData , setConfusionMatrixData ] = useState < ConfusionMatrix [ ] > ( [ ] ) ; const [ overallAccuracy , setOverallAccuracy ] = useState < null | number > ( null ) ; const [ avgRecall , setAvgRecall ] = useState < null | number > ( null ) ; const [ evaluationMetricsItems , setEvaluationMetricsItems ] = useState < ClassificationMetricItem [ ] > ( [ ] ) ; const [ isLoading , setIsLoading ] = useState < boolean > ( false ) ; const [ docsCount , setDocsCount ] = useState < null | number > ( null ) ; const [ error , setError ] = useState < null | string > ( null ) ; useEffect ( ( ) => { async function loadConfusionMatrixData ( ) { setIsLoading ( true ) ; let requiresKeyword = false ; const dependentVariable = getDependentVar ( jobConfig . analysis ) ; const resultsField = jobConfig . dest . results_field ; const isTraining = isTrainingFilter ( searchQuery , resultsField ) ; try { requiresKeyword = isKeywordAndTextType ( dependentVariable ) ; } catch ( e ) { console . error ( 'Unable to load new field types' , e ) ; } const evalData = await loadEvalData ( { isTraining , index : jobConfig . dest . index , dependentVariable , resultsField , predictionFieldName : getPredictionFieldName ( jobConfig . analysis ) , searchQuery , jobType : ANALYSIS_CONFIG_TYPE . CLASSIFICATION , requiresKeyword , } ) ; const docsCountResp = await loadDocsCount ( { isTraining , searchQuery , resultsField , destIndex : jobConfig . dest . index , } ) ; if ( evalData . success === true && evalData . eval && isClassificationEvaluateResponse ( evalData . eval ) ) { const confusionMatrix = evalData . eval ?. classification ?. multiclass_confusion_matrix ?. confusion_matrix ; setError ( null ) ; setConfusionMatrixData ( confusionMatrix || [ ] ) ; setAvgRecall ( evalData . eval ?. classification ?. recall ?. avg_recall || null ) ; setOverallAccuracy ( evalData . eval ?. classification ?. accuracy ?. overall_accuracy || null ) ; setEvaluationMetricsItems ( getEvalutionMetricsItems ( evalData . eval ?. classification ) ) ; setIsLoading ( false ) ; } else { setIsLoading ( false ) ; setConfusionMatrixData ( [ ] ) ; setError ( evalData . error ) ; } if ( docsCountResp . success === true ) { setDocsCount ( docsCountResp . docsCount ) ; } else { setDocsCount ( null ) ; } } loadConfusionMatrixData ( ) ; } , [ JSON . stringify ( [ jobConfig , searchQuery ] ) ] ) ; return { avgRecall , confusionMatrixData , docsCount , error , isLoading , overallAccuracy , evaluationMetricsItems , } ; } ;