李航《统计学习方法》第二版 学习笔记
知识点
- 分类算法
- 属于线性模型
- 其图形是一条S型曲线,单调增,并且定义域是(−∞ ,+∞ ),值域是(0,1)
- logistics回归比较两个条件概率值的大小,将X分到概率值较大的那一类
- 公式:
- 式1:
- 式2:
- 式1:
- 用线性回归模型的预测结果去逼近真实标记的对数几率
- logistics的特点:在logistics回归模型中,输入Y=1的对数几率是输入x的线性函数
,所以logistic函数又叫对数几率函数
- 采用梯度下降法对w,b进行更新
一些公式:该部分来源:理解 logistic 回归 - 知乎、logistic回归原理与实现 - 知乎
python代码实现
利用python实现二元逻辑回归,没有加正则项。挑选iris数据前100个样本作为训练集
'''导入包'''
from sklearn.datasets import load_iris
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
'''数据准备'''
# 鸢尾花数据集
iris = load_iris()
data = pd.DataFrame(iris.data, columns=iris.feature_names)
X = np.array(data.iloc[:100, [0, 1]])
y = iris.target[:100]
y = np.array(y)
y = y.reshape(len(y),1)
# print(X.shape)输出(100, 2)
# print(y.shape)输出(100, 1)
# 数据集可视化
plt.scatter(X[0:50, 0], X[0:50, 1], c="red", marker="x")
plt.scatter(X[50:100, 0], X[50:100, 1], c="green")
plt.show()
'''参数初始化'''
w = tf.Variable(tf.cast(np.random.randn(2,1)*0.001,tf.float32),name="weight")
b = tf.Variable(tf.cast(np.random.randn(1),tf.float32),name="bias")
learning_rate =0.3
step = 10000
'''定义sigmoid函数'''
def sigmoid_func(z):
a = 1/(1+tf.exp(-z))
return a
'''定义逻辑方程'''
def y_func(x):
# print(x.shape)输出(100, 2)
# print(w.shape)输出(2, 1)
z = x@w+b
a = sigmoid_func(z)
return a
'''定义损失函数'''
def loss_func(y_pred,y_true):
term1 = -y_true*tf.math.log(y_pred)
term2 = -(1-y_true)*tf.math.log(1-y_pred)
loss = term1+term2
loss = tf.reduce_mean(loss)
return loss
'''模型训练'''
optimizer = tf.optimizers.SGD(learning_rate)
def train(x,y_true):
with tf.GradientTape() as g:
y_pred = y_func(x)
loss = loss_func(y_pred,y_true)
gradients = g.gradient(loss, [w, b])
optimizer.apply_gradients(zip(gradients,[w,b]))
'''模型运行'''
all_loss = []
all_step = []
for i in range(step):
train(X,y)
if i%50==0:
y_pred = y_func(X)
loss = loss_func(y_pred,y)
all_loss.append(loss)
all_step.append(i)
print("step:%i,loss:%f,w:%f,b:%f"%(i,loss,w.numpy()[0], b.numpy()))
'''可视化损失'''
plt.plot(all_step, all_loss)
plt.show()
'''可视化分类结果'''
print("w:",w.numpy())
print("b:",b.numpy())
x1 = np.arange(4, 7.5,0.5)
x2 = -(w[0] * x1 + b) / w[1]
plt.plot(x1, x2)
plt.scatter(X[0:50, 0], X[0:50, 1], c="red", marker="x")
plt.scatter(X[50:100, 0], X[50:100, 1], c="green")
plt.xlabel('feature1')
plt.ylabel('feature2')
plt.show()
输出的损失图形如下:
输出的W和b结果如下:
w: [[ 7.5633535] [-10.776955 ]] b: [-7.6320033]
输出的分类结果如下: