Среднеквадратичное отклонение по результатам GAM с использованием R
Фон
База данных PostgreSQL использует PL/R для вызова функций R. Вызов R для вычисления корреляции Спирмена выглядит следующим образом:
cor( rank(x), rank(y) )
Также в R наивный расчет подобранной обобщенной аддитивной модели (GAM):
data.frame( x, fitted( gam( y ~ s(x) ) ) )
Вот x
представляет годы с 1900 по 2009 год и y
это среднее измерение (например, минимальная температура) за этот год.
проблема
Подходящая линия тренда (с использованием GAM) достаточно точна, как вы можете видеть на следующем рисунке:
Проблема состоит в том, что корреляции (показанные в левом нижнем углу) не точно отражают, насколько точно модель соответствует данным.
Возможное решение
Одним из способов повышения точности корреляции является использование вычисления среднеквадратичной ошибки (RMSE) для данных в двоичном виде.
Вопросы
В.1. Как бы вы реализовали расчет среднеквадратичного отклонения для связанных данных, чтобы получить корреляцию (между 0 и 1) соответствия GAM измерениям на языке R?
В.2. Есть ли лучший способ найти точность подгонки GAM к данным, и если да, то что это такое (например, среднеквадратичное отклонение)?
Попытка решения 1
- Вызовите функцию PL/R, используя наблюдаемые суммы и модельные (GAM) суммы:
correlation_rmse := climate.plr_corr_rmse( v_amount, v_model );
- определять
plr_corr_rmse
следующим образом (гдеo
а такжеm
представляют наблюдаемые и смоделированные данные):CREATE OR REPLACE FUNCTION climate.plr_corr_rmse( o double precision[], m double precision[]) RETURNS double precision AS $BODY$ sqrt( mean( o - m ) ^ 2 ) $BODY$ LANGUAGE 'plr' VOLATILE STRICT COST 100;
o - m
неправильно. Я хотел бы объединить оба набора данных путем расчета mean
из каждых 5 точек данных (будет не более 110 точек данных). Например:
omean <- c( mean(o[1:5]), mean(o[6:10]), ... )
mmean <- c( mean(m[1:5]), mean(m[6:10]), ... )
Затем исправьте расчет RMSE следующим образом:
sqrt( mean( omean - mmean ) ^ 2 )
Как вы рассчитываете c( mean(o[1:5]), mean(o[6:10]), ... )
для вектора произвольной длины в соответствующем количестве бинов (например, 5, может быть не идеальным только для 67 измерений)?
Я не думаю hist
подходит здесь, не так ли?
Попытка решения 2
Следующий код решит проблему, однако отбрасывает точки данных из конца списка (чтобы список делился на 5). Решение не идеальное, так как число "5" довольно волшебно.
while( length(o) %% 5 != 0 ) {
o <- o[-length(o)]
}
omean <- apply( matrix(o, 5), 2, mean )
Какие еще варианты доступны?
Заранее спасибо.
1 ответ
Вы говорите, что:
Проблема состоит в том, что корреляции (показанные в левом нижнем углу) не точно отражают, насколько точно модель соответствует данным.
Вы можете рассчитать соотношение между подобранными значениями и измеренными значениями:
cor(y,fitted(gam(y ~ s(x))))
Я не понимаю, почему вы хотите скопировать ваши данные, но вы можете сделать это следующим образом:
mean.binned <- function(y,n = 5){
apply(matrix(c(y,rep(NA,(n - (length(y) %% n)) %% n)),n),
2,
function(x)mean(x,na.rm = TRUE))
}
Это выглядит немного некрасиво, но должно обрабатывать векторы, длина которых не кратна длине биннинга (т.е. 5 в вашем примере).
Вы также говорите, что:
Одним из способов повышения точности корреляции является использование вычисления среднеквадратичной ошибки (RMSE) для данных в двоичном виде.
Я не понимаю, что вы имеете в виду под этим. Корреляция является фактором, определяющим среднеквадратичную ошибку - например, см. Уравнение 10 Мерфи (1988, Monthly Weather Review, v. 116, pp. 2417-2424). Но, пожалуйста, объясните, что вы имеете в виду.