Получена функция следующим образом. Для определения пространства поиска задается"сигнатура" - множество допустимых элементарных функций, композицией которых получается аппроксимирующая функция.
Критерий поиска - минимальная квадратичная ошибка и "простота" функции, которая определяется суть "количеством" закорючек в формуле. Алгоритм "перебирает" функции и отыскивает минимум.
Ниже приведено начало журнала работы программы:
Код:
Func: v As Float
1. x As Float
Fitness function: (DiscOf+0.06)*Exp(0.1*SizeOf)
v(0)=0
Discrepancy function: (v(x)-y)^2
Hash function: Round(v(x),3)
Signatures: { "* 2", "/ 2", "- 2", "+ 2", "- 1", "ln 1", "exp 1", "abs 1", "Float 0" }
Arg Call Count Limit=3
Const Count Limit=4
+[1]: x x
+[2]: xx0 xx0
New[1]: -0.441101758181587 x 3.21435729926719 2.84847075931396 1
* +Global Record[1]: x 3.21435729926719 2.84847075931396 1
Stats: tot=2 tree=0 fitfail=0 optcall=0 recs=1 hrej=0 hrep=0 rectrunc=0
optimize[2]: xx0 4.76337895541391 2.82913538028847 5
New[2]: 0 xx0 4.76337895541391 2.82913538028847 5
+Global Record[2]: 0 4.76337895541391 2.82913538028847 5
* Global Integer Record[2]: False 3.19298840067825 2.82913538028847 1
Stats: tot=2 tree=0 fitfail=0 optcall=1 recs=2 hrej=0 hrep=0 rectrunc=0
* Up lower bound: 0 --> 0.0663102550845389 1
--r Select[2]: xx0 4.76337895541391 2.83E+00 5
Stats: tot=2 tree=0 fitfail=0 optcall=1 recs=2 hrej=0 hrep=0 rectrunc=0
+[3]: x+xx0 xx0+x
-[3]: x-xx0 xx0+x
+[4]: xx0-x xx0+ -x
+[5]: x*xx0 xx0*x
-[5]: x/xx0 xx0*x
+[6]: xx0/x xx0*x^ -1
tol=6 added=4
optimize[3]: x+xx0 5.85694086616721 2.84847075931396 7 -[1]
optimize[4]: xx0-x 5.93714180049986 2.8882973646539 7
New[4]: 0.441101758181587 xx0-x 5.93714180049986 2.8882973646539 7
...
Критерий поиска представляет собой выражение (DiscOf+0.06)*Exp(0.1*SizeOf), где DiscOf погрешность на одно измерение, SizeOf - "размер" (простота, суть бритва Оккама) искомой функции. Т.е. для улучшение критерия поиска, линейному увеличение "количества закорючек" в аппроксимирующей функции должно соответствовать экспоненциальному уменьшение погрешности.
Но в реальности компромисс между простотой и точностью довольно трудно подобрать. Поэтому в качестве результата можно получать функции в зависимости от количества "закорючек в функции". Так, результат решения приведен ниже, где последнее число в строке - "количество закорючек", "предпоследнее" - точность, пред-предпоследнее - значение критерия поиска, выражение еще левее- сама функция.
Код:
Total Global record[1711] : 1+x+2.78228635989394*x/(0.0453510179105356+x) 2.30325445568784 0.360766640755218 17
Total Global subrecord[2]: 1 3.19298840067825 2.82913538028847 1
Total Global subrecord[14]: 1+Abs(x) 3.0375533379119 2.42693833186315 2
Total Global subrecord[29]: 1+Abs(x+x) 3.15559420616488 2.05525805354624 4
Total Global subrecord[39]: 1+Abs(x+x+x) 3.26857585045849 1.73383246018755 6
Total Global subrecord[22]: 1+5.21834833717729*Abs(x) 3.20427367258679 1.37977297005151 8
Total Global subrecord[55]: 1+(x+5.21834833717729)*Abs(x) 3.87315845973987 1.36485536973755 10
Total Global subrecord[1697]: 1+(x+x)/(0.0610372111860029+x) 2.84728582451262 0.887779118003694 11
Total Global subrecord[9973]: 1+Ln(Exp(x)+Abs((-41.074875125693)*x)) 3.01663778463529 0.848593840167798 12
Total Global subrecord[2891]: 1+Abs((x+x)/((-0.0544893976514991)+Abs(x))) 2.91797574682508 0.735241162312001 13
Total Global subrecord[1701]: 1+2.83071098771745*x/(0.0294951297261624+x) 2.3954389719412 0.474494681435031 15
Total Global subrecord[24211]: 1+x+2.65694038556965*x/Ln(0.0439244877623086+Exp(x)) 2.76974072822774 0.354266296325719 19
Total Global subrecord[23112]: 1+((-2.96712174678618)-x)*x/Ln((-0.0449906928246921)+Exp(-x)) 3.03053979970898 0.350138962153442 20
Total Global subrecord[23043]: 1+(-1.25041321126017)*x/Ln(0.544461484366544+Exp((-0.829739359006278)-x)) 4.07164918255577 0.34821883908794 23
Total Global subrecord[24641]: 1+(3.59423091421308-Exp((-0.384745387131403)-x))*x/(0.0397417309162283+x) 4.4407184355607 0.342852887608628 24
Total Global subrecord[28071]: 1+(4.43888006611709-Exp(0.401787083760687*Exp(-x)))*x/(0.0384088844892154+x) 5.3998904927908 0.341069188865136 26
Total Global subrecord[3422]: 1+Abs(2.92426973874349*x/(x*0.182078589529588+Abs((-1.02000310355838)+Exp(-x)))) 5.67593934334244 0.321454413849047 27
Total Global subrecord[4181]: 1+Abs(4.06094771991911*x/(Exp(x)*(-0.45605361473599)+Abs((-0.602199881519801)+Exp((-0.976659674898583)*x)))) 9.7027723813358 0.297868977996936 33
Total Global subrecord[8520]: 1+Exp(Exp(1.23098953416086-Abs((-2.29789963761277)*((-0.937858579415315)+Exp(x)))))*Abs(Exp(0.557330786939697+x)*x) 11.841348122993 0.29757772950717 35
Total Global subrecord[8586]: 1+Exp(Exp(1.37363922312694-Abs(2.05655507143861*((-0.946808074726886)+Exp(x)))))*Abs(Exp((-0.901804828587998)+Exp(x))*x) 11.9487445258995 0.266484179019285 36
В принципе, можно посмотреть на мелкой сетке все функции, имеющие погрешность не более 0.4, и выбрать подходящую. Самая точная и самая "сложная" функция - последняя; она дает погрешность 0.266484179019285 на одно измерение.
В домашних условиях вряд ли получится организовать такой поиск аппроксимирующей функции, т.к. для этого нужен специальный софт.
Всегда существует вопрос, можно ли пользоваться полученной аппроксимацией. Один из методов проверки называется "перекрестная проверка" (cross-checking). Суть его заключается в том, что множество исходных данных делят на обучающее и проверочное множество. На обучающем производят аппроксимацию, а на тестовом проверяют точность. При использовании деления данных на обучающее и проверочное есть нюансы, касательные оценки простоты функции (подбираемые при обучении константы учитываются особым образом).
Более подробно, как производить проверку и какие подводные камни встречаются, рассматривается в DataMining.
UPD. Дополнительные требования при подборе функции встречались следующие:
1. Должна проходить через некоторые заданные точки
2. Диапазон допустимых значений функции
3. Особые точки
4. Значения функции при предельных значениях аргументов
5. Степень гладкости функции
6. Монотонность функции (неубывание)
7. Аналитичность (что не всегда обязательно); также рассматриваются разные варианты с разрешением задания функции дифференциальным / функциональным уравнением
....