使用逻辑回归
导入库,因为这次的数据是mat文件,需要使用scipy库中的loadmat进行读取数据。
通过对数据类型的分析,发现是字典类型,查看该字典的键,可以发现又X,y等关键字。
import numpy as np
import matplotlib.pyplot as plt
import scipy.io as sio
#读取数据
path = "./ex3data1.mat"
data = sio.loadmat(path)
X = data.get("X")
Y = data.get("y")
这个问题可以看出是逻辑回归问题,只不过是一对多的问题,代价函数都是一样的。
def cost_func(theta,X,Y,lamda):
z = X @ theta
A = 1/(1+np.exp(-z))
m = len(X)
cost = -(np.sum(Y*np.log(A)+(1-Y)*np.log(1-A)))/m
reg = np.sum(np.power(theta[1:],2))*(lamda/(2*m))
return cost+reg
梯度下降,其实只是梯度项,方便后面调用minimize优化
def gradient_descent(theta,X,Y,lamda):
m = len(X)
z = X @ theta
A = 1 / (1 + np.exp(-z))
reg = theta[1:] * (lamda / m)
reg = np.insert(reg, 0, values=0, axis=0)
first = (X.T@(A - Y)) / m
return first+reg
新添入X0=1
X = np.insert(X,0,values=1,axis=1)
Y = Y.flatten()
对于一对多的问题,需要建立多个逻辑回归,在这道问题中,共有十个分类,则需要建立十个逻辑回归。使用for循环,每次迭代都得到一个theta向量。
from scipy.optimize import minimize
def one_vs_all(X,Y,lamda,k):
n = X.shape[1]
theta_all = np.zeros((k,n))
for i in range(1,k+1):
theta_i = np.zeros(n,)
res = minimize(fun=cost_func,
x0=theta_i,
args=(X,Y==i,lamda),
method='TNC',
jac=gradient_descent)
theta_all[i-1,:] = res.x
return theta_all
先初始化lamda和k
写出预测函数,一对多的预测就是计算出假设函数。假设函数输出的是概率,选取概率最大的对应的下标。
最后计算一下预测的准确率。
lamda = 1
K = 10
theta_final = one_vs_all(X,Y,lamda,K)
print(theta_final)
def predict(X,theta_final):
z = X @ theta_final.T
h = 1/(1+np.exp(-z))
h_argmax = np.argmax(h,axis=1)
return h_argmax+1
y_pred = predict(X, theta_final)
acc = np.mean(y_pred == Y)
# 0.9446
print(acc)
使用神经网络
导入库,因为这次的数据是mat文件,需要使用scipy库中的loadmat进行读取数据。
通过对数据类型的分析,发现是字典类型,查看该字典的键,可以发现又X,y等关键字。
同时,导入参数文件
import numpy as np
import scipy.io as sio
#读取数据
path = "./ex3data1.mat"
data = sio.loadmat(path)
X = data.get("X")
Y = data.get("y")
X = np.insert(X,0,values=1,axis=1)
Y = Y.flatten()
#读取权重
path_weights = "./ex3weights.mat"
theta = sio.loadmat(path_weights)
# print(theta)
# print(type(theta))
theta1 = theta.get("Theta1")
theta2 = theta.get("Theta2")
# print(theta1.shape)
# print(theta2.shape)
前向传播
z2 = X@theta1.T
a2 = 1/(1+np.exp(-z2))
a2 = np.insert(a2,0,values=1,axis=1)
z3 = a2@theta2.T
h = 1/(1+np.exp(-z3))
# print(h)
# print(h.shape)
预测
一对多的预测就是计算出假设函数。假设函数输出的是概率,选取概率最大的对应的下标。
最后计算一下预测的准确率。
h_argmax = np.argmax(h,axis=1)
h_argmax = h_argmax+1
acc = np.mean(h_argmax==Y)
print(acc)