代码不包括画图部分
逻辑回归
import numpy as np
import matplotlib.pylab as plt
import scipy.io as sio
import math
import scipy.optimize as op
# 逻辑回归
# 分类(识别)手写数字图片
def sigmoid(z):
return 1/(1+np.exp(-z))
def costFunction(theta, x, y, lam):
m = np.size(y)
h = sigmoid(x@theta)
if np.sum(1-h < 1e-10) != 0:
return np.inf
first = (-y@np.log(h) - (1-y)@np.log(1-h)) /m
second = lam/2/m * theta[1:]@theta[1:]
# theta_0不需要正则化
return first + second
def gradFunction(theta, x, y, lam):
m = np.size(y)
h = sigmoid(x@theta)
grad = x.T@(h - y)/m
grad[1:] += lam/m * theta[1:]
# theta_0不需要正则化
return grad
def OneVsAll(x, y, class_num, lam):
m, n = np.shape(x)
theta = np.zeros((class_num, n+1))
# n为特征数,+1是theta_0
x = np.column_stack((np.ones(m), x))
for i in range(class_num):
num = 10 if i == 0 else i #如果i==0那么num=10,否则num=i
p = (y == num) *1
# 计算每个class时,将训练集的分类结果设置为0和1,对应的class为1,其他为0
# (y == num)向量的元素是True和False,1*转换为数字
init_theta = np.zeros(n+1)
result = op.minimize(costFunction, init_theta, args=(x,p,lam), \
method='BFGS', jac=gradFunction, options={'maxiter': 200})
# maxiter为迭代次数
theta[i, :] = result.x
return theta
# np.set_printoptions(threshold=np.inf) # print()可以显示所有数据
data = sio.loadmat('ex3data1.mat')
# data包含两个矩阵X和y,X有5000行400列,y为5000行向量;
# X有5000个实例,每个实例是20*20像素的灰度图像,即每行都是一个手写数字图片;
# y是对应实例的对应数字1-10(10代表手写图片0)
X = data['X']
Y = data['y'][:, 0] # [:, 0]才能变成向量
# print(Y.shape)
# print(Y)
class_num = 10 # 0-9
lamb = 0.1
theta = OneVsAll(X, Y, class_num, lamb)
# 预测值函数
def predictOneVsAll(theta, x):
m = np.size(x, 0)
x = np.column_stack((np.ones(m), x))
p = np.argmax(x@(theta.T), axis=1)
# np.argmax求最大值的索引值,axis=0求列最大值,axis=1求行最大值
# p为每个实例最大可能的分类,组成的向量
# sigmoid(z)为增函数,比较z的大小即可
return p
pred = predictOneVsAll(theta, X)
print('Training Set Accuracy: ', np.sum(pred == (Y % 10))/np.size(Y))
神经网络
import numpy as np
import matplotlib.pylab as plt
import scipy.io as sio
import math
import scipy.optimize as op
# 神经网络
# 分类(识别)手写数字图片
# 正向传播,已知权值
def sigmoid(z):
return 1/(1+np.exp(-z))
np.set_printoptions(threshold=np.inf) # print()可以显示所有数据
data = sio.loadmat('ex3data1.mat')
# data包含两个矩阵X和y,X有5000行400列,y为5000行向量;
# X有5000个实例,每个实例是20*20像素的灰度图像,即每行都是一个手写数字图片;
# y是对应实例的对应数字1-10(10代表手写图片0)
X = data['X']
Y = data['y'][:, 0] # [:, 0]才能变成向量
data = sio.loadmat('ex3weights.mat')
# print(data)
theta1 = data['Theta1']
theta2 = data['Theta2']
m = np.size(Y)
X = np.column_stack((np.ones(m), X))
z2 = X@(theta1.T)
a2 = sigmoid(z2)
a2 = np.column_stack((np.ones(m), a2))
z3 = a2@(theta2.T)
a3 = sigmoid(z3)
pred = np.argmax(a3, axis=1)+1 #直接比较z3也可以
# 这个训练的theta权值有点坑,是按照1-10的结果去训练的,即a3中10列的概率值对应是1234567890,所以索引要+1
print('Training Set Accuracy: ', np.sum(pred == Y)/np.size(Y))