Python 各种回归(含sklearn)

机器学习
https://www.jb51.net/article/164603.htm
多元回归
https://zhuanlan.zhihu.com/p/61084966?utm_source=wechat_session
正态性检验
https://blog.csdn.net/QimaoRyan/article/details/72861387

# 定义模型预测准确率得分
n_folds = 5
def score(model):
    kf = KFold(n_folds, shuffle=True, random_state=20)
    score=cross_val_score(model,x, y, scoring="accuracy", cv = kf)
    return(score.mean())

一、多元线性回归

调用statsmodels模块中的子模块ols函数。有关该函数的语法及参
数含义可见下方:
ols(formula, data, subset=None, drop_cols=None)
formula:以字符串的形式指定线性回归模型的公式,如’y~x1+x2+x3’(对于非数值的离散变量,建模时必须将其设置为哑变量的效果,实现方式很简单,将该变量套在C()中,表示将其当作分(Category)变量处理即可。即含定性自变量的回归模型)
C()无法选择对照变量(包含在常数中的变量) ,随机选
data:指定建模的数据集。
subset:通过bool类型的数组对象,获取data的子集用于建模。
drop_cols:指定需要从data中删除的变量。

实训任务1:产品利润预测

数据集包含5个变量,分别是产品的研发成本、管理成本、市场营销成本、销售市场和销售利润,请完成以下任务:
(1)将数据集划分为训练集和测试集,其中测试集占比20%,完成多元线性回归建模;
(2)完成F检验和t检验;
(3)完正态性检验、多重共线性检验、线性相关性检验、异常值检验、独立性检验、方差齐性检验;
(4)使用最终确定的模型进行预测,并画出图形,比较预测值和实际值。

###方法罗列,不是完整顺序
# 工作年限与收入之间的散点图
# 导入第三方模块
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 导入数据集
income = pd.read_csv(r'C:\Users\Administrator\Desktop\Salary_Data.csv')
# 绘制散点图
sns.lmplot(x = 'YearsExperience', y = 'Salary', data = income, ci = None)
# 显示图形
plt.show()

# 简单线性回归模型的参数求解
# 样本量
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 = income.Salary.mean()-b*income.YearsExperience.mean()
# 打印出计算结果
print('回归参数a的值:',a)
print('回归参数b的值:',b)

# 导入第三方模块
import statsmodels.api as sm
# 利用收入数据集,构建回归模型
fit = sm.formula.ols('Salary ~ YearsExperience', data = income).fit()
# 返回模型的参数值
fit.params



####====== 多元线性回归模型的构建和预测==========
# 导入模块
from sklearn import model_selection
# 导入数据
Profit = pd.read_excel(r'C:\Users\Administrator\Desktop\Predict to Profit.xlsx')
# 将数据集拆分为训练集和测试集
train, test = model_selection.train_test_split(Profit, test_size = 0.2, random_state=1234)
# 根据train数据集建模
model = sm.formula.ols('Profit ~ RD_Spend + Administration + Marketing_Spend + C(State)', data = train).fit()
print('模型的偏回归系数分别为:\n', model.params)
# 删除test数据集中的Profit变量,用剩下的自变量进行预测
test_X = test.drop(labels = 'Profit', axis = 1)
pred = model.predict(exog = test_X)
print('对比预测值和实际值的差异:\n',pd.DataFrame({
   'Prediction':pred,'Real':test.Profit}))

# 生成由State变量衍生的哑变量
dummies = pd.get_dummies(Profit.State)
# 将哑变量与原始数据集水平合并
Profit_New = pd.concat([Profit,dummies], axis = 1)
# 删除State变量和California变量(因为State变量已被分解为哑变量,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)

# 导入第三方模块
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)
## 直接得
# 返回模型中的F值
model2.fvalue

