交叉熵

# -*- coding: utf-8 -*-
"""
Created on Wed Jan  9 09:18:49 2019
@author: shenfangyuan
参见:http://scikit-learn.org/stable/modules/model_evaluation.html#log-loss
"""
from sklearn.metrics import log_loss
from sklearn.preprocessing import LabelBinarizer
from math import log
import numpy as np
'''
数据说明:
1,y_pred是3行10列的数据,3行代表3个样本,10列代表该行样本对应于classes中类别的
  分类概率, y_pred每行数据(各个类别的预测概率之和)相加和是"1".
2,y_pred的3个行与:y_true = ['1', '4', '5']相对应,代表着该行数据的真实分类标签
  他的数据取自于classes中的值.
3,我们通过每行的10个数据,得到分类的预测值.
4,y_pred的每行10个数据,类似于神经网络的10个输出神经元细胞,(相当于10个评委)
  这10个输出分别对应在10个"类别轴"上的概率值.我们通常取这10个值中的最大值,
  作为分类的预测值,把各行的分类预测值与分类标签y_true对比,求取差异--交叉熵.
 
  1)先求数据在每个"类别轴"的投影值,"预测概率" 向量
  2)求概率预测值向量中的最大值,作为该行数据最后所属的分类值.
  3)把预测得到的分类与标记标签进行"差异"估计--交叉熵是方法之一!

 
'''
classes = ['0','1','2','3','4','5','6','7','8','9']
#y_true 是样本集合中,样本的真实标签,其取值数据只能取自labels集合中的元素
y_true = ['1', '4', '5']
#y_pred 样本的预测概率 每行 10个元素,labels也是10个元素.
y_pred = [[0.1, 0.6, 0.3, 0, 0, 0, 0, 0, 0, 0],
          [0, 0.3, 0.2, 0, 0.5, 0, 0, 0, 0, 0],
          [0.6, 0.3, 0, 0, 0, 0.1, 0, 0, 0, 0]]              
# 利用sklearn中的log_loss()函数计算交叉熵
sk_log_loss = log_loss(y_true, y_pred, labels=classes)
print("Loss by sklearn  is:%s." %sk_log_loss)
# 利用公式实现交叉熵
# 交叉熵的计算公式网址为:
# http://scikit-learn.org/stable/modules/model_evaluation.html#log-loss
# 对样本的真实标签进行标签二值化
lb = LabelBinarizer() #构造一个LabelBinarizer类对象
lb.fit(classes)       #通过类对象,以classes中的数据为参数对类对象进行配置
transformed_labels = lb.transform(y_true)  #依照类对象中存储的classes,对y_true进行编码
#transformed_labels是(3,10)的矩阵,one-hot编码,3行对应3个数据,10列对应10个分类类别的概率.
#相当于把y_true进行one-hot编码.
# print(transformed_labels)
N = len(y_true)  # 样本个数 N=3
K = len(classes)  # 标签个数 K=10
eps  = 1e-15      # 预测概率的控制值
#eps  = 0.00001      # 预测概率的控制值
Loss = 0         # 损失值初始化
for i in range(N):
    for k in range(K):
        # 控制预测概率在[eps, 1-eps]内,避免求对数时出现问题
        # 这里主要是为了避免出现数值计算问题,如:log(0) 和 log(1)
        if y_pred[i][k] < eps:
            y_pred[i][k] = eps
        if y_pred[i][k] > 1-eps:
            y_pred[i][k] = 1-eps
        # 多分类问题的交叉熵计算公式
        # transformed_labels 是理想标签经过转换后的矩阵,维度也是 (3,10)
        Loss -= transformed_labels[i][k]*log(y_pred[i][k])
Loss /= N
print("Loss by equation is:%s." % Loss)
'''
Loss by sklearn  is:1.16885263244.
Loss by equation is:1.16885263244.
'''

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值