前言以及回归分析

news/2024/10/14 20:24:10

统计建模

前言

这次想尝试一下统计建模,准备长三角建模的同时,加强一下自己的数据分析能力,学习的教材是张良均的《Python数据分析与挖掘实战》,这本书后面的实战练习相当不错,值得一做,书长下面这样,zlib里有pdf的,里面涉及的代码和数据在本书中均有给出获得方式。此学习笔记仅供参考,大部分内容和书中的内容相同,代码部分会有一些改进。

image-20240430222612646

这本书第1~5章在讲基础部分,主要是数据的处理方法、python的使用以及一些常用的模型与方法,前四章内容我先前接触过,内容较为简单,这里就先略过,从第五章 挖掘建模开始学习。

第五章 挖掘建模

5.1 分类与预测

分类主要是预测分类标号(离散属性), 而预测主要是建立连续值函数模型,预测给定自变量对应的因变量的值。

5.1.1 实现过程

image-20240430223507137

5.1.2 常用算法

image-20240430223559139

5.1.3 回归分析

回归分析:通过建立模型来研究变量之间相互关系的密切程度、结构状态及进行模型预测的有效工具。研究的范围大致如下:

image-20240430223845012

在数据挖掘环境下,自变量与因变量具有相关关系,自变量的值是已知的,因变量是要预测的。

常用的回归模型见下表:

image-20240430224121750

线性回归模型是相对简单的回归模型,但是通常因变量和自变量之间呈现出某种曲线关系,这就需要建立非线性回归模型。

1. Logistic 回归分析介绍

Logistic 回归属于概率型非线性回归,分为二分类和多分类的回归模型。

( 1 )Logistic 函数

Logistic 回归模型中的因变量只有 1-0(如“是”和“否”、“发生”和“不发生”)两种取值。假设在\(p\)个独立自变量\(x_1,x_2,\cdots,x_p\)的作用下,记\(y\)取 1 的概率是\(p=P(y=1\mid X)\) , 取 0 的概率是 1\(-p\) ,取 1 和取 0 的概率之比为\(\frac p{1-p}\),称为事件的优势比(odds),对odds 取自然对数即得 Logistic 变换 \(\mathrm{Logit}(p)=\ln\left(\frac p{1-p}\right)\circ\)

\(\mathrm{Logit}(p)=\ln\left(\frac p{1-p}\right)=z\), 则\(p=\frac1{1+\mathrm{e}^{-z}}\)即为 Logistic 函数,如图所示。

image-20240430231719902
( 2 ) Logistic 回归模型

Logistic 回归模型是建立 \(\ln\left(\frac p{1-p}\right)\)与自变量的线性回归模型。Logistic 回归模型为下式:

\[\ln\biggl(\frac{p}{1-p}\biggr)=\beta_0+\beta_1x_1+\cdots+\beta_px_p+\varepsilon \]

因为\(\ln\left(\frac p{1-n}\right)\)的取值范围是\((-\infty,+\infty)\),这样,自变量 \(x_1,x_2,\cdots,x_p\) 可在任意范围内取值。记\(g(x)=\beta_0+\beta_1x_1+\cdots+\beta_px_p\),得到式\((5-2)\)和式\((5-3)\)

\[p=P(y=1\mid X)=\frac{1}{1+\mathrm{e}^{-g(x)}} \tag{5-2} \]

\[1-p=P(y=0\mid X)=1-\frac{1}{1+\mathrm{e}^{-g(x)}}=\frac{1}{1+\mathrm{e}^{g(x)}}\tag{5-3} \]

( 3 )Logistic 回归模型的解释

\[\frac p{1-p}=\mathrm{e}^{\beta_0+\beta_1x_1+\cdots+\beta_px_p+\varepsilon}\tag{5-4} \]

\(\beta_0:\)在没有自变量,即\(x_1,x_2,\cdots,x_p\)全部取 0 时,\(y=1\)\(y=0\)发生概率之比的自然对数;

\(\beta_1:\)某自变量\(x_i\)变化时,即\(x_i=1\)\(x_i=0\)相比,\(y=1\)优势比的对数值。

image-20240430233117395

2. Logistic 回归建模步骤

image-20240430233506079
( 1 )Code

利用 \(\text{scikit-learn}\) 库对这个数据建立逻辑回归模型

import pandas as pd
from sklearn.linear_model import LogisticRegression as LR
# 参数初始化
filename = '../data/bankloan.xls'
data = pd.read_excel(filename)x = data.iloc[:,:8]
y = data.iloc[:,8]lr = LR()  # 建立逻辑回归模型
lr.fit(x, y)  # 用筛选后的特征数据来训练模型
print('模型的平均准确度为:%s' % lr.score(x, y))

