文章目录
一元线性回归
如果需要查找两个变量之间是否存在线性关系
1.散点图
散点图只能反映出两个变量之间是否存在线性关系
并不能直接断定两个变量没有关系(还可能存在非线性关系)
2.公式计算
利用线性计算公式推导两个变量之间的关系
大于0.8说明两个变量存在明显的线性关系
大于0.5小于0.8说明两个变量存在线性关系
大于0.3小于0.5说明两个变量可能存在线性关系
小于0.3说明两个变量之间不存在线性关系(没有关系、非线性)
# 数学概念
因变量:受自变量的影响而改变
自变量:由实验者操纵、掌握的变量
自变量是原因,因变量是结果
ex:
x称为⾃变量,y称为因变量
a为模型的截距项,b为模型的斜率项,ε为模型的误差项;
误差项ε的存在主要是为了平衡等号两边的值,通常被称为模型无法解释的部分
一元线性回归代码
import pandas as pd
import statsmodels.api as sm
import matplotlib.pyplot as plt
df1 = pd.read_csv(r'Salary_Data.csv')
# 先画出工作年限和薪资待遇的散点图
# 绘制散点图
plt.scatter(x = df1.YearsExperience, # 指定散点图的x轴数据
y = df1.Salary, # 指定散点图的y轴数据
color = 'steelblue' # 指定散点图中点的颜色
)
# 添加x轴和y轴标签
plt.xlabel('YearsExperience')
plt.ylabel('Salary')
# 添加标题
plt.title('Salary&YearsExperience')
# 显示图形
plt.show()
# 使用线性回归公式计算方程
fit = sm.formula.ols('Salary~YearsExperience',data=df1).fit()
fit.params
Intercept 25792.200199 截距项
YearsExperience 9449.962321 斜率项
公式:
Salary = 25792.200199 + 9449.962321YearsExperience
多元线性回归模型
1.对于一元线性回归模型来说,其反映的是单个自变量对因变量的影响,
然而实际情况中,影响因变量的自变量往往**不止一个**,
从而需要将一元线性回归模型扩展到多元线性回归模型
2.训练集
主要就是用来模拟出数学模型
测试集
主要就是用来测试模拟的数学模型是否准确
通常将数据集的80%作为训练集,20%作为训练集
我们在研究因变量与自变量关系的时候,如果自变量不止一个,
那么我们需要确保多个自变量之间互相没有干扰(不能有关系)
通常采取的策略是先转换成数值型变量,之后随即删除一个用来解决自变量之间强烈相关性问题
3.离散型变量
非数值类型的数据
连续型变量
数字类型的数据
4.多个自变量之间一定不能存在强烈的关系
多元线性回归代码
from sklearn import model_selection
df2 = pd.read_excel(r'Predict to Profit.xlsx') #读取数据
df2.head()
# 将数据拆分成训练集(80%)和测试集(20%)
train,test = model_selection.train_test_split(df2,test_size=0.2,random_state=1234)
# 依据训练集创建模型(State不是数值型变量 带入模型需要加C)
model = sm.formula.ols('Profit~RD_Spend+Administration+Marketing_Spend+C(State)',
data=train).fit()
# 离散型变量转换用 C(数据字段) 非数字都可以
# .fit() 拟合
print('模型的偏回归系数分别为:\n', model.params)
模型的偏回归系数分别为:
Intercept 58581.516503
C(State)[T.Florida] 927.394424
C(State)[T.New York] -513.468310
RD_Spend 0.803487
Administration -0.057792
Marketing_Spend 0.013779
dtype: float64
排除干扰随机删除一项,只保留new york和florida
# 利用模型验证
# 先删除实际因变量利润 用模型产生预测利润
test_X = test.drop(labels='Profit',axis=1)
# 模型预测
pred = model.predict(exog = test_X)
print('对比预测值和实际值的差异:\n',
pd.DataFrame({
'Prediction':pred,
'Real':test.Profit}))
对比预测值和实际值的差异:
Prediction Real
8 150621.345801 152211.77
48 55513.218079 35673.41
14 150369.022458 132602.65
42 74057.015562 71498.49
29 103413.378282 101004.64
44 67844.850378 65200.33
4 173454.059691 166187.94
31 99580.888894 97483.56
13 128147.138396 134307.35
18 130693.433835 124266.90
预测与实际结果比较相当接近
自定义哑变量
又称虚设变量、名义变量或哑变量,用以反映质的属性的一个人工变量,是量化了的自变量,通常取值为0或1。引入哑变量可使线形回归模型变得更复杂,但对问题描述更简明,一个方程能达到两个方程的作用,而且接近现实。
模型中引入虚拟变量的**作用**
1、分离异常因素的影响,例如分析我国GDP的时间序列,必须考虑“**”因素对国民经济的破坏性影响,剔除不可比的“**”因素。
2、检验不同属性类型对因变量的作用,例如工资模型中的文化程度、季节对销售额的影响。
3、提高模型的精度,相当于将不同属性的样本合并,扩大了样本容量(增加了误差自由度,从而降低了误差方差)
-{
生成有state变量衍生的哑变量
dummies = pd.get_dummies(变量名.State)
将哑变量与原始数据集水平合并
Profit_New = pd.concat([变量名,dummies], axis = 1)
删除不需要的值
Profit_New.drop(labels = ['State','*****'], axis = 1, inplace = True)
}
# 生成由State变量衍生的哑变量
dummies = pd.get_dummies(df2.State)
# 将哑变量与原始数据集水平合并
Profit_New = pd.concat([df2,dummies], axis = 1)
Profit_New.head()
# 删除不需要的值 手动剔除new york
Profit_New.drop(labels = ['State','New York'], axis = 1, inplace = True)
# 拆分数据集Profit_New
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+Florida+California', data = train).fit()
print('模型的偏回归系数分别为:\n', model2.params)
# model2测出各种系数
模型的偏回归系数分别为:
Intercept 58068.048193
RD_Spend 0.803487
Administration -0.057792
Marketing_Spend 0.013779
Florida 1440.862734
California 513.468310
dtype: float64
这里就删除了new york进行建模预测
# 利用模型验证
# 先删除实际因变量利润 用模型产生预测利润
test_X = test.drop(labels='Profit',axis=1)
# 模型预测
pred = model2.predict(exog = test_X)
print('对比预测值和实际值的差异:\n',
pd.DataFrame({
'Prediction':pred,
'Real':test.Profit}))
对比预测值和实际值的差异:
Prediction Real
8 150621.345802 152211.77
48 55513.218079 35673.41
14 150369.022458 132602.65
42 74057.015562 71498.49
29 103413.378282 101004.64
44 67844.850378 65200.33
4 173454.059692 166187.94
31 99580.888895 97483.56
13 128147.138397 134307.35
18 130693.433835 124266.90
和未引入哑变量(手动删除一项、)的预测结果相差不大
模型检验之F检验
F检验(F-test),最常用的别名叫做**联合假设检验**,此外也称方差比率检验、方差齐性检验。
它是一种在零假设之下,统计值服从F-分布的检验。
其通常是用来分析用了超过一个参数的统计模型,以判断该模型中的全部或一部分参数是否适合用来估计母体。
*检验模型的合理性*
计算得到的F值,再与对应F分布表查询,若大于表中的值,则接受原假设(两样本的方差相同),否则拒绝原假设。
#导入第三方模块
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统计量的值
F = (RSS/p)/(ESS/(n-p-1))
print('F统计量的值:',F)
out:
F的统计量的值:174.6372
可以看出计算出来的F统计量值174.64远远大于理论值2.50,
所以应当拒绝原假设,即多元线性回归模型是显著的,也就是说回归模型的偏回归系数都不全为0。
————————————————
原代码:https://blog.csdn.net/weixin_49855757/article/details/109231165
结论
模型检验之T检验
*检验系数的合理性*
# 查看T检验
model2.summary()
P>|t| 系数越小,影响利润的程度越大、高
首先是 RD_Spend 0.000 # 研发成本
其次是 Administration 0.265 # 管理成本
才是 Marketing_Spend 0.359 # 销售额
最后才是是地区 # 跟地区关系不大
线性回归模型的短板
1.自变量的个数多于样本量
2.多个自变量之间存在多重共线性
岭回归模型
目的是优化线性回归
为解决多元线性回归模型中可能存在的不可逆问题,统计学家提出了岭回归模型
该模型的思路是在线性回归模型的目标函数之上添加一个 l2 正则项(惩罚项)
用于平衡模型方差和偏差
l2其实本质就是平方项
线性回归模型的目标函数
为了保证回归系数β \betaβ可求,岭回归模型在目标函数上加了一个L2范数的惩罚项
其中λ为非负数,λ 越大,则为了使J ( β ) 最小,回归系数 β 就越小。
————————————————
详细可看:https://blog.csdn.net/weixin_43374551/article/details/83688913
import pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn.linear_model import Ridge
import matplotlib.pyplot as plt
data=pd.read_excel(r'diabetes.xlsx')
#拆分为训练集和测试集
predictors=data.columns[:-1]
x_train,x_test,y_train,y_test=model_selection.train_test_split(data[predictors],data.Y,
test_size=0.2,random_state=1234)
#构造不同的lambda值
Lambdas=np.logspace(-5,2,200)
#存放偏回归系数
ridge_cofficients=[]
for Lambda in Lambdas:
ridge=Ridge(alpha=Lambda,normalize=True)
ridge.fit(x_train,y_train)
ridge_cofficients.append(ridge.coef_)
#绘制岭迹曲线
plt.rcParams['font.sans-serif']=['Microsoft YaHei']
plt.rcParams['axes.unicode_minus']=False
plt.style.use('ggplot')
plt.plot(Lambdas,ridge_cofficients)
#x轴做对数处理
plt.xscale('log')
plt.xlabel('Log(Lambda)')
plt.ylabel('Cofficients')
plt.show()
'''曲线不容易看出最小值'''
交叉验证
将数据先进行分组,之后取一组作为测试集,其他组作为训练集
依次往复,知道所有的分组都参与了模型的训练和测试为止,最后选出最佳模型
- 交叉验证公式
RidgeCV(alphas=(0.1,1.0,10.0),fit_intercept=True,normalize=False,
scoring=None,cv=None)
alphas:用于指定多个lambda值的元组或数组对象,默认该参数包含0.1、1和10三种值
fit_intercept:bool类型参数,是否需要拟合截距项,默认为True
normalize:bool类型参数,建模时是否需要对数据集做标准化处理,默认为False
scoring:指定用于评估模型的度量方法
cv:指定交叉验证的重数
--------------------
- 代码
import pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn.linear_model import RidgeCV
data=pd.read_excel(r'diabetes.xlsx')
#拆分为训练集和测试集
predictors=data.columns[:-1]
x_train,x_test,y_train,y_test=model_selection.train_test_split(data[predictors],data.Y,
test_size=0.2,random_state=1234)
#构造不同的lambda值
Lambdas=np.logspace(-5,2,200)
#设置交叉验证的参数,使用均方误差评估
ridge_cv=RidgeCV(alphas=Lambdas,normalize=True,scoring='neg_mean_squared_error',cv=10)
ridge_cv.fit(x_train,y_train)
print(ridge_cv.alpha_)
'''
0.013509935211980266
'''
import pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn.linear_model import Ridge,RidgeCV
from sklearn.metrics import mean_squared_error
data=pd.read_excel(r'diabetes.xlsx')
data=data.drop(['AGE','SEX'],axis=1)
#拆分为训练集和测试集
predictors=data.columns[:-1]
x_train,x_test,y_train,y_test=model_selection.train_test_split(data[predictors],data.Y,
test_size=0.2,random_state=1234)
#构造不同的lambda值
Lambdas=np.logspace(-5,2,200)
#设置交叉验证的参数,使用均方误差评估
ridge_cv=RidgeCV(alphas=Lambdas,normalize=True,scoring='neg_mean_squared_error',cv=10)
ridge_cv.fit(x_train,y_train)
# 基于最佳lambda值建模
ridge=Ridge(alpha=ridge_cv.alpha_,normalize=True)
ridge.fit(x_train,y_train)
#返回岭回归系数
print(pd.Series(index