# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.pyplot import MultipleLocator
"""
输出观测值和模型预测值之间的拟合曲线,即拟合模型
决定系数R2,有拟合曲线公式,有1:1线
注意:R2、RMSE是预测和实测计算的,即原来的反演或预测模型的值。拟合曲线模型是预测和实测重新计算的拟合曲线。
"""
# R2计算
def R2(target, predict):
SSE = sum((target - predict) ** 2)
SST = sum((target - (target).mean()) ** 2)
return 1 - (SSE / SST)
if __name__ == '__main__':
# x: 是观测值; y: 是模型预测值
x = np.random.random((100))
y = (x+np.sin(np.random.random((100))))/2
fig, ax = plt.subplots(figsize=(3, 3), dpi=100)
# 绘制1:1对角线,linewidth线的粗细,ls线的格式,c线的颜色,
ax.plot((0, 1), (0, 1), linewidth=1, transform=ax.transAxes, ls='--', c='k', label="1:1 line", alpha=0.5)
# 绘制点,'o'点的形状,点的颜色,markersize点的大小
ax.plot(x, y, 'o', c='black', markersize=5)
# polyfit(x, y, 1),1代表线性拟合
# parameter返回的是线性拟合线的斜率和截距
parameter = np.polyfit(x, y, 1)
f = np.poly1d(parameter)
ax.plot(x, f(x), 'r-', lw=1)
# 计算决定系数R
r2 = R2(x,y)
print(r2)
# 那个框框的设置
bbox = dict(boxstyle="round", fc='1', alpha=0.)
bbox = bbox
# 在图上安放R2和拟合曲线公式,0.05和0.87是位置偏移量,自己调试
plt.text(0.05, 0.87, "$R^2=%.2f$\n$y=%.2fx+%.2f$" % ((r2), parameter[0], parameter[1]),
transform=ax.transAxes, size=7, bbox=bbox)
# 横轴的设置
ax.set_xlabel('Measured values($g\cdot kg^{-1}$)', fontsize=7)
ax.set_ylabel("Predicted values($g\cdot kg^{-1}$)", fontsize=7)
# 设置图片title
ax.tick_params(labelsize=7)
ax.set_title("pre", fontsize=7)
x_major_locator = MultipleLocator(0.1)
ax.xaxis.set_major_locator(x_major_locator)
y_major_locator = MultipleLocator(0.1)
ax.yaxis.set_major_locator(y_major_locator)
# 坐标轴
ax.set(xlim=(-0.05, 1.05), ylim=(-0.05, 1.05))
# plt.savefig("out.png", bbox_inches='tight')
plt.show()
在给出其他方法计算截距和斜率的方法:
import numpy as np
from scipy.stats import linregress
import statsmodels.api as sm
# Example usage
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 6, 8, 10])
# 第一种
def calculate_r_squared(x, y):
'''Calculates the coefficient of determination (R-squared) and tests for significant correlation between two datasets.
Parameters:
- x: the first dataset
- y: the second dataset
'''
# Calculate linear regression. slope: 斜率,intercept: 截距
slope, intercept, r_value, p_value, std_err = linregress(x, y)
# Calculate coefficient of determination (R-squared)(决定系数,但是这个决定系数是基于linregress回归的结果的)
r_squared = r_value**2
# Check for significant correlation(同理,基于linregress回归的结果的)
if p_value < 0.05:
result = "Significant correlation"
else:
result = "Non-significant correlation"
return result, r_squared, p_value
result, r_squared, p_value = calculate_r_squared(x, y)
print(result)
print("Coefficient of determination (R-squared):", r_squared)
print("P-value:", p_value)
# 第二种
def calculate_r_squared_sm(x,y):
# 添加截距项
x = sm.add_constant(x)
# 创建线性回归模型
model = sm.OLS(y, x)
# 拟合数据
results = model.fit()
# 提取决定系数(决定系数,但是这个决定系数是基于OLS回归的结果的)
r_squared = results.rsquared
# 计算相关性显著性(同理, 基于OLS回归的结果的)
p_value = results.f_pvalue
# 获取截距项和系数
intercept = results.params[0] # 截距项
coefficient = results.params[1] # 系数
return r_squared,p_value, [intercept,coefficient]
print(calculate_r_squared_sm(x,y))