2014-03-31 3 views
1

시간당 측정 값 (약 3000 점)의 데이터 세트가 있습니다. 나는 그것을 통해 곡선을 피팅하여 데이터를 부드럽게하고 싶습니다. 실험은 다단계 물리 프로세스이므로 하나의 다항식이 전체 집합에 적합하지 않을 것이라고 확신합니다.조각 별 함수로 실험 데이터 평활화

따라서 나는 조각 별 일련의 다항식을보고 있습니다. 얼마나 많은 다항식을 사용할 지 지정하고 싶습니다. 이것은 나에게 상당히 직설적 인 것으로 보이며, 나는 그것을 할 수있는 사전 구축 된 라이브러리가 있기를 희망했다. 나는 Apache Commons Math에서 org.apache.commons.math3.fitting.PolynomialFitter을 보았지만 단 한 다항식에서만 작동하는 것으로 보인다.

누구나 최선의 방법을 제안 할 수 있습니까? 자바 선호하지만 파이썬에서 일할 수 있습니다.

+0

하나의 다항식 구분 보간 만들기 --- 당신이 경계에서 차이를 지정하지 않는 한 좋은 시작이다) 1.2.12와 호환. –

+0

당신은 조금 명확히 할 수 . 내가 원하는 것은 (내가 생각하기에) 시간축을 세분화하고 각각이 연속적 이도록 낮은 차수의 다항식을 맞추는 것입니다. 내가 이해하는 바와 같이 높은 차수의 다항식은 피팅에 적합하지 않습니다. –

+0

라이브러리의 보간 지원을 각 세그먼트에 적용 할 수 있습니다. 수동으로 작업하여 파트를 서로 붙입니다. –

답변

1

finmath lib에는 몇 가지 보간 체계 (선형, 스플라인, 아키마 등)를 구현하는 curve라는 클래스가 있습니다. 이러한 곡선은 점을 매개 변수로 솔버에 제공 할 수 있으므로 Levenberg Marquardt 옵티 마이저와 같은 전역 최적화를 사용하여 데이터와 곡선의 거리를 최소화 할 수 있습니다 (일부 기본 설정 정의).

실제로 이것은 수학 금융 응용 프로그램 인 "Curve Calibration"에서 수행됩니다. 커브에 데이터만큼 많은 포인트 (매개 변수)가 있다면 완벽하게 맞을 것입니다. 데이터보다 점수가 적 으면 평상시와 가장 잘 어울립니다.

finmath lib의 Levenberg Marquardt는 멀티 스레드이며 매우 빠릅니다 (> 200 포인트가 < < 1 초에 맞음).

http://svn.finmath.net/finmath%20lib/trunk/src/main/java/net/finmath/optimizer/LevenbergMarquardt.java

면책 조항에 http://svn.finmath.net/finmath%20lib/trunk/src/main/java/net/finmath/marketdata/model/curves/Curve.java

  • 과 LM 최적화에

    • 커브 클래스를 참조하십시오 : 그 라이브러리/개발자입니다.

      참고 : 저는 또한 commons-math를 좋아하지만 커브 피팅에 대해서는 아직 사용하지 않았습니다. 응용 프로그램 (수학 금융)과 관련된 일부 맞춤 속성이 필요합니다.

      (편집) 다음

      작은 데모입니다 :(참고 :이 데모는 finmath-lib 디렉토리 1.2.13 또는 mvn.finmath.net 또는 github.com/finmath/finmath-lib에서 사용할 수있는 현재 1.2.12 - 스냅 샷 (그렇지 않은 필요

      package net.finmath.tests.marketdata.curves; 
      
      import java.text.DecimalFormat; 
      import java.text.NumberFormat; 
      
      import org.junit.Test; 
      
      import net.finmath.marketdata.model.curves.Curve; 
      import net.finmath.marketdata.model.curves.CurveInterface; 
      import net.finmath.optimizer.LevenbergMarquardt; 
      import net.finmath.optimizer.SolverException; 
      
      /** 
      * A short demo on how to use {@link net.finmath.marketdata.model.curves.Curve}. 
      * 
      * @author Christian Fries 
      */ 
      public class CurveTest { 
      
          private static NumberFormat numberFormat = new DecimalFormat("0.0000"); 
      
          /** 
          * Run a short demo on how to use {@link net.finmath.marketdata.model.curves.Curve}. 
          * 
          * @param args Not used. 
          * @throws SolverException Thrown if optimizer fails. 
          * @throws CloneNotSupportedException Thrown if curve cannot be cloned for optimization. 
          */ 
          public static void main(String[] args) throws SolverException, CloneNotSupportedException { 
           (new CurveTest()).testCurveFitting(); 
          } 
      
          /** 
          * Tests fitting of curve to given data. 
          * 
          * @throws SolverException Thrown if optimizer fails. 
          * @throws CloneNotSupportedException Thrown if curve cannot be cloned for optimization. 
          */ 
          @Test 
          public void testCurveFitting() throws SolverException, CloneNotSupportedException { 
      
           /* 
           * Build a curve (initial guess for our fitting problem, defines the times). 
           */ 
           Curve.CurveBuilder curveBuilder = new Curve.CurveBuilder(); 
      
           curveBuilder.setInterpolationMethod(Curve.InterpolationMethod.LINEAR); 
           curveBuilder.setExtrapolationMethod(Curve.ExtrapolationMethod.LINEAR); 
           curveBuilder.setInterpolationEntity(Curve.InterpolationEntity.VALUE); 
      
           // Add some points - which will not be fitted 
           curveBuilder.addPoint(-1.0 /* time */, 1.0 /* value */, false /* isParameter */); 
           curveBuilder.addPoint(0.0 /* time */, 1.0 /* value */, false /* isParameter */); 
      
           // Add some points - which will be fitted 
           curveBuilder.addPoint(0.5 /* time */, 2.0 /* value */, true /* isParameter */); 
           curveBuilder.addPoint(0.75 /* time */, 2.0 /* value */, true /* isParameter */); 
           curveBuilder.addPoint(1.0 /* time */, 2.0 /* value */, true /* isParameter */); 
           curveBuilder.addPoint(2.2 /* time */, 2.0 /* value */, true /* isParameter */); 
           curveBuilder.addPoint(3.0 /* time */, 2.0 /* value */, true /* isParameter */); 
      
           final Curve curve = curveBuilder.build(); 
      
           /* 
           * Create data to which the curve should be fitted to 
           */ 
           final double[] givenTimes = { 0.0, 0.5, 0.75, 1.0, 1.5, 1.75, 2.5 }; 
           final double[] givenValues = { 3.5, 12.3, 13.2, 7.5, 5.5, 2.9, 4.4 }; 
      
           /* 
           * Find a best fitting curve. 
           */ 
      
           // Define the objective function 
           LevenbergMarquardt optimizer = new LevenbergMarquardt(
             curve.getParameter() /* initial parameters */, 
             givenValues    /* target values */, 
             100,     /* max iterations */ 
             Runtime.getRuntime().availableProcessors() /* max number of threads */ 
             ) { 
      
            @Override 
            public void setValues(double[] parameters, double[] values) throws SolverException { 
      
             CurveInterface curveGuess = null; 
             try { 
              curveGuess = curve.getCloneForParameter(parameters); 
             } catch (CloneNotSupportedException e) { 
              throw new SolverException(e); 
             } 
      
             for(int valueIndex=0; valueIndex<values.length; valueIndex++) { 
              values[valueIndex] = curveGuess.getValue(givenTimes[valueIndex]); 
             } 
            } 
           }; 
      
           // Fit the curve (find best parameters) 
           optimizer.run(); 
      
           CurveInterface fittedCurve = curve.getCloneForParameter(optimizer.getBestFitParameters()); 
      
           // Print out fitted curve 
           for(double time = -2.0; time < 5.0; time += 0.1) { 
            System.out.println(numberFormat.format(time) + "\t" + numberFormat.format(fittedCurve.getValue(time))); 
           } 
      
           // Check fitted curve 
           double errorSum = 0.0; 
           for(int pointIndex = 0; pointIndex<givenTimes.length; pointIndex++) { 
            errorSum += fittedCurve.getValue(givenTimes[pointIndex]) - givenValues[pointIndex]; 
           } 
           System.out.println("Mean deviation: " + errorSum); 
      
           /* 
           * Test: With the given data, the fit cannot over come that at 0.0 we have an error of -2.5. 
           * Hence we test if the mean deviation is -2.5 (the optimizer reduces the variance) 
           */ 
           org.junit.Assert.assertTrue(Math.abs(errorSum - -2.5) < 1E-5); 
          } 
      } 
      
  • +0

    그것은 완벽하게 들린다. 나는 finmath를 살펴볼 것입니다 - 단지 금융 용어의 일부로 그립에 도달해야합니다! –

    +0

    관심이 있으시면 작은 데모를 게시 할 수 있습니다.이 데모는 신청서 (예 : 수학 재무)와는 별개입니다. –

    2

    local regression을 찾으려면 Commons Math는 LoessInterpolator으로 구현합니다. 최종 결과는 조각 별 입방 다항식의 부드러운 시퀀스 인 "스플라인"으로 나타납니다.

    +0

    거의 다 그렇지만 시간 순서가 몇 개의 섹션으로 나뉘어 있는지 지정하고 싶습니다. LoessInterpolator에 3000 포인트를 공급하면 2999 다항식 함수가 생성됩니다. 커브를 10으로 나누고 각 다항식에 최상의 다항식을 맞춰야한다고 말하고 싶습니다. (원래 질문에서 명확하지 않아 편집 했으므로) –

    +0

    10 개를 부드럽게 함께 넣으시겠습니까? – Joni

    +0

    나는 그것들을 함께 맞추기를 원하지만 실제로 1 차 도함수는 불연속적일 수있다. –

    관련 문제