数据分析中的常用数学模型实战教程笔记(上)

一元线性回归

如果需要查找两个变量之间是否存在线性关系
	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.1110三种值
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
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值