逻辑回归 识别0-9数字-吴恩达-机器学习

#导入模块
import matplotlib.pyplot as plt
import numpy as np
from scipy.io import loadmat
import matplotlib
import scipy.optimize as opt
from sklearn.metrics import classification_report#这个包是评价报告

第一步 数据可视化

#导入数据
data =loadmat('ex3data1.mat')
data.keys()
dict_keys(['__header__', '__version__', '__globals__', 'X', 'y'])
X =data['X']
y =data['y']

#输出一个数字
ix =np.random.randint(0,5000)
a =X[ix,:]
#输入一个数字图像
b =a.reshape(20,20)
fig,ax =plt.subplots(figsize =(8,7))
ax.matshow(b)
ax.matshow(b,cmap =matplotlib.cm.binary)

 输出100个手写体数字

#数字是旋转的需要对其进行转置
X1 =np.array([im.reshape(20,20).T for im in X])
X_T =np.array([im.reshape(400) for im in X1])

#输出100个数字图像
#随机选取X中的100个数字图像
image_index =np.random.choice(X_T.shape[0],100)
image_100 =X_T[image_index,:]
#fig,ax =plt.subplots(figsize =(8,7))

fig1,ax =plt.subplots(nrows =10,ncols =10,figsize =(10,10),sharey=True, sharex=True,)

for i in range(10):
    for j in range(10):
        #不要下标
        plt.xticks(np.array([])) 
        plt.yticks(np.array([]))
        ax[i,j].matshow(image_100[i*10+j,:].reshape(20,20),cmap =matplotlib.cm.binary)
        
    
        

 

 第二步:向量化逻辑回归,损失函数和迭代梯度(含正则化)

#训练图像特征X_T,训练标签y1
y1 =y.reshape(y.shape[0])
print(X_T.shape,y1.shape)
print(type(X_T),type(y1))

#特征数据第一列插入1值
trainX =np.insert(X_T,0,values =np.ones(X_T.shape[0]),axis =1)

ln =[]
#对数据y1进行处理,例如只看数字10为标签,则10的位置为1,其他地方为0
#因此,对10,1,2.。。数字进行分类标签处理,每个数字映射为0,1标签(5000*1)
for num in range(1,11):
    ln.append((y1==num).astype(int))
ln =[ln[-1]]+ln[:-1]
trainy =np.array(ln)

#训练图像特征dataX,训练标签datay
print(trainX.shape,trainy.shape)
print(type(trainX),type(trainy))

(5000, 401) (10, 5000)
<class 'numpy.ndarray'> <class 'numpy.ndarray'>

定义损失函数与梯度函数

#定义损失函数
def cost(theta,X,y):
    '''
    输入:theta 参数,X 特征数据 ,y标签数据
    输出:cost 损失值
    '''
    #假设函数
    h =X@theta
    g =1/(1+np.exp(-h))
    #损失值
    first =-y*np.log(g)
    second =(1-y)*(np.log(1-g))
    return np.mean(first-second)

#定义梯度迭代函数
def gradient(theta,X,y):
    '''
    输入:theta 参数,X 特征数据 ,y标签数据
    输出:迭代后的参数θ值 
    '''
    #假设函数
    h =X@theta
    g =1/(1+np.exp(-h))
    
    temp =g-y
    return (X.T@temp)/len(X)

#定义正则化损失函数与梯度函数
#定义正则化损失函数
def cost_regularize(theta,X,y,lamda=1):
    '''
    输入:theta 参数28*1,X 特征数据 118*28,y标签数据118*1,l 正则化参数lamda,默认为1
    输出:cost 损失值
    '''
    third =np.sum(np.power(theta,2))*lamda/(len(X)*2)
    return cost(theta,X,y)+third

#定义正则化梯度迭代函数
def gradient_regularize(theta,X,y,lamda=1):
    '''
    输入:theta 参数28*1,X 特征数据 118*28,y标签数据118*1,l 正则化参数lamda,默认为1
    输出:迭代后的参数θ值 28*1
    注:theta0的梯度不用正则化
    '''
    #正则化
    theta_reg =theta*lamda/(len(X))
    theta_reg[0] =0
    return gradient(theta,X,y)+theta_reg

 第三步:分类和预测

先做一分类,识别数字0

#先做一分类,识别数字0
trainy0 =trainy[0]
trainy0.shape
(5000,)


#定义正则化训练模型
def logistic(X,y,lamda =1):
    #初始化参数theta
    theta =np.zeros(trainX.shape[1])
    #初始损失值
    print('初始损失值:',cost(theta,X,y))
    #训练模型
    result =opt.minimize(fun =cost_regularize,x0 =theta, args=(X,y,lamda),method ='TNC',jac =gradient_regularize)
    #终止损失值
    print('最终损失值:',result.fun)
    return result.x

theta_final=logistic(trainX,trainy0)

#模型评价
h =trainX@theta_final
g =1/(1+np.exp(-h))
predict =[]
for i in g:
    if i>=0.5:
        predict.append(1)
    else:
        predict.append(0)
print(classification_report(trainy0,predict))

0-9多分类训练

theta_k =[]
for i in range(10):
    theta_k.append(logistic(trainX,trainy[i]))
theta_k =np.array(theta_k)
theta_k.shape

#将训练好的10个数字的theta参数代入训练特征中,计算预测结果,并对其进行评价
#定义sigmoid函数
def sigmoid(x):
    f =1/(1+np.exp(-x))
    return f
p_k = sigmoid(trainX @theta_k.T)
p_k.shape,p_k

#多分类,不能直接利用数值大于0.5或小于0.5来判断0-1分类
#p_k 5000*10 ,要得到预测的结果是5000*1,
#也就是说,每一行中数值最大的那个数对应的数字预测结果可能性最大
#所以每一行返回数值最大的对应的下标,将5000*10映射为5000*1,便是结果
predict_y =np.argmax(p_k,axis =1)
real_y =y.copy()
real_y[real_y==10] =0
print(classification_report(real_y,predict_y))

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

なつの目

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值