import numpy as np
import matplotlib.pyplot as plt
import csv
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
from tqdm import tqdm
sc = MinMaxScaler()
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def forward_propagation(w, b, x_train, y_train):
'''
逻辑回归:y = w.T * x + b
逻辑回归概率分布:f(x|p) = {p^x(1-p)^(1-x), x=0,1}
在训练过程中要理解,y_train的可能值为0或1,对应上述式子的x,
p为发生的概率,是由y激活后计算出来的,h(y) = sigmoid(calc_y)
则f(x|p) = f(y_train|h(y)) = {h(y)^y_train * (1-h(y))^(1-y_train)
损失函数 L 是对似然函数做对数 L = lnf = -(y_train*ln(h(y)) + (1-y_train)*ln(1-h(y)))
:param w: y = wx + b, D(dimension) = n * 1
:param b: 初始b
:param x_train: D = m(数据量) * n(维度)
:param y_train: D = m * 1
:return:
'''
y = np.dot(w.T, x_train.T) + b
active_y = sigmoid(y)
loss = -y_train * np.log(active_y) - (1 - y_train) * np.log(1 - active_y)
coss = np.sum(loss) / x_train.shape[0]
return coss
def backward_forward_propagation(w, b, x_train, y_train):
'''
backward propagation
对于前向传播的理论对数似然函数L,做微分
dL/dw = - 1/m * [y_train * (h'(y)/h(y)) + (1-y_train) * (-h'(y)/(1-h(y)))].T * x_train
= 1/m * (h(y) - y_train).T * x_train
dL/db = 1/m * sum((h(y) - y_train))
:return:
'''
# forward pro
y = np.dot(x_train, w) + b
active_y = sigmoid(y) # probabilistic 0-1
loss = -y_train * np.log(active_y) - (1 - y_train) * np.log(1 - active_y)
cost = np.sum(loss) / x_train.shape[0]
# backward pro
d_w = 1 / x_train.shape[0] * np.dot((active_y - y_train).T, x_train)
d_w = d_w.reshape([d_w.shape[1], d_w.shape[0]])
d_b = 1 / x_train.shape[0] * np.sum((active_y - y_train))
gradients = {"d_w": d_w, "d_b": d_b}
return cost, gradients
def updata(w, b, x_train, y_train, learning_rate, iter_num):
cost_list = []
cost_list_ = []
index = []
for i in tqdm(range(iter_num)):
cost, gradients = backward_forward_propagation(w, b, x_train, y_train)
cost_list.append(cost)
w = w - learning_rate * gradients['d_w']
b = b - learning_rate * gradients['d_b']
if i % 100 == 0:
cost_list_.append(cost)
index.append(i)
print("Cost after iteration %i: %f" % (i, cost))
parameters = {'weight': w, 'bias': b}
plt.plot(index, cost_list_)
plt.xticks(index, rotation='vertical')
return parameters, gradients, cost_list
def predict(w, b, x_test):
y = np.dot(x_test, w) + b
active_y = sigmoid(y)
pred_y = np.zeros_like(active_y)
for i in range(pred_y.shape[0]):
if active_y[i, 0] > 0.5:
pred_y[i, 0] = 1
else:
pred_y[i, 0] = 0
return pred_y
def logistic_regression(x_train, y_train, x_test, y_test, learning_rate, iter_num):
init_w = np.ones([x_train.shape[1], 1]) * 0.01
init_b = 0.01
para, grad, cost_list = updata(init_w, init_b, x_train, y_train, learning_rate, iter_num)
y_train_pred = predict(para['weight'], para['bias'], x_train)
y_test_pred = predict(para['weight'], para['bias'], x_test)
# Print train/test Errors
print("train accuracy: {} %".format(100 - np.mean(np.abs(y_train_pred - y_train)) * 100))
print("test accuracy: {} %".format(100 - np.mean(np.abs(y_test_pred - y_test)) * 100))
train = pd.read_csv(r"E:Digit Recognizertrain.csv")
logic_0 = train[train['label'] == 0]
logic_1 = train[train['label'] == 1]
logic_train = np.concatenate((logic_0, logic_1))
logic_train = sc.fit_transform(logic_train)
logic_train_x = logic_train[:, 1:]
logic_train_y = logic_train[:, 0]
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(logic_train_x, logic_train_y,
test_size=0.2,
random_state=0,
)
logistic_regression(X_train, y_train.reshape([len(y_train), 1]), X_test, y_test.reshape([len(y_test), 1]), 0.01, 1000)
plt.show()
源代码:kaggle 基于python逻辑回归
数据:kaggle 比赛的数据



