AIC слишком низок для плохо подогнанного полинома - PullRequest
0 голосов
/ 14 июня 2019

Я пытаюсь найти наилучший полином, подходящий для набора данных. Он рассчитывает AIC для каждого полиномиального соответствия определенной степени, а затем выбирает тот, который имеет наименьший AIC. Насколько мне известно (в чем я могу ошибаться) самое низкое значение AIC, которое я считаю, является наилучшим.

Здесь я определяю свои полиномы:

def p2(xData,a0,a1,a2):
    return a0 + a1 * xData + a2 * xData**2
def p3(xData,a0,a1,a2,a3):
    return a0 + a1 * xData + a2 * xData**2 + a3 * xData**3
def p4(xData,a0,a1,a2,a3,a4):
    return a0 + a1 * xData + a2 * xData**2 + a3 * xData**3 + a4 * xData**4

Моя функция для вычисления AIC:

def compute_AIC(yData,model,variables):
    residual=yData-model
    SSE=np.sum(residual**2)
    return 2*variables-2*np.log(SSE)

А мой код для подбора полинома подходит для моих данных и выбора лучшего:

def polynom_best_fit(xData,yData):
        print('Assessing if the best fit is higher order..')
        AICS=[]
        for i in [2,3,4]:
            params=[]
            params=poly.polyfit(xData,yData,i)
            print(params)
            if len(params) == 3:
                model_p2=p2(xData,*params)
                AICS.append(compute_AIC(yData,model_p2,3))
            if len(params) == 4:
                model_p3=p3(xData,*params)
                AICS.append(compute_AIC(yData,model_p3,4))
            if len(params) == 5:
                model_p4=p4(xData,*params)
                AICS.append(compute_AIC(yData,model_p4,5))
            else:
                continue
            print(AICS)
            best=np.where(AICS==min(AICS))
            best_model=[]
        for i in best:
            if np.where(AICS==min(AICS))[0][0] == 0:
                print('Second degree best fit')
                print('with AIC =', min(AICS))
                plt.plot(xData,model_p2,color='red')
                plt.scatter(xData,yData)
                plt.show()
                return min(AICS)
            if np.where(AICS==min(AICS))[0][0] == 1:
                print('Third degree best fit')
                print('with AIC =', min(AICS))
                return min(AICS)
            if np.where(AICS==min(AICS))[0][0] == 2:
                print('Fourth degree best fit')
                print('with AIC =', min(AICS))
                return min(AICS)
            else:
                print('Error')

Однако, когда я выполняю это с моим кодом, который требует подгонки, я получаю:

enter image description here

Который имеет обезоруживающе низкое значение AIC.

Для набора данных, для которого кусочно-линейная регрессия явно выглядела наилучшим образом, функция создала полином, который имел более низкое значение AIC, чем моя кусочно-линейная регрессия, с R-квадратом более 0,99, но AIC около 12.

enter image description here

Это не проходит проверку работоспособности, поэтому я, должно быть, здесь что-то не так сделал. Возможно, мое определение моих полиномов или то, как я определил свою функцию, которая вычисляет AIC, неверно, или просто то, что мое понимание того, что AIC говорит мне о наилучшем соответствии, неверно.

Может также случиться так, что, хотя мои кусочные регрессии имели очень хорошие значения Rsquared, они имели огромное количество параметров (точка останова 1, точка останова 2, slope1, slope2, slope3, offset1, offset2, offset3 - создание 8 параметров или переменных), что могло привести к победе полиномов, но я все еще скептически отношусь к тому, что мой код говорит правду.

...