一、概念
1、拓展线性模型
基本的线性模型虽简单,却有丰富的变化。我们将模型改写为
y = transfer(W)* X + b
尝试令模型逼近 y 的衍生物,比如ln(y):
ln(y)= transfer(W)* X + b
这就是广义线性模型中的泊松回归模型
2、广义线性模型
广义线性模型(generalize dlinear model)是线性模型的扩展,通过联结函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。其特点是不强行改变数据的自然度量,数据可以具有非线性和非恒定方差结构。
广义线性模型的核心体现在预测变量y服从指数族分布(包括高斯分布,伯努利分布,多项式分布,泊松分布,beta分布……)
以泊松回归模型为例:
ln(y)= transfer(W)* X + b
它可以变形为
y = etransfer(W)*X+b
它实际上是试图让etransfer(W)*X+b逼近y,形式上仍是线性回归,但实质上已是在求取输入空间到输出空间的非线性函数映射。
将它拓展到更一般的形式,令
这样得到的就是广义线性模型,其中 g(·)称为"联系函数"(link function)。
3、对数几率回归(逻辑回归)
对数几率回归(逻辑回归)是一种广义的线性回归,通过构造联系函数,利用机器学习来实现分类或者预测。
以二分类问题为例,解决该问题最理想的是单位阶跃函数
但是该函数不连续,所以需要找到一个函数一定程度上近似单位阶跃函数并且单调可微,对数几率函数(logistic function)正是这样一个常用替代函数——sigmoid函数。
代入Z=transfer(W)*X+b有
换个角度理解,把上面的公式表示为如下形式
ln()= transfer(W)* X + b
若将y视为样本x作为正例的可能性,则1-y是其反例的可能性,两者的比值称为“几率”,取对数则得到对数几率。这就是一个被logistic方程归一化后的线性回归,仅此而已。
二、逻辑回归的实现
用梯度下降法求解逻辑回归问题
# coding=utf-8
import numpy as np
import matplotlib.pyplot as plt
import math
from sklearn.datasets.samples_generator import make_classification
#========================================================
# 参数设置
#========================================================
# 学习率
learning_rate = 0.001
# 迭代次数
n_epochs = 200
# 设置阈值
epsilon = 1e-5
#========================================================
# 生成数据集
#========================================================
# 构造训练数据集
x0, labels = make_classification(n_samples=200,n_features=2,n_redundant=0,n_informative=2,
random_state=1,n_clusters_per_class=2)
X = np.insert(x0, 0, 1, axis=1) #特征数据集,添加1是构造常数项x0
y = labels.reshape(X.shape[0], 1)
#========================================================
# sigmoid函数
#========================================================
def sigmoid(z):
m = 1 / (1 + np.exp(-z))
return m
#========================================================
# 用批量梯度下降算法求解逻辑回归问题
#========================================================
def LogisticsRegression(X_train, y_train):
'''
逻辑回归算法的实现
INPUT -> 输入, 目标
'''
lr = learning_rate
# 初始化迭代次数
count = 0
# 初始化theta
theta = np.random.randn(X_train.shape[1], 1)
before_theta = np.zeros((X_train.shape[1], 1))
for epoch in range(n_epochs):
count += 1
error = sigmoid(np.dot(X_train, theta)) - y_train
gradient = np.dot(X_train.T, error)
# 参数更新
theta = theta - learning_rate * gradient
# theta-before_theta表示前后两个梯度的变化,当梯度变化很小(在接收的范围内)时,便停止迭代
if np.linalg.norm(theta - before_theta) < epsilon:
print(count)
break
else:
before_theta = theta
return theta
#========================================================
# 可视化函数图像
#========================================================
def plot_bestfit(weights):
'''
数据可视化并画出最佳划分线
'''
unique_lables = set(labels)
colors = plt.cm.Spectral(np.linspace(0, 1, len(unique_lables)))
for k, col in zip(unique_lables, colors):
x_k = x0[labels == k]
plt.plot(x_k[:,0], x_k[:,1], 'o', markerfacecolor=col, markeredgecolor="k", markersize=10)
y = (-weights[0, 0] - weights[1, 0] * x0) / weights[2, 0]
plt.plot(x0, y)
plt.xlabel('X1')
plt.ylabel('X2')
plt.show()
#========================================================
# 主程序
#========================================================
if __name__ == '__main__':
optimal = LogisticsRegression(X, y)
print(optimal)
plot_bestfit(optimal)
上述optimal就是所求的回归系数。w0 = -0.14621134, w1 = -0.12217623, w2=2.08536734
之前预测的直线方程0 = w0x0 + w1x1 + w2x2, 带入回归系数,可以确定边界。
x2 = (-w0 - w1*x1) / w2
网友评论