1.常见的回归函数
2.工具
数据分析有很多成熟的工具可以使用,如R、python、spss等。此处我们选用python进行分析。首先,我们需要安装并导入python数据分析常用的库。
# 工具:python3
#固定导入
import numpy as np #科学计算基础库,多维数组对象ndarray
import pandas as pd #数据处理库,DataFrame(二维数组)
import matplotlib as mpl #画图基础库
import matplotlib.pyplot as plt#最常用的绘图库
from scipy import stats #scipy库的stats模块
mpl.rcParams["font.family"]="SimHei" #使用支持的黑体中文字体
mpl.rcParams["axes.unicode_minus"]=False # 用来正常显示负号 "-"
plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
# % matplotlib inline #jupyter中用于直接嵌入图表,不用plt.show()
import warnings
warnings.filterwarnings("ignore") #用于排除警告
#用于显示使用库的版本
print("numpy_" + np.__version__)
print("pandas_" + pd.__version__)
print("matplotlib_"+ mpl.__version__)
3.线性回归分析
Y= aX + b + e ,e表示残差。
线性回归:分析结论的前提:(数据满足统计假设)
-
正态性:预测变量固定时,因变量正态分布;
-
独立性:因变量互相独立;
-
线性:因变量与自变量线性(残差白噪声);
-
同方差性:残差方差均匀。
3.1 statsmodels.formula.api.OLS():普通最小二乘模型拟合- - 常用
tips = pd.read_csv(r"D:\Case_data/tips.csv",sep=',',encoding='utf-8')
#导入txt格式数据
display(tips.sample(3))
#随机抽取3行数据
import statsmodels.formula.api as sm
#statsmodels.formula.api.ols 回归模型库
model = sm.OLS(tips["total_bill"], tips["tip"])
# OLS 是普通最小二乘,sm 中还有很多其它方法解决不同的问题
# total_bill:因变量, tip:自变量
result = model.fit() # 做拟合
print(result.summary())
#返回拟合总结信息
print(result.params)
# 对应的各个变量的权重
resid = result.resid
# 输出残差
print(type(resid))
# <class 'pandas.core.series.Series'>
print(stats.normaltest(result.resid.values))
#对残差进行正态分布检验,p<阀值,拒绝原假设,则是正态分布
figure = plt.figure(num="画布1",figsize=(8,4),dpi=80,facecolor="gray",edgecolor="blue",frameon=True)
axes1=figure.add_subplot(1,2,1)
plt.title("残差图")
axes1.plot(result.resid) #看看残差图
axes2=figure.add_subplot(1,2,2)
plt.title('分布/拟合图')
plt.xlabel('tip')
plt.ylabel('total_bill')
axes2.plot(tips["tip"],tips["total_bill"],'bo',tips["tip"],result.params[0]*tips["tip"],'r-')
plt.legend(["total_bill","total_bill拟合"],loc="best", frameon=False, ncol=2)
plt.show()
模型解释:
-
result.summary()的输出解释:R-squared:0.892,Adj. R-squared:0.891 都比较大,说明模型是比较显著的;
-
tip权值检验p:0.000,非常小,拒绝原假设,说明系数的正确性也是非常显著的;
-
stats.normaltest(result.resid.values) :对残差进行正态分布检验,p<阀值,说明残差也是符合要求。
-
模型可用公式为:total_bill = 6.2052 * tip
3.2 scipy.optimize.curve_fit():回归函数拟合
from scipy.optimize import curve_fit
#回归函数拟合包
def func(x,a,b):
y = a*x + b
return y
x= np.array([150,200,250,350,300,400,600])
ydata=np.array([6450,7450,8450,9450,11450,15450,18450])
popt,pcov=curve_fit(func,x,ydata)
print(curve_fit(func,x,ydata))
#拟合函数 y = 28.03191489*x + 2011.17021277
plt.title('分布图')
plt.xlabel('x')
plt.ylabel('y')
plt.plot(x,ydata,'bo',x,func(x,popt[0],popt[1]),'r-')
plt.legend(["ydata","y拟合"],loc="best", frameon=False, ncol=1)
plt.show()
3.3 scipy.stats.linregress(): 线性拟合
from scipy import stats #线性回归包
x= np.array([150,200,250,350,300,400,600])
ydata=np.array([6450,7450,8450,9450,11450,15450,18450])
slope, intercept, r_value, p_value, std_err = stats.linregress(x,ydata)
#a ,b ,r ,p ,标准误
print(slope, intercept, r_value, p_value, std_err)
print(stats.linregress(x,ydata))
y = slope*x + intercept #拟合函数
3.4 statsmodels.formula.api.ols():采取公式的方式
np.random.seed(123456789)
N = 100
x1 = np.random.randn(N) # 自变量
x2 = np.random.randn(N)
data = pd.DataFrame({"x1": x1, "x2": x2})
def y_true(x1, x2):
return 1 + 2 * x1 + 3 * x2 + 4 * x1 * x2
data["y_true"] = y_true(x1, x2) # 因变量
e = np.random.randn(N) # 标准正态分布
data["y"] = data["y_true"] + e
# 加些噪音,加些扰动,噪音是符合标准正态分布的
data.head(3)
import statsmodels.formula.api as sm
#statsmodels.formula.api.ols 回归模型库
model = sm.ols("y ~x1 + x2", data)
# 这里没有写截距,截距是默认存在的
# model = sm.ols("y ~ -1 + x1 + x2", data)
# 这里加上-1,表示不加截距
result = model.fit()
print(result.summary())