### 正态性检验
## 直方图法
# 导入第三方模块
import scipy.stats as stats
# 中文和负号的正常显示
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
# 绘制直方图
sns.distplot(a = Profit_New.Profit, bins = 10, fit = stats.norm, norm_hist = True,
             hist_kws = {
   'color':'steelblue', 'edgecolor':'black'}, 
             kde_kws = {
   'color':'black', 'linestyle':'--', 'label':'核密度曲线'}, 
             fit_kws = {
   'color':'red', 'linestyle':':', 'label':'正态密度曲线'})
# 显示图例
plt.legend()
# 显示图形
plt.show()

## 残差的正态性检验(PP图和QQ图法)
pp_qq_plot = sm.ProbPlot(Profit_New.Profit)
# 绘制PP图
pp_qq_plot.ppplot(line = '45')
plt.title('P-P图')
# 绘制QQ图
pp_qq_plot.qqplot(line = 'q')
plt.title('Q-Q图')
# 显示图形
plt.show()

## shapiro检验(数据<5000)
# 导入模块
import scipy.stats as stats
stats.shapiro(Profit_New.Profit)

## K-S检验
# 生成正态分布和均匀分布随机数(随机数据)
rnorm = np.random.normal(loc = 5, scale=2, size = 10000)  #正态分布
runif = np.random.uniform(low = 1, high = 100, size = 10000)  #均匀分布
# 正态性检验
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')
  #rvs:待检验的数据 cdf:检验方法,norm即正态性检验
print(KS_Test1)
print(KS_Test2)

### 多重共线性检验
# 导入statsmodels模块中的函数
from statsmodels.stats.outliers_influence import variance_inflation_factor
# 自变量X(包含RD_Spend、Marketing_Spend和常数列1)
X = sm.add_constant(Profit_New.ix[:,['RD_Spend','Marketing_Spend']])

# 构造空的数据框,用于存储VIF值
vif = pd.DataFrame()
vif["features"] = X.columns
vif["VIF Factor"] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
# 返回VIF值
vif

### 线性相关性检验
# 计算数据集Profit_New中每个自变量与因变量利润之间的相关系数
Profit_New.drop('Profit', axis = 1).corrwith(Profit_New.Profit)

# 散点图矩阵
# 导入模块
import matplotlib.pyplot as plt
import seaborn
# 绘制散点图矩阵
seaborn.pairplot(Profit_New.ix[:,['RD_Spend','Administration','Marketing_Spend','Profit']])
# 显示图形
plt.show()

### 模型修正(去掉不显著的)
model3 = sm.formula.ols('Profit ~ RD_Spend + Marketing_Spend', data = train).fit()
# 模型回归系数的估计值
model3.params

### 异常值检验
outliers = model3.get_influence()
# 高杠杆值点(帽子矩阵)
leverage = outliers.hat_matrix_diag
# dffits值(不常用)
dffits = outliers.dffits[0]
# 学生化残差
resid_stu = outliers.resid_studentized_external
# cook距离
cook = outliers.cooks_distance[0]

# 合并各种异常值检验的统计量值
contat1 = pd.concat([pd.Series(leverage, name = 'leverage'),pd.Series(dffits, name = 'dffits'),
                     pd.Series(resid_stu,name = 'resid_stu'),pd.Series(cook, name = 'cook')],axis = 1)
# 重设train数据的行索引
train.index = range(train.shape[0])
# 将上面的统计量与train数据集合并
profit_outliers = pd.concat([train,contat1], axis = 1)
profit_outliers.head()

# 计算异常值数量的比例
outliers_ratio = sum(np.where((np.abs(profit_outliers.resid_stu)>2),1,0))/profit_outliers.shape[0]
outliers_ratio
# 挑选出非异常的观测点
none_outliers = profit_outliers.ix[np.abs(profit_outliers.resid_stu)<=2,]

# 应用无异常值的数据集重新建模
model4 = sm.formula.ols('Profit ~ RD_Spend + Marketing_Spend', data = none_outliers).fit()
model4.params

### 独立性检验
# Durbin-Watson统计量
# 模型概览
model4.summary()

### 方差齐性检验
## 图形法
# 设置第一张子图的位置
ax1 = plt.subplot2grid(shape = (2,1), loc = (0,0))
# 绘制散点图
ax1.scatter(none_outliers.RD_Spend, (model4.resid-model4.resid.mean())/model4.resid.std())
# 添加水平参考线
ax1.hlines(y = 0 ,xmin = none_outliers.RD_Spend.min(),xmax = none_outliers.RD_Spend.max(), color = 'red', linestyles = '--')
# 添加x轴和y轴标签
ax1.set_xlabel('RD_Spend')
ax1.set_ylabel('Std_Residual')

# 设置第二张子图的位置
ax2 = plt.subplot2grid(shape = (2,1), loc = (1,0))
# 绘制散点图
ax2.scatter(none_outliers.Marketing_Spend, (model4.resid-model4.resid.mean())/model4.resid.std())
# 添加水平参考线
ax2.hlines(y = 0 ,xmin = none_outliers.Marketing_Spend.min(),xmax = none_outliers.Marketing_Spend.max(), color = 'red', linestyles = '--')
# 添加x轴和y轴标签
ax2.set_xlabel('Marketing_Spend')
ax2.set_ylabel('Std_Residual')

# 调整子图之间的水平间距和高度间距
plt.subplots_adjust(hspace=0.6, wspace=0.3)
# 显示图形
plt.show()

## BP检验法(方差齐性)
sm.stats.diagnostic.het_breushpagan(model4.resid, exog_het = model4.model.exog)

### 模型预测
# model4对测试集的预测
pred4 = model4.predict(exog = test.ix[:,['RD_Spend','Marketing_Spend']])
# 绘制预测值与实际值的散点图
plt.scatter(x = test.Profit, y = pred4)
# 添加斜率为1,截距项为0的参考线
plt.plot([test.Profit.min(),test.Profit.max()],[test.Profit.min(),test.Profit.max()],
        color = 'red', linestyle = '--')
# 添加轴标签
plt.xlabel('实际值')
plt.ylabel('预测值')
# 显示图形
plt.show()
实训任务2:上市公司来年盈利状况的预测

本案例随机抽取深市和沪市2002年和2003年各500个样本,对上市公司的净资产收益率(return on equity, ROE)进行预测。
我们要求使用2002年的样本来建立模型,2003年的数据用来检验模型的预测精度。

目标:盈利预测
因变量:下一年的净资产收益率(ROE)
自变量:当年的财务信息
样本容量:2002年500;2003年500

ROEt: 当年净资产收益率
ATO: 资产周转率(asset turnover ratio)
LEV: 债务资本比率(debt to asset ratio)反映公司基本债务状况
PB: 市倍率(price to book ratio)反映公司预期未来成长率
ARR: 应收账款/主营业务收入(account receivable over total income)反映公司的收入质量
PM: 主营业务利润/主营业务收入(profit margin)反映公司利润状况
GROWTH: 主营业务增长率(sales growth rate)反映公司已实现的当年增长率
INV: 存货/资产总计(inventory to asset ratio)反映公司的存货状况
ASSET: (对数)资产总计(log-transformed asset)反映公司的规模

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import statsmodels.api as sm

# 导入数据集
data = pd.read_csv(r'C:\Users\hp\Desktop\roe.csv')

# 将数据集拆分为训练集和测试集
train=data.iloc[0:500]
test=data.iloc[500:]

# 根据train数据集建模
model = sm.formula.ols('ROE~ROEt+ATO+PM+LEV+GROWTH+PB+ARR+INV+ASSET', data = train).fit()
print('模型的偏回归系数分别为:\n', model.params)
model.summary()
'''
ROEt、LEV、GROWTH系数显著
'''

### 线性相关性检验
## 计算每个自变量与因变量利润之间的Marketin相关系数
data.drop('ROE'
  • 5
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值