机器学习之回归算法(线性回归推导和实战)

1、主要回归算法

  • 线性回归
  • Logistic回归
  • Softmax回归
  • 梯度下降
  • 特征抽取
  • 线性回归案例
    在这里插入图片描述

2、什么是回归算法

在这里插入图片描述

3、线性回归推导

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
参考
在这里插入图片描述
其中n为特征值的个数
误差
众所周知,当我们吧数据进行拟合后,不可能所有的数据均落在拟合线或者拟合平面内,因此拟合值跟实际值之间肯定会产生一个误差(我们用ε来表示误差),因此对于每个样本点来说:
在这里插入图片描述
一般来说误差具有独立同分布的特点,并且符合正态分布,其均值为0,方差为θ的平方:

在这里插入图片描述
由于误差服从正态分布:
在这里插入图片描述
我们将误差函数与正态分布的公式组合(其中μ为0 ):
在这里插入图片描述
将误差公式代入上述式子中:
在这里插入图片描述
在这里我们引入似然函数,似然函数在统计学中扮演着重要的角色,我们可以简单理解为什么样的参数跟我们的数据组合后恰好是真实值:
在这里插入图片描述
因为这个函数是一个累乘的式子,为了方便计算,我们将其取对数,将乘法变成加法,即为对数似然:
在这里插入图片描述
将式子展开化简:
在这里插入图片描述
根据概率和统计中所学的知识,我们知道,对同一个似然函数,如果存在一个参数值,使得它的函数值达到最大的话,那么这个值就是最为“合理”的参数值。 化简后减数和被减数均为正数,要使函数获得最大值,那么我们就要使减数越小越好:
在这里插入图片描述
此时我们要求的就是J(θ)的极小值:

在这里插入图片描述
因为这个函数本质上来说是一个面,因此它的极值一般会出现在偏导为0的地方,于是我们对J(θ)分别对x和y求偏导:
在这里插入图片描述
如果偏导为0,则:
在这里插入图片描述
评估方法
我们最常用的评估方法为:
在这里插入图片描述
其取值越接近于1,我们认为模型的拟合程度越好。

先用最大似然函数求出目标函数,然后利用对目标函数利用最小二乘法求出参数

4、案例1:预测家庭用电(时间和电压的关系)

数据集介绍:
在这里插入图片描述

思路:
将时间划分为6个特征X,预测电压Y,设置回归函数为:在这里插入图片描述
目标:求参数θ

导包

#导包
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd
import time

import sklearn
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression   #底层为最小二乘的线性包
from sklearn.preprocessing import StandardScaler   # 标准化
from sklearn.metrics import mean_absolute_error,r2_score  #评估标准

加载数据

# 加载数据
path='C:/Users/hubert/Desktop/Python零基础人工智能就业25G视频教程/5、机器学习/data/household_power_consumption_1000.txt' ## 1000行数据

'''
pandas读取csv文件默认是按块读取的,即不一次性全部读取;
另外pandas对数据的类型是完全靠猜的,所以pandas每读取一块数据就对csv字段的数据类型进行猜一次,
所以有可能pandas在读取不同块时对同一字段的数据类型猜测结果不一致。
low_memory=False 参数设置后,pandas会一次性读取csv中的所有数据,
然后对字段的数据类型进行唯一的一次猜测。这样就不会导致同一字段的Mixed types问题了。
'''
df = pd.read_csv(path, sep=';', low_memory=False)   #当文件中的数据类型为单一类型时,low_memory能提高效率

# 异常数据处理(异常数据过滤)
new_df = df.replace('?', np.nan)    #用nan替换 有问题的数据,方便进行dropna操作
datas = new_df.dropna(axis=0,how = 'any') # any只要该行有数据为nan,就进行删除操作;all是全为nan时才删除行

展示

display(datas.head(5))
display(datas.info())

在这里插入图片描述
提取特征数据X和目标值Y

# 提取特征数据
## 创建一个时间字符串格式化字符串
def date_format(dt):
    #dt在这里是一行,是Series类型,这一行有两个数据
    #接下来要把这两个数据拼成字符串,再提取其中的‘年月日时分秒’
    import time
    t = time.strptime(' '.join(dt), '%d/%m/%Y %H:%M:%S')  #函数根据指定的格式把一个时间字符串解析为时间元组。
    return pd.Series([t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec])

## 时间和电压之间的关系(Linear)
# 获取x和y变量, 并将时间转换为数值型连续变量
X = datas.iloc[:,0:2]  # 选取datas中前三列
X = X.apply(date_format, axis=1)   #1代表按行,默认的是0代表列
Y = datas['Voltage']
display(X.head(2))
display(Y.head(2))
display(X.describe())

在这里插入图片描述
划分训练集和测试集,并模型建立

# 划分数据集,标准化,模型训练,并使用模型预测
# 对数据集进行测试集和训练集划分
X_train,X_test,Y_train,Y_test = train_test_split(X, Y, test_size=0.2, random_state=0)  # 训练集80%

# 数据标准化,必须先fit_transform(X_train),然后transform(X_test),保证归一化标准一样
# fit,训练模型,没有返回值
#transform,对数据进行转化
#fit_transform,先训练,再转换
ss = StandardScaler()
X_train = ss.fit_transform(X_train) # 对训练集进行训练并标准化
X_test = ss.transform(X_test) #在训练集的fit标准下,用X_test进行的标准化模型训练,用训练好的模型,再对X_test进行转换

# 模型训练
lr = LinearRegression()
lr.fit(X_train, Y_train) ## 训练模型

# 模型校验
y_pred = lr.predict(X_test) ## 预测结果

评估

# 模型效果(R^2)
#第一种方式,用lr.score
print("训练集R^2:",lr.score(X_train, Y_train))  #测训练集准确率
print("测试集R^2:",lr.score(X_test, Y_test))  #测试集准确率
#第二种方式,用metrics里的r2_score
print('测试集R^2:',r2_score(Y_test,y_pred))

#测试集均方误差MAE
print('测试集均方误差:',mean_absolute_error(Y_test,y_pred))

#测试集平均方差MSE和RMSE
MSE=np.average((y_pred-Y_test)**2)
RMSE=np.sqrt(MSE)
print("MSE:",MSE)
print("RMSE:",RMSE)

在这里插入图片描述
可视化

## 设置字符集,防止中文乱码
mpl.rcParams['font.sans-serif']=[u'simHei']
mpl.rcParams['axes.unicode_minus']=False

## 预测值和实际值画图比较
t=np.arange(len(X_test))    #用测试集数据量200作为横轴
plt.figure(facecolor='w')  # 背景颜色白色
plt.plot(t, Y_test, 'r-', linewidth=2, label=u'真实值')
plt.plot(t, y_pred, 'b-', linewidth=2, label=u'预测值')
plt.legend(loc = 'lower right')
plt.title(u"线性回归预测时间和功率之间的关系", fontsize=20)
plt.grid(b=True)#网格
plt.show()

在这里插入图片描述
打印函数

#打印参数y=239.92665+0*x1+0*x2+3.97781449*x3+0.87333465*x4+0.17064799*x5+0*x6
print(lr.coef_) #打印参数项
print(lr.intercept_) #打印截距项

在这里插入图片描述

5、案例5:预测家庭用电(电流和功率的关系)

不利用线性回归模块,直接用上面推导的在这里插入图片描述
求出每个特征的参数,特征X为功率两个,电压Y为一个,该方法没有考虑截距,得到y=θ1*x+θ2*x

导包读数据

#导包
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd
import time

import sklearn
from sklearn.model_selection import train_test_split

## 设置字符集,防止中文乱码
mpl.rcParams['font.sans-serif']=[u'simHei']
mpl.rcParams['axes.unicode_minus']=False

# 加载数据
path='C:/Users/hubert/Desktop/Python零基础人工智能就业25G视频教程/5、机器学习/data/household_power_consumption_1000.txt' ## 1000行数据
df = pd.read_csv(path, sep=';', low_memory=False)   #当文件中的数据类型为单一类型时,low_memory能提高效率

df.head(2)

在这里插入图片描述
提取特征数据和目标数据,划分训练测试

## 功率和电流的关系
X=df.iloc[:,2:4]
Y=df.iloc[:,5]
display(X.head(2))
display(Y.head(2))

在这里插入图片描述

# 对数据集进行测试集和训练集划分
X_train,X_test,Y_train,Y_test = train_test_split(X, Y, test_size=0.2, random_state=0)  # 训练集80%

最小二乘法需要是矩阵,但是dataframe不是矩阵

# 最小二乘法需要是矩阵,但是dataframe不是矩阵
display(type(X_train))
display(X_train.head(3))
display(Y_train.head(3))

在这里插入图片描述
转换成矩阵

# 将X和Y转换成矩阵
X_train1=np.mat(X_train)  # X_train1:800*2
display(type(X_train1))

Y_train1=np.mat(Y_train)  # Y_train1:800*1
display(type(Y_train1))

# X*Y,需要维数对应,所以把Y转置
Y_train1=Y_train1.reshape(-1,1)

在这里插入图片描述
计算 θ = ( X T X ) − 1 ( X T X ) θ=(X^TX)^{-1}(X^TX) θ=(XTX)1(XTX)

Theta=(X_train1.T*X_train1).I*X_train1.T*Y_train1
print(Theta)

在这里插入图片描述
对测试集进行预测y=Theta*x

# 对测试集进行预测y=Theta*x
X_test1=np.mat(X_test)
y_pre = X_test1*Theta

可视化

# 可视化
t=np.arange(len(X_test1))    #用测试集数据量200作为横轴
plt.figure(facecolor='w')  # 背景颜色白色
plt.plot(t, Y_test, 'r-', linewidth=2, label=u'真实值')
plt.plot(t, y_pre, 'b-', linewidth=2, label=u'预测值')
plt.legend(loc = 'lower right')
plt.title(u"线性回归预测功率和电流之间的关系", fontsize=20)
plt.grid(b=True)#网格
plt.show()

在这里插入图片描述

6、模型保存

import sklearn
from sklearn.linear_model import LinearRegression   
from sklearn.preprocessing import StandardScaler   # 标准化

ss = StandardScaler()
lr = LinearRegression()

# 模型保持/持久化
# 在机器学习部署的时候,实际上其中一种方式就是将模型进行输出;
# 另一种方式就是直接将预测结果进行输出。
# 模型输出一般是将模型直接输出到磁盘文件。
from sklearn.externals import joblib

# 保存文件要求指定的文件夹存在,默认是当前路径
joblib.dump(ss,'data_ss.model')  # 保存标准化模型
joblib.dump(lr,'data_lr.model')  # 保存线性模型

在这里插入图片描述

# 加载模型
ss1 = joblib.load('data_ss.model')  # 加载模型
lr1 = joblib.load('data_lr.model')

# 用模型进行预测
data1=[[2006,12,17,12,25,0]]
data2=[[2006,12,1,17,24,0]]
data11=[234.84]
data22=[233.63]

data1=ss1.fit_transform(data1)
data2=ss1.transform(data2)

lr1.fit(data1, data11) ## 训练模型

y_pred = lr1.predict(data2) ## 预测结果

print([data22,y_pred])

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
逻辑回归是一种用于二分类问题的机器学习算法,它通过建立一个逻辑回归模型来预测样本的类别概率。在推导逻辑回归算法的数学原理时,我们将使用最大似然估计的方法。 假设我们有一个训练数据集,包含n个样本点。每个样本点由输入向量x和对应的类别标签y组成,其中x ∈ R^d,y ∈ {0, 1}。 逻辑回归的目标是建立一个模型,能够根据输入向量x预测出样本属于类别1的概率P(y=1|x)。 为了建立逻辑回归模型,我们使用逻辑函数(或称为sigmoid函数)将线性模型的输出转化为概率值。逻辑函数的形式为: g(z) = 1 / (1 + e^(-z)) 其中,z是线性模型的输出。在逻辑回归中,我们假设线性模型可以表示为: z = w^Tx + b 其中,w是权重向量,b是偏置项。 根据最大似然估计的思想,我们希望找到一组最优的参数w和b,使得在给定训练数据集下,模型对每个样本属于类别1的概率P(y=1|x)尽可能接近其真实标签y。 假设训练数据集中的样本是独立同分布的,我们可以构造似然函数来描述模型的拟合度。对于一个样本点(x, y),似然函数可以表示为: L(w, b) = P(y=1|x)^y * P(y=0|x)^(1-y) 为了简化计算,我们可以将似然函数取对数,得到对数似然函数: l(w, b) = log(L(w, b)) = y * log(P(y=1|x)) + (1-y) * log(P(y=0|x)) 我们的目标是最大化对数似然函数。为了实现这个目标,我们可以通过最小化负对数似然函数来转化为一个优化问题: minimize: -l(w, b) 接下来,我们可以使用梯度下降等优化算法来求解上述优化问题。通过计算负对数似然函数的梯度,并不断更新参数w和b,直到收敛为止。 具体地,我们可以计算负对数似然函数关于参数w和b的偏导数,并进行参数更新。更新规则可以表示为: w := w - α * ∂l/∂w b := b - α * ∂l/∂b 其中,α是学习率,控制参数更新的步长。 通过迭代执行上述更新步骤,我们可以逐渐优化参数w和b,找到最大似然估计下的最优解。 总结起来,逻辑回归算法的数学原理是通过最大似然估计的方法,构建逻辑回归模型,将线性模型的输出通过逻辑函数转化为概率值。通过最小化负对数似然函数,使用梯度下降等优化算法来求解模型的参数。最终,我们可以根据模型的参数来预测样本属于类别1的概率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值