在数学建模时,我们往往一般都习惯性用方差来判断模型的拟合效果,可是并不是每个模型都是有方差或方差计算量较大,如果数据不是连续变量的话,通过误差的平方和来判断容易做出偏大或偏小的结果。
而Log-likelihood则是用对数似然的方式,本质是通过计算概率相乘的概率来计算数据都在拟合的函数周围的概率,而对数则是为了令概率相乘变为相加的形式,能够更好地优化。
以下是一个例子:
# 生成模拟数据集
set.seed(123)
n <- 100 # 样本量
x <- rnorm(n) # 自变量
true_beta <- c(1, 2) # 真实参数(截距和斜率)
y <- true_beta[1] + true_beta[2] * x + rnorm(n, sd = 0.5) # 因变量(加噪声)
# 可视化数据
plot(x, y, main = "模拟数据集")
abline(a = true_beta[1], b = true_beta[2], col = "red")
# 用lm函数拟合模型
fit <- lm(y ~ x)
summary(fit)
# 手动计算log-likelihood的函数
log_likelihood <- function(y, x, beta, sigma) {
y_pred <- beta[1] + beta[2] * x # 预测值
residuals <- y - y_pred # 残差
# 计算每个数据点的对数似然(正态分布假设)
ll <- sum(dnorm(residuals, mean = 0, sd = sigma, log = TRUE))
return(ll)
}
# 使用拟合模型的参数计算log-likelihood
beta_hat <- coef(fit) # 估计的系数
sigma_hat <- summary(fit)$sigma # 估计的残差标准差
# 计算log-likelihood
ll_value <- log_likelihood(y, x, beta_hat, sigma_hat)
cat("计算得到的log-likelihood:", ll_value, "\n")
# 与R内置函数比较(应该相同)
cat("R内置logLik函数结果:", logLik(fit), "\n")
# 尝试不同的参数值看看log-likelihood如何变化
beta_test <- c(0.5, 1.5) # 不太好的参数
ll_test <- log_likelihood(y, x, beta_test, sigma_hat)
cat("测试参数的log-likelihood:", ll_test, "\n") # 应该比拟合参数的小
输出:
Call:
lm(formula = y ~ x)
Residuals:
Min 1Q Median 3Q Max
-0.95367 -0.34175 -0.04375 0.29032 1.64520
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.94860 0.04878 19.45 <2e-16 ***
x 1.97376 0.05344 36.94 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.4854 on 98 degrees of freedom
Multiple R-squared: 0.933, Adjusted R-squared: 0.9323
F-statistic: 1364 on 1 and 98 DF, p-value: < 2.2e-16
计算得到的log-likelihood: -68.60687
R内置logLik函数结果: -68.59673
测试参数的log-likelihood: -159.164
可以看到,改变参数后,Log-likelihood的变化很明显,这能帮助我们定位参数,选择更好的参数。