Используйте groupby для статистически обработанных значений R2 - python - PullRequest
0 голосов
/ 23 сентября 2018

Для моего исследования у меня есть конкретный расчет для значений R2.Это не значение R2, напрямую рассчитанное с использованием функции Линрегресса.

Код, который я использую, предназначен для статистически обработанного значения R2 (помечено как «лучший R2).Я получаю значение R2 для всей оси X и Y.Однако в данных есть несколько «тестовых событий».Это означает, что мне нужно значение R2 для отдельного «тестового события»

Код, который я использую до сих пор для вычисления значений R2 (и какой мне нужен вывод), выглядит следующим образом:


import numpy, scipy,pandas as pd, matplotlib
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import scipy.stats
import copy
df=pd.read_excel("I:/Python/Excel.xlsx")
df.head()

xyDataPairs = df[['x', 'y']].values.tolist()

minDataPoints = len(xyDataPairs) - 1
# utility function
def UniqueCombinations(items, n):
    if n==0:
        yield []
    else:
        for i in range(len(items)):
            for cc in UniqueCombinations(items[i+1:],n-1):
                yield [items[i]]+cc

bestR2 = 0.0
bestDataPairCombination = []
bestParameters = []

for pairs in UniqueCombinations(xyDataPairs, minDataPoints):
    x = []
    y = []
    for pair in pairs:
        x.append(pair[0])
        y.append(pair[1])
    fittedParameters = numpy.polyfit(x, y, 1) # straight line
    modelPredictions = numpy.polyval(fittedParameters, x)
    absError = modelPredictions - y
    Rsquared = 1.0 - (numpy.var(absError) / numpy.var(y))
    if Rsquared > bestR2:
        bestR2 = Rsquared
        bestDataPairCombination = copy.deepcopy(pairs)
        bestParameters = copy.deepcopy(fittedParameters)
    print('best R2', bestR2)

Вышеупомянутое лучшее значение R2 для целых столбцов x и y.Однако, скажем, мне нужно разделить весь набор данных на четыре события, каждое событие имеет свое собственное значение R2.Тогда как мне это получить?Мне нужно, чтобы вышеприведенный код дал мне значения 'bestR2' с 'groupby' относительно 'Test Event.Это значение R2, которое тщательно обрабатывается, чтобы соответствовать результатам, необходимым для моего исследовательского проекта.Таким образом, прямое использование Linregress не поможет, и по этой причине я рассчитал bestR2 по-другому.Короче говоря: мне нужно лучшее значение R2 для нескольких тестовых событий, рассчитанное по вышеуказанному методу.


Результат должен быть следующим:

Test_Event  best R2
1           0.999
2           0.547
3           0.845
4           0.784

Спасибо за чтение !!

1 Ответ

0 голосов
/ 28 сентября 2018

Вы можете группировать по столбцу test_event и применять пользовательскую функцию для вычисления значения best_r2 для каждой группы.Пользовательская функция - это просто оболочка над желаемой логикой (здесь она называется compute_best_r2).

Ниже приведено рабочее решение:

import numpy, pandas as pd
import copy

df=pd.read_excel("...")

def UniqueCombinations(items, n):
    if n==0:
        yield []
    else:
        for i in range(len(items)):
            for cc in UniqueCombinations(items[i+1:],n-1):
                yield [items[i]]+cc


def compute_best_r2(data):
    xyDataPairs = data[['x', 'y']].values.tolist()
    minDataPoints = len(xyDataPairs)
    bestR2 = 0.0
    bestDataPairCombination = []
    bestParameters = []

    for pairs in UniqueCombinations(xyDataPairs, minDataPoints):
        x = []
        y = []
        for pair in pairs:
            x.append(pair[0])
            y.append(pair[1])
        fittedParameters = numpy.polyfit(x, y, 1) # straight line
        modelPredictions = numpy.polyval(fittedParameters, x)
        absError = modelPredictions - y
        Rsquared = 1.0 - (numpy.var(absError) / numpy.var(y))
        if Rsquared > bestR2:
            bestR2 = Rsquared
            bestDataPairCombination = copy.deepcopy(pairs)
            bestParameters = copy.deepcopy(fittedParameters)
    data['best_r2'] = bestR2
    return data

df_with_best_r2 = df.groupby(['test_event']).apply(compute_best_r2)
result = df_with_best_r2[['test_event', 'best_r2']].groupby(['test_event']).agg(['first']).reset_index()[['test_event', 'best_r2']]
result.columns = result.columns.droplevel(-1)

Обратите внимание, что я изменил minDataPoints на len(xyDataPairs) вместо len(xyDataPairs) - 1, поскольку это выглядело как ошибка, пожалуйста, убедитесь, что это именно то, что вы и хотели.

Я проверил это на примере данных:

test_event  x   y
1          1.5  2
1          1    1.8
1          2    4
1          2    6
2          1    1
2          2    2

Результат с:

   test_event   best_r2
0           1  0.705464
1           2  1.000000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...