一元线性回归模型:
ε:模型误差项,平衡等号两边值
import seaborn as sns
income = pd.read_csv(r'Salary_Date.csv')
sns.lmplot(x='YearExperience',y='Salary',
data=income,ci=None)
plt.show()
线性拟合求解:
误差项最小,转换为误差平方项最小
最小时,偏导数为0
①使用基本语法求解
n = income.shape[0]
sum_x = income.YearsExperience.sum()
sum_y = income.Salary.sum()
sum_x2 = income.YearsExperience.pow(2).sum()
xy = income.YearsExperience * income.Salary
sum_xy = xy.sum()
b = (sum_xy - sum_x * sum_y / n) / (sum_x2 - sum_x ** 2 / n)
a = sum_y.mean() - b * sum_x.mean()
②使用statsmodels中的ols函数
ols(formula,data,subset=None,drop_cols)
formula:‘y~x’
subset:bool类型,子集建模
import statsmodels.api as sm
fit = sm.formula.ols('income.Salary ~ income.YearsExperience',data=income).fit()
fit.params
多元线性回归
构建多元线性回归的数据集包含n个观测,p+1个变量(p个自变量,1个因变量)
β:p1的一维向量,偏回归系数
ε:n1的一维向量,误差项
常量,转置为本身
Prodict_Profit.xlsx
State为字符型离散变量
from sklearn import model_selection
import statsmodels.api as sm
profit = pd.read_excel(r'Prodict_Profit.xlsx')
train,test = model_selection.train_test_split(profit,test_size=0.2,random_state=1234)
model = sm.formula.ols('Profit ~ RD_Spend + Administration + Marketing_Spend + C(State)',data=train).fit()
print(model.params)
test_X = test.drop(labels='Profit',axis=1)
pred = model.predict(exog=test.X)
print({'prediction':pred,'real':test.Porfit})
State为离散变量,建模时为哑变量,嵌套在C(),表示为category变量。
State:Cal,Flo,NY。模型中默认将Cal作为对照组。
将NY作为对照组
dummies = pd.get_dummies(profit.State)
profit_new = pd.concat([profit,dummies],axis=1)
profit_new.drop(labels=['State','New York'],axis=1,inplace=True)
train,test = model_selection.train_test_split(profit_new,test_size=0.2,random_state=1234)
model2 = sm.formula.ols('Profit ~ RD_Spend + Administration + Marketing_Spend + Flo + Cal',data=train).fit()
print(model2.params)
从state中演变出来的哑变量在回归系数中只保留了Flo和Cal,而NY作为参照组。
以RD_Spend和Fla为例:在其他变量不变的情况下,研发成本每增加1元,利润增加0.8元;在其他不变的情况下,以NY为基准,在Flo销售,增加1440元。
回归模型的假设检验
模型的显著性检验是构成因变量的线性组合是否有效,即模型中是否存在一个自变量能够真正影响到因变量的波动,整体的效应。
回归系数的显著性检验是说明单个自变量在模型中是否有效。
模型显著性和回归系数显著性分别使用统计学中的F检验,t检验。
- F检验
①提出问题原假设和备选假设
通过数据推翻H0,接受H1
②构造统计量
ESS:误差平方和,随时间变动
RSS:回归离差平方和,随时间变动
TSS:总离差平方和,不变
TSS=ESS+RSS
线性回归模型的参数求解,使ESS最小,则RSS最大。
构造F统计量
p:RSS自由度
n-p-1:ESS自由度
③
import numpy as np
ybar = train.Profit.mean()
p = model2.df_model
n = train.shape[0]
RSS = np.sum((model2.fittedvalues - ybar) **2)
ESS = np.sum(model2.resid **2)
F = (RSS / p) / (ESS / (n-p-1))
print(F)
#验证手动计算值是否正确
model2.fvalue
④对比F统计量的值和理论F分布的值
#调用计算理论分布值
from scipy.stats import f
F_throry = f.ppf(q=0.95,dfn=p,dfd=n-p-1)
print(F_theory)
F统计量值远远大于F分布的理论值,所以拒绝原假设,认为多元线性回归模型是显著的,所以回归模型的偏回归系数不全为0。
- 回归系数的显著性检验,t检验
①提出假设
原假设:第j变量的偏回归系数为0
②构造统计量
③计算统计量
model2.summary()
第一部分:
模型的判决系数R-squared:自变量对因变量的解释程度
模型的F-statistic:检验模型的显著性
模型的信息准则AIC,BIC:对比模型的拟合效果好坏
第二部分:
回归系数的估计值Coef,t统计量值,回归系数的置信区间
第三部分:
模型误差项ε的有关信息,检验误差项独立性的杜宾-瓦特森统计量Durbin-Watson,衡量误差项是否服从正态分布的JB统计量,误差项偏度Skew,峰度Kurtosis
④第二部分含有每个偏回归系数的t统计量值,由估计值Coef和标准误Std err的商所得,每个t统计量都对应了概率值p,用来判别统计量是否显著的直接方法,通常概率p小于0.05时表示拒绝原假设,未通过表示变量不是重要因素。
检验通过后,开始对模型进行诊断
回归模型的诊断
模型的假设对残差项要求服从正态分布,实质要求因变量服从正态分布。
正态性检验运用两种方法:
定性的图形法
定量的非参数法
①直方图法
import scipy.stats as stats
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode-minus'] = False
plt.style.use('ggplot')
sns.distplot(a=profit_new.Profit,bins=10,fit=stats.norm,norm_hist=True,
hist_kws=['color':'steelblue','edgecolor':'blue'],
kde_kws=['color':'orange','linestyle':'-','label':True],
fit_kws=['color':red,'linestyle':'--'])
plt.legend()
plt.show()
绘制变量Profit的直方图,核密度曲线,理论正态分布,如果两条曲线近似或者吻合,说明服从正态分布。
②PP图,QQ图
#残差的正态检验
import ststamodels.api as sm
pp_qq_plot = sm.ProbPlot(profit_new.Profit)
#PP图
pp_qq_plot.ppplot(line=45)
plt.title('PP图')
pp_qq_plot.qqplot(line='q')
plt.title('QQ图')
plt.show()
PP图:对比正态分布的累计概率值和实际分布的累计概率值
QQ图:对比正态分布的分位数和世纪分布的分位数
判断变量是否服从正态分布的标准:散点都比较均匀的落在直线上。
③Shapiro K-S
假设变量服从正态分布,若数据小于5000,使用shapiro检验
import scipy.stats as stats
stats.shapiro(profit_new.Profit)
返回元组,第一个元素是shapiro检验的统计量值,第二个元素是对应的概率p,由于p值大于置信水平0.05,故接受利润分布服从正态分布
#生成正态分布和均匀分布
rnorm = np.random.normal(loc=5,scale=2,size=1000)
runif = np.random.unifrom(low=1,high=100,size=1000)
#正态性检验
KS_test1 = stats.kstest(rvs=rnorm,args=(rnorm.mean(),rnorm.std()),cdf='norm')
KS_test2 = stats.kstest(rvs=runif,args=(runif.mean(),runif.std()),cdf='norm')
正态随机分布随机数的检验p值大于置信水平0.05,接受原假设
均匀分布p值小于0.05,拒绝原假设
使用kstest函数对变量进行正态性检验,必须指定args参数,传递被检验变量的均值和标准差
变量检验成果不满足正态分布,使用数学转换。
来源:https://blog.csdn.net/qq_32733847/article/details/98341657