1
- namespace AiDotNet . Helpers ;
1
+ using System . Linq ;
2
+
3
+ namespace AiDotNet . Helpers ;
2
4
3
5
public static class StatisticsHelper < T >
4
6
{
@@ -903,21 +905,21 @@ public static T CalculateTValue(int degreesOfFreedom, T confidenceLevel)
903
905
return CalculateInverseStudentTCDF ( degreesOfFreedom , NumOps . Subtract ( NumOps . One , alpha ) ) ;
904
906
}
905
907
906
- public static ( T FirstQuartile , T ThirdQuartile ) CalculateQuartiles ( Vector < T > data )
908
+ public static ( T FirstQuantile , T ThirdQuantile ) CalculateQuantiles ( Vector < T > data )
907
909
{
908
910
var sortedData = data . OrderBy ( x => x ) . ToArray ( ) ;
909
911
int n = sortedData . Length ;
910
912
911
- T Q1 = CalculateQuartile ( sortedData , NumOps . FromDouble ( 0.25 ) ) ;
912
- T Q3 = CalculateQuartile ( sortedData , NumOps . FromDouble ( 0.75 ) ) ;
913
+ T Q1 = CalculateQuantile ( sortedData , NumOps . FromDouble ( 0.25 ) ) ;
914
+ T Q3 = CalculateQuantile ( sortedData , NumOps . FromDouble ( 0.75 ) ) ;
913
915
914
916
return ( Q1 , Q3 ) ;
915
917
}
916
918
917
- public static T CalculateQuartile ( T [ ] sortedData , T quartile )
919
+ public static T CalculateQuantile ( T [ ] sortedData , T quantile )
918
920
{
919
921
int n = sortedData . Length ;
920
- T position = NumOps . Multiply ( NumOps . FromDouble ( n - 1 ) , quartile ) ;
922
+ T position = NumOps . Multiply ( NumOps . FromDouble ( n - 1 ) , quantile ) ;
921
923
int index = NumOps . ToInt32 ( NumOps . Round ( position ) ) ;
922
924
T fraction = NumOps . Subtract ( position , NumOps . FromDouble ( index ) ) ;
923
925
@@ -956,4 +958,117 @@ public static (T skewness, T kurtosis) CalculateSkewnessAndKurtosis(Vector<T> sa
956
958
957
959
return ( skewness , kurtosis ) ;
958
960
}
961
+
962
+ public static ( T Lower , T Upper ) CalculateToleranceInterval ( Vector < T > actual , Vector < T > predicted , T confidenceLevel )
963
+ {
964
+ int n = actual . Length ;
965
+ T mean = predicted . Average ( ) ;
966
+ T stdDev = CalculateStandardDeviation ( predicted ) ;
967
+ T factor = NumOps . FromDouble ( Math . Sqrt ( 1 + ( 1.0 / n ) ) ) ;
968
+ T tValue = CalculateTValue ( n - 1 , confidenceLevel ) ;
969
+ T margin = NumOps . Multiply ( tValue , NumOps . Multiply ( stdDev , factor ) ) ;
970
+
971
+ return ( NumOps . Subtract ( mean , margin ) , NumOps . Add ( mean , margin ) ) ;
972
+ }
973
+
974
+ public static ( T Lower , T Upper ) CalculateForecastInterval ( Vector < T > actual , Vector < T > predicted , T confidenceLevel )
975
+ {
976
+ int n = actual . Length ;
977
+ T mean = predicted . Average ( ) ;
978
+ T mse = CalculateMeanSquaredError ( actual , predicted ) ;
979
+ T factor = NumOps . FromDouble ( Math . Sqrt ( 1 + ( 1.0 / n ) ) ) ;
980
+ T tValue = CalculateTValue ( n - 1 , confidenceLevel ) ;
981
+ T margin = NumOps . Multiply ( tValue , NumOps . Multiply ( NumOps . Sqrt ( mse ) , factor ) ) ;
982
+
983
+ return ( NumOps . Subtract ( mean , margin ) , NumOps . Add ( mean , margin ) ) ;
984
+ }
985
+
986
+ public static List < ( T Quantile , T Lower , T Upper ) > CalculateQuantileIntervals ( Vector < T > actual , Vector < T > predicted , T [ ] quantiles )
987
+ {
988
+ var result = new List < ( T Quantile , T Lower , T Upper ) > ( ) ;
989
+ var sortedPredictions = new Vector < T > ( [ .. predicted . OrderBy ( x => x ) ] ) ;
990
+
991
+ foreach ( var q in quantiles )
992
+ {
993
+ T lowerQuantile = CalculateQuantile ( sortedPredictions , NumOps . Subtract ( q , NumOps . FromDouble ( 0.025 ) ) ) ;
994
+ T upperQuantile = CalculateQuantile ( sortedPredictions , NumOps . Add ( q , NumOps . FromDouble ( 0.025 ) ) ) ;
995
+ result . Add ( ( q , lowerQuantile , upperQuantile ) ) ;
996
+ }
997
+
998
+ return result ;
999
+ }
1000
+
1001
+ public static ( T Lower , T Upper ) CalculateBootstrapInterval ( Vector < T > actual , Vector < T > predicted , T confidenceLevel )
1002
+ {
1003
+ int n = actual . Length ;
1004
+ int bootstrapSamples = 1000 ;
1005
+ var bootstrapMeans = new List < T > ( ) ;
1006
+
1007
+ Random random = new ( ) ;
1008
+ for ( int i = 0 ; i < bootstrapSamples ; i ++ )
1009
+ {
1010
+ var sample = new Vector < T > ( n ) ;
1011
+ for ( int j = 0 ; j < n ; j ++ )
1012
+ {
1013
+ int index = random . Next ( n ) ;
1014
+ sample [ j ] = predicted [ index ] ;
1015
+ }
1016
+ bootstrapMeans . Add ( sample . Average ( ) ) ;
1017
+ }
1018
+
1019
+ bootstrapMeans . Sort ( ) ;
1020
+ int lowerIndex = NumOps . ToInt32 ( NumOps . Divide ( NumOps . Multiply ( confidenceLevel , NumOps . FromDouble ( bootstrapSamples ) ) , NumOps . FromDouble ( 2 ) ) ) ;
1021
+ int upperIndex = bootstrapSamples - lowerIndex - 1 ;
1022
+
1023
+ return ( bootstrapMeans [ lowerIndex ] , bootstrapMeans [ upperIndex ] ) ;
1024
+ }
1025
+
1026
+ public static ( T Lower , T Upper ) CalculateSimultaneousPredictionInterval ( Vector < T > actual , Vector < T > predicted , T confidenceLevel )
1027
+ {
1028
+ int n = actual . Length ;
1029
+ T mean = predicted . Average ( ) ;
1030
+ T mse = CalculateMeanSquaredError ( actual , predicted ) ;
1031
+ T factor = NumOps . Sqrt ( NumOps . Multiply ( NumOps . FromDouble ( 2 ) , confidenceLevel ) ) ;
1032
+ T margin = NumOps . Multiply ( factor , NumOps . Sqrt ( mse ) ) ;
1033
+
1034
+ return ( NumOps . Subtract ( mean , margin ) , NumOps . Add ( mean , margin ) ) ;
1035
+ }
1036
+
1037
+ public static ( T Lower , T Upper ) CalculateJackknifeInterval ( Vector < T > actual , Vector < T > predicted )
1038
+ {
1039
+ int n = actual . Length ;
1040
+ var jackknifeSamples = new List < T > ( ) ;
1041
+
1042
+ for ( int i = 0 ; i < n ; i ++ )
1043
+ {
1044
+ var sample = new Vector < T > ( n - 1 ) ;
1045
+ int index = 0 ;
1046
+ for ( int j = 0 ; j < n ; j ++ )
1047
+ {
1048
+ if ( j != i )
1049
+ {
1050
+ sample [ index ++ ] = predicted [ j ] ;
1051
+ }
1052
+ }
1053
+ jackknifeSamples . Add ( sample . Average ( ) ) ;
1054
+ }
1055
+
1056
+ T jackknifeEstimate = new Vector < T > ( [ .. jackknifeSamples ] ) . Average ( ) ;
1057
+ T jackknifeStdError = CalculateStandardDeviation ( new Vector < T > ( [ .. jackknifeSamples ] ) ) ;
1058
+ T tValue = CalculateTValue ( n - 1 , NumOps . FromDouble ( 0.95 ) ) ;
1059
+ T margin = NumOps . Multiply ( tValue , jackknifeStdError ) ;
1060
+
1061
+ return ( NumOps . Subtract ( jackknifeEstimate , margin ) , NumOps . Add ( jackknifeEstimate , margin ) ) ;
1062
+ }
1063
+
1064
+ public static ( T Lower , T Upper ) CalculatePercentileInterval ( Vector < T > predicted , T confidenceLevel )
1065
+ {
1066
+ var sortedPredictions = new Vector < T > ( [ .. predicted . OrderBy ( x => x ) ] ) ;
1067
+ int n = sortedPredictions . Length ;
1068
+ T alpha = NumOps . Subtract ( NumOps . One , confidenceLevel ) ;
1069
+ int lowerIndex = NumOps . ToInt32 ( NumOps . Divide ( NumOps . Multiply ( alpha , NumOps . FromDouble ( n ) ) , NumOps . FromDouble ( 2.0 ) ) ) ;
1070
+ int upperIndex = n - lowerIndex - 1 ;
1071
+
1072
+ return ( sortedPredictions [ lowerIndex ] , sortedPredictions [ upperIndex ] ) ;
1073
+ }
959
1074
}
0 commit comments