加载库, 数据读取。正类样本:(x_1, y_1),负类样本:(x_0, y_0),标签:label。
import numpy as np
import math
import matplotlib.pyplot as plt
filename = r"C:\Users\samsara\Desktop\LR.txt"
fr = open(filename)
#读取数据
data, label = [], []
for line in fr.readlines():
lineArr = line.strip().split()
data.append([1.0, float(lineArr[0]), float(lineArr[1])])
label.append(int(lineArr[2]))
x_0, x_1, y_0, y_1 = [], [], [], []
for i in range(len(data)):
if label[i] == 0:
x_0.append(data[i][1])
y_0.append(data[i][2])
else:
x_1.append(data[i][1])
y_1.append(data[i][2])
上方代码中data存储的数据维度为100*3,data[0]为常数项,data[1]为x,data[2]为y(也可以理解为x1,x2, 二维数据,两个特征),data= [1,X,Y]。 weights为权值,所以权值初始化为[1,1,1](也可以是随机数)。接着就是梯度下降法更新权值:
weights = weights - alpha * dataMatrix.T * L
L为所有数据与权值作内积(wT * X)再经过sigmoid函数(sigmoid(wT * X)),再减去真实值也就是标签:(Label - sigmoid(wT * X)),也就是残差,再与数据作内积:XT * (Label - sigmoid(wT * X))。在实际公式推导中,权重的更新公式为:右侧括号内为:(样本为正的概率 - 标签)。
#梯度下降法
def gardDescent(data,label):
dataMatrix = np.mat(data) #100*3
labelMatrix = np.mat(label).T
m,n = np.shape(dataMatrix)
alpha = 0.01 # 迭代步长
iteration = 5000 # 迭代次数
weights = np.ones((n,1)) #3*1
for k in range(iteration):
h = dataMatrix * weights # 100*3 * 3*1 = 100*1
for i in range(len(h)):
h[i] = Sigmoid(h[i])
L = (h - labelMatrix) #100*1
weights = weights - alpha * dataMatrix.T * L # 3*1 - 3*100 * 100*1
return weights
#sigmoid函数
def Sigmoid(x):
return (1.0/(1+math.exp(-x)))
可视化:
weights = gardDescent(data, label)
w = []
for i in range(len(weights)):
w.append(float(weights[i]))
w = np.array(w)
fig = plt.figure(figsize=(14,6))
ax = fig.add_subplot(111)#1行1列
ax.scatter(x_0,y_0,s=30,c='red',marker='s')
ax.scatter(x_1,y_1,s=30,c='blue',)
x_new = np.arange(-3.0,3.0,0.1)
y_new = (-w[0]-w[1]*x_new)/(w[2])
ax.plot(x_new, y_new, 'k--',color = 'black', linewidth=2)
plt.xlabel('Logistics Regression GradDescent')
参考: