导入库
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import loadmat
import scipy.optimize as opt
from sklearn.metrics import classification_report
函数:Sigmoid函数
def sigmoid(z): #Sigmoid函数
return 1/(1+np.exp(-z))
函数:计算正则化的代价函数J(theta)
def computeRegCost(theta,X,y,lambada): #计算正则化的代价函数J(theta)
theta=np.matrix(theta)
X=np.matrix(X)
y=np.matrix(y)
first=np.multiply(-y,np.log(sigmoid(X*theta.T)))
second=np.multiply((1-y),np.log(1-sigmoid(X*theta.T)))
reg=(lambada/(2*len(X)))*np.sum(np.power(theta[:,1:theta.shape[1]],2)) #matrix[:,1:matrix.shape[1]]:取矩阵的第一列直到最后一列(左闭右闭)
return np.sum(first-second)/len(X)+reg
函数:计算正则化的梯度grad
def computeRegGradient(theta,X,y,lambada): #计算正则化的梯度grad
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
parameters=int(theta.ravel().shape[1])
grad = np.zeros(parameters)
error=(sigmoid(X*theta.T))-y
for i in range(parameters):
term=np.multiply(error,X[:,i])
if (i==0): #theta_0的梯度单独更新
grad[i]=np.sum(term)/len(X)
else:
grad[i]=np.sum(term)/len(X)+(lambada/len(X))*theta[:,i]
return grad
函数:一对多分类器
def one_vs_all(X,y,num_labels,lambada): #一对多分类器
rows=X.shape[0]
parameters=X.shape[1]+1
all_theta=np.zeros((num_labels,parameters)) #num_labels=10,10个分类器各自有all_theta的一行
X=np.insert(X,0,values=np.ones(rows),axis=1)
#a=np.insert(arr,obj,values= ,axis= ): arr:原始数组;obj:插入元素位置;values:插入内容;axis=0按行插入,axis=1按列插入
#np.ones:用法同np.zeros
for i in range(1,num_labels+1):
theta=np.zeros(parameters)
y_i=np.array([1 if label==i else 0 for label in y]) #对每个分类器,遍历y,将y从类标签转换为每个分类器的二进制值(是类i/不是类i)并将这些二进制值存储在y_i中
y_i=np.reshape(y_i,(rows,1)) #相当于将y_i转置
fmin=opt.fmin_tnc(func=computeRegCost,x0=theta,fprime=computeRegGradient,args=(X,y_i,lambada))
all_theta[i-1,:]=fmin[0]
return all_theta
函数:预测函数
def predict_all(X,all_theta): #预测函数
rows=X.shape[0]
X=np.insert(X,0,values=np.ones(rows),axis=1)
X=np.matrix(X)
all_theta=np.matrix(all_theta)
h=sigmoid(X*all_theta.T)
#X(5000*400),all_theta(10*400)--X*all_theta.T(5000*10)--h(5000*10):h[i,j]表示X中的第i个数据为第j类(数字j)的概率
# 取二维数组和矩阵中的数字
#data = np.array([[1, 2, 3], [4, 5, 6]]);print(data[0][1])
#data = np.matrix(data);print(data[0, 1])
h_argmax=np.argmax(h,axis=1)
#np.argmax(array([ ])):取出array中元素最大值对应的索引(默认从0开始)
#np.argmax(array([[ ],[ ]]),axis= ): axis=1:按行方向取出array中元素最大值对应的索引;axis=0:按列方向
h_argmax=h_argmax+1 #这里得到的h_argmax即为y_pred:分类器返回的预测值
return h_argmax
主函数:
#Logistic Regression in multi-class classification problem:One_vs_All Classifier
#使用一对一全分类方法,有k个不同类的标签就有k个分类器,每个分类器在"类别i"和"不是i"之间决定
#我们把分类器训练包含在一个函数中,该函数计算10个分类器中的每个分类器的最终权重
data=loadmat('ex3data1.mat') #用Python读取MATLAB格式的.m文件
#data['X'].shape=(5000, 400),data['y'].shape=(5000, 1):5000个数据,每个数据有400个像素,每个像素都是影响该数据为某个数字的因素
#随机展示100个数据
sample_index=np.random.choice(np.arange(data['X'].shape[0]),100)
#np.random.choice(a,size=None,replace=True,p=None):从一维数据a中随机抽取数字,返回指定size的数组
#replace:True表示可以取相同数字,False表示不可以取相同数字; 数组p:与数组a对应,表示取数组a中每个元素的概率,默认概率相同
sample_images=data['X'][sample_index,:] #取所有列的sample_idx行
fig,ax_array=plt.subplots(nrows=10,ncols=10,sharex=True,sharey=True,figsize=(12,12))
#plt.subplots(nrows=1,ncols=1,sharex=False,sharey=False,squeeze=True,subplot_kw=None,gridspec_kw=None,**fig_kw):
#nrows,ncols:子图行列数; sharex,sharey设置为True时,所有子图共享x,y轴; **fig_kw:所有其他关键字参数传递给figure()调用
for row in range(10): #range(start,stop,step):[start,stop);start省略时从0开始计数,step省略时步长为1
for col in range(10): #遍历确保对每一个[row,col]的子图都进行修改
ax_array[row,col].matshow(sample_images[10*row+col].reshape((20,20)).T,cmap='gray_r')
#plt.matshow(matrix,cmap= ):绘制矩阵,一个矩阵元素对应一个图像像素
#100个数据,每个数据是20*20像素的数字灰度图像,每个像素用一个浮点数表示该位置的灰度强度,20*20的像素网格被展开成一个400维的向量
#a.reshape(m,n):将原数组a转化为一个m行n列的新数组,a自身不变;((m,n))表示转化为矩阵
#.T将图像翻转,否则图像不正立显示
#cmap='gray_r':白底黑字 (gray:黑底白字)
plt.xticks([]) #去掉x轴刻度
plt.yticks([]) #去掉y轴刻度
plt.show()
labels=np.unique(data['y']) #np.unique():去除数组中的重复数字,顺序排序后输出
num_labels_real=len(labels)
all_theta=one_vs_all(data['X'],data['y'],num_labels_real,1)
y_pred=predict_all(data['X'],all_theta)
print(classification_report(data['y'],y_pred))
#classification_report(y_true,y_pred):显示主要分类指标的文本报告,包括每个类的精确度P、召回率R、F1值(2/F1=1/P+1/R)
#y_true:1维数组,目标值;y_pred:1维数组,分类器返回的预测值
#输出:
#精确度P:对类别n,实际为类别n与预测为类别n的比例
#召回率R:对类别n,预测为类别n与实际为类别n的比例
#F1值(2/F1=1/P+1/R):精确度和召回率都高时,F1值也会高;F1值在1时达到最佳值(完美的精确度和召回率),最差为0
#accuracy:准确率,也即正确预测样本量与总样本量的比值
#macro avg:宏平均,所有类别对应指标的平均值
#weighted avg:带权重平均,类别样本占总样本的比重与对应指标的乘积的累加和
随机展示的100个数据
主要分类指标的文本报告
2-Feedforward Neural Network:在现有权重基础上实现前馈神经网络来识别手写数字导入库
import numpy as np
from scipy.io import loadmat
from sklearn.metrics import classification_report
函数:Sigmoid函数
def sigmoid(z): #Sigmoid函数
return 1/(1+np.exp(-z))
主函数:
#Feedforward Neural Network:在现有权重基础上实现前馈神经网络来识别手写数字
#Iuput layer:20*20像素的图片有400个输入层单元(不包括额外添加的常数项)
#Hidden Layer(25),theta1和Output Layer(10),theta2均已提供
data=loadmat("ex3data1.mat")
weight=loadmat("ex3weights.mat")
theta1,theta2=weight['Theta1'],weight['Theta2']
X=np.matrix(np.insert(data['X'],0,values=np.ones(data['X'].shape[0]),axis=1))
y=np.matrix(data['y'])
#theta1.shape=(25,401) theta2.shape=(10,26)
#X.shape=(5000,401) y.shape=(5000,1)
#前馈神经网络模型
a1=X
z2=a1*theta1.T
a2=sigmoid(z2)
a2=np.insert(a2,0,values=np.ones(a2.shape[0]),axis=1)
z3=a2*theta2.T
a3=sigmoid(z3)
y_pred=np.argmax(a3,axis=1)+1
print(classification_report(y,y_pred))
现有模型(提供)
主要分类指标的文本报告
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)