模型的平均准确度为:0.8085714285714286

一些参数如下:

image-20240430233813359

  • model.coef_ 得到[\(\beta_1\),\(\beta_2\),\(\cdots\),\(\beta_k\) ]

  • model.intercept_得到\(\beta_0\),截距,默认有截距

5.1.4 决策树

决策树方法在分类、预测、规则提取等领域有着广泛应用。决策树是一种树状结构,它的每一个叶节点对应着一个分类,非叶节点对应着在某个属性上的划分,根据样本在该属性上的不同取值将其划分成若干个子集。对于非纯的叶节点,多数类的标号给出到达这个节点的样本所属的类。构造决策树的核心问题是在每一步如何选择适当的属性对样本做拆分。对一个分类问题,从已知类标记的训练样本中学习并构造出决策树是一个自上而下、分而治之的过程。

image-20240501183116302

1.ID3算法

image-20240501183540591

这个图片中的公式是关于信息熵的一个变体,特别是针对集合 ( A ) 中的事件 \(( a_1, a_2, \ldots, a_k )\) 对某个特定系统状态 \(S\) 的贡献。这个系统状态 \(S\) 可以进一步细分为 \(( S_1, S_2, \ldots, S_k )\)。公式中的 $E(A) $ 表示的是系统状态 $ S $ 下集合 $ A $ 中各事件的信息熵期望值。

公式 \(E(A)\) 定义如下:

\[E(A) = \sum_{j=1}^k \frac{s_{j}}{s} I(s_{j1}, s_{j2}, \ldots, s_{jm_j}) \]

这里:

  • $s_j $ 表示在状态 $S_j $ 下的特定事件的数量。
  • $s $是所有事件的总数。
  • $I(s_{j1}, s_{j2}, \ldots, s_{jm_j}) $是在状态 $S_j $ 下,对应 $ s_j $ 事件集合的信息熵。

简而言之,这个公式计算的是给定系统状态下,各个子状态的加权信息熵总和。每个子状态的信息熵是根据该子状态的事件数量进行加权的。这种方法常用于考虑条件概率或者系统在不同子状态下的不确定性。

image-20240501183708744

2. ID3 算法具体流程

示例较为简单,自行阅读。

image-20240501184835492 image-20240501185006504

( 1 )具体步骤

就是在按照具体流程一步一步计算。

image-20240501185513678 image-20240501185610927 image-20240501185830494

( 2 )Code

import pandas as pd
# 参数初始化
filename = '../data/sales_data.xls'
data = pd.read_excel(filename, index_col = '序号')  # 导入数据# 数据是类别标签,要将它转换为数据
# 用1来表示“好”“是”“高”这三个属性,用-1来表示“坏”“否”“低”
data[data == '好'] = 1
data[data == '是'] = 1
data[data == '高'] = 1
data[data != 1] = -1
x = data.iloc[:,:3].astype(int)
y = data.iloc[:,3].astype(int)from sklearn.tree import DecisionTreeClassifier as DTC
dtc = DTC(criterion='entropy')  # 建立决策树模型,基于信息熵
dtc.fit(x, y)  # 训练模型# 导入相关函数,可视化决策树。
# 导出的结果是一个dot文件,需要安装Graphviz才能将它转换为pdf或png等格式。
from sklearn.tree import export_graphviz
x = pd.DataFrame(x)"""
string1 = '''
edge [fontname="NSimSun"];
node [ fontname="NSimSun" size="15,15"];
{
''' 
string2 = '}'
"""with open("../tmp/tree.dot", 'w') as f:export_graphviz(dtc, feature_names = x.columns, out_file = f)f.close()from IPython.display import Image  
from sklearn import tree
import pydotplus dot_data = tree.export_graphviz(dtc, out_file=None,  #regr_1 是对应分类器feature_names=data.columns[:3],   #对应特征的名字class_names=data.columns[3],    #对应类别的名字filled=True, rounded=True,  special_characters=True)  
graph = pydotplus.graph_from_dot_data(dot_data)  
graph.write_png('../tmp/example.png')    #保存图像
Image(graph.create_png()) 

( 2 )Result

image-20240501190310990

5.1.5 人工神经网络

神经网络本人学习较多,所以此处不加以展开,这里用pytorch重构一下案例代码。

  • 本案例数据量太少只有34条,所以使用神经网络效果肯定是不好的,这边只是实现一下代码。
  • 书中给出的代码,直接在训练集上做测试,简直是不可理喻,但是此题数据量太少了,所以数据分割其实意义也不大,此处结果单纯做一个示范,不要较真。

1.Code

import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
import seaborn as sns# 参数初始化
inputfile = '../data/sales_data.xls'
data = pd.read_excel(inputfile, index_col='序号')  # 导入数据# 数据是类别标签,要将它转换为数据
# 用1来表示“好”“是”“高”这三个属性,用0来表示“坏”“否”“低”
data[data == '好'] = 1
data[data == '是'] = 1
data[data == '高'] = 1
data[data != 1] = 0# 分割数据
x_train_data = np.array(data.iloc[1:29, :3].values).astype(float)
y_train_data = np.array(data.iloc[1:29, 3].values).astype(float)
x_eval_data =  np.array(data.iloc[29:35, :3].values).astype(float)
y_eval_data =  np.array(data.iloc[29:35, 3].values).astype(float)x = torch.Tensor(x_train_data)
y = torch.Tensor(y_train_data)
x_eval = torch.Tensor(x_eval_data)
y_eval = torch.Tensor(y_eval_data)
# 创建TensorDatasets和DataLoader
dataset = TensorDataset(x, y)
dataloader = DataLoader(dataset, batch_size=10, shuffle=False)# 定义模型
class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.fc1 = nn.Linear(3, 10)self.fc2 = nn.Linear(10, 1)self.relu = nn.ReLU()self.sigmoid = nn.Sigmoid()def forward(self, x):x = self.relu(self.fc1(x))x = self.sigmoid(self.fc2(x))return xmodel = Net()# 损失函数和优化器
loss_fn = nn.BCELoss()optimizer = optim.Adam(model.parameters(),lr=0.01)# 训练模型
for epoch in range(1000):for inputs, labels in dataloader:optimizer.zero_grad()outputs = model(inputs)loss = loss_fn(outputs.squeeze(), labels)loss.backward()optimizer.step()# 预测
with torch.no_grad():predictions1 = model(x_eval).squeeze()predictions = (predictions1 >= 0.5).float()  # 将输出转换为0或1# 绘制混淆矩阵
def cm_plot(original, predictions):cm = confusion_matrix(original, predictions)sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')plt.xlabel('Predicted')plt.ylabel('True')plt.show()cm_plot(y_eval, predictions)

2.Result

Figure_1

数据量太少了,此处单纯用来练习可视化,测试数据太少不要较真。

5.1.6 分类与预测算法评价

分类与预测模型对训练集进行预测而得出的准确率并不能很好地反映预测模型未来的性能,为了有效判断一个预测模型的性能表现,需要一组没有参与预测模型建立的数据集,并在该数据集上评价预测模型的准确率,这组独立的数据集叫测试集。模型预测效果评价,通常用绝对误差与相对误差、平均绝对误差、根均方差、相对平方根误差等指标来衡量。

1. 绝对误差与相对误差

\(Y\)表示实际值,\(\hat{Y}\)表示预测值,则称\(E\) 为绝对误差(Absolute Error),计算公式如下:

\[E=Y-\hat{Y} \]

\(e\)为相对误差(Relative Error),计算公式如下:

\[e=\frac{Y-\hat{Y}}Y \]

有时相对误差也用百分数表示,如下式所示。

\[e=\frac{Y-\hat{Y}}Y\times100\% \]

这是一种直观的误差表示方法。

2.平均绝对误差

平均绝对误差( Mean Absolute Error, MAE),计算公式如下所示:

\[\mathrm{MAE}=\frac1n\sum_{i=1}^n\mid E_i\mid=\frac1n\sum_{i=1}^n\mid Y_i-\hat{Y_i}\mid \]

式中,\(\rm{MAE}\) 表示平均绝对误差,\(E_i\)表示第\(i\)个实际值与预测值的绝对误差,\(Y_{i}\)表示第\(i\)个实际值,\(\hat{Y}_i\)表示第\(i\)个预测值。由于预测误差有正有负,为了避免正负相抵消,故取误差的绝对值进行综合并取其平均数,这是误差分析的综合指标法之一。

3.均方误差

均方误差(Mean Squared Error, MSE),计算公式如下式所示:

\[\mathrm{MSE}=\frac1n\sum_{i=1}^nE_i^2=\frac1n\sum_{i=1}^n(Y_i-\hat{Y}_i)^2 \]

式中,\(\rm{MSE}\) 表示均方差。本方法用于还原平方失真程度。均方误差是预测误差平方之和的平均数,它避免了正负误差不能相加的问题。由于对误差\(E\)进行了平方,加强了数值大的误差在指标中的作用,从而提高了这个指标的灵敏性,是一大优点。均方误差是误差分析的综合指标法之一。

4.均方根误差

均方根误差(Root Mean Squared Error, RMSE)计算公式如下式所示。

\[\mathrm{RMSE}=\sqrt{\frac1n\sum_{i=1}^nE_i^2}=\sqrt{\frac1n\sum_{i=1}^n\left(Y_i-\hat{Y}_i\right)^2} \]

式中,\(\rm{RMSE}\) 表示均方根误差。这是均方误差的平方根,代表了预测值的离散程度,也叫标准误差,最佳拟合情况
\(\rm{RMSE}=0\)。均方根误差也是误差分析的综合指标之一。

5.平均绝对百分误差

平均绝对百分误差( Mean Absolute Percentage Error, MAPE)计算公式如下式所示。

\[\mathrm{MAPE}=\frac{1}{n}\sum_{i=1}^{n}\mid E_{i}\:/\:Y_{i}\mid=\frac{1}{n}\sum_{i=1}^{n}\mid(Y_{i}-\hat{Y}_{i})\:/\:Y_{i}\mid \]

式中,\(\rm{MAPE}\) 表示平均绝对百分误差。一般认为 MAPE 小于 10 时,预测精度较高。

6. Kappa 统计

image-20240501222749747

7. 识别准确度

image-20240501222817114 image-20240501222827639

8. 识别精确率

image-20240501222921016

9. 反馈率

image-20240501222942872

10. ROC 曲线

image-20240501223133656

11. 混淆矩阵

image-20240501223158052 image-20240501223329242

神经网络那个例子里的结果就是混淆矩阵,看一下就明白了。

5.1.7 Python 分类预测模型特点

image-20240501223556624

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/26661.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

红米note12t 小菜菜miui13体验

仅记录,以下用户均出自 酷安 @是小菜菜吖 的miui13 潘多拉0926,@落日的挽歌 的520 591两档降压,noactive

模拟集成电路设计系列博客——6.2.1 二进制权重电阻转换器

6.2.1 二进制权重电阻转换器 一种主流的实现D/A转换器的方式是将一组信号以二进制方式进行组合。这组二进制信号可以是电流(在电阻或者电流方式中),但二进制权重的电荷也经常使用。在这个章节中,将首先介绍店主方式,然后是和电荷重分布的模式和电流模式。在这个远离下并不…

力扣-430. 扁平化多级双向链表

1.题目 题目地址(430. 扁平化多级双向链表 - 力扣(LeetCode)) https://leetcode.cn/problems/flatten-a-multilevel-doubly-linked-list/ 题目描述 你会得到一个双链表,其中包含的节点有一个下一个指针、一个前一个指针和一个额外的 子指针 。这个子指针可能指向一个单独的双…

如何安全的使用密码登录账号(在不知道密码的情况下)

首先,需要用到的这个工具:度娘网盘 提取码:qwu2 蓝奏云 提取码:2r1z1、打开工具,进入账号密码模块,如图2、看到鼠标移动到密码那一栏有提示,按住Ctrl或者Alt点击或者双击就能复制内容,这方法虽然快,但还是能看到密码。3、先模拟一个账号,随意填写数据。保存它。之后左…

使用joinjs绘制流程图(七)-实战-绘制流程图+节点设置样式+节点添加事件

效果图原理 joinjs中通过svg来绘制流程图,然后我们可以使用localToClientRect这个方法对节点(element)复制,它会在原来的element在svg位置上生成一个html元素,但是这样会造成原来的element节点监听的点击事件无法触发,我们可以使用原生来操作对这个元素(比如样式的设置和…

webapi创建和调用WebService

首先需要引入soapcore包这个包提供了所需的类和soap终结点中间件。 引入这个这个包之后,我们需要定义提供的服务。 这里我写了一个用于查询省份面积的服务。省份信息服务 /// <summary> /// 省份信息服务接口 /// </summary> [ServiceContract] public interface …

Y2 知识和题单

Link。 0x01 进制 引入 计数原理,对于 \(N\) 进制,那么就是逢 \(N\) 进一。 计算机中常用二进制,对应电路中的通电(\(1\))断电(\(0\))。 人类从远古以来使用十进制。 常用的有二进制、三进制、八进制、十进制、十六进制等。 由于不同进制之间数值写法可能相同,在没有特…

m基于CCSDS标准的LDPC编码器的FPGA实现,包含testbench,码长1024,码率0.5

1.算法仿真效果 vivado2019.2仿真结果如下:2.算法涉及理论知识概要LDPC码是一种具有稀疏校验矩阵的线性分组码,由Robert G. Gallager在1962年首次提出。它利用图论中的 Tanner 图来表示其编解码结构,其中节点分为变量节点和校验节点。变量节点对应于消息比特,而校验节点则对…