小工具知识网

当前位置: 首页 > 行业知识 > 新闻单标签多分类

行业知识

新闻单标签多分类

2026-11-07 16:47:09 来源:互联网转载

from keras.datasets import reuters

()

import numpy as np

训练数据,训练标签,测试数据,测试标签,8982个训练样本,2246个测试样本

()

# 这个是新闻单标签多分类问题,就是每个样本会被贴上一个标签,如果是贴多个,就是多标签多分类

# start_char=1,进入新的一篇新闻的标志, oov_char=2,只映射最常用的1万字,超出范围的映射2,

#index_from=3,真正有意义的单词是从索引3开始的,46个类别

(train_data,train_label),(test_data,test_lable)=reuters.load_data(num_words=10000)

#单词对应数字的字典

w_inx=reuters.get_word_index()

#新字典,数字对应单词

# rsw_inx={val:key for (key,val) in w_inx.items()}

rsw_inx=dict([(val,key) for (key,val) in w_inx.items()])

#为啥索引-3,因为它的0,1,2索引是'padding,start of sequence,unknown',

# 翻译成白话就是如果电脑读到1,她就知道这是一篇新的新闻,读到2,就知道这个单词不在1万个常用字之内

#单词和单词之间有空格,应该就是padding,根据数字映射单词,前两个单词应该是人名,不在1万常用字里面

decoded_newswire=''.join([rsw_inx.get(i-3,'?') for i in train_data[0][:20]])

def vect_sequences(seqs,dimension=10000):

    #初始化行为新闻样本数,列为常用的1万个单词

    # 如果是训练数据,形状是(8982,10000),默认元素是0

    res=np.zeros(shape=(len(seqs),dimension))

#     print(enumerate(seqs))

    #遍历所有新闻样本

    #seq是遍历的每一个新闻样本,现在脑子中一定要把新闻

    #这个东西当成一个数字列表,程序员就是翻译家,我们

    #在处理实际问题时要抽象化为数字,这样电脑看起来是很爽的

    # 在给人看的时候是把抽象的数字具体化了,这个方法得作用

    # 就是让电脑知道,一篇新闻里都出现了哪些字

    # 不同的新闻出现的字是不一样的,而我们给的答案(标签)

    # 不一样,这样电脑就会根据输入x,输出y来拟合f,拟合的好坏

    # 是比较真实答案和预测答案的误差,越大越糟糕

    for i,seq in enumerate(seqs):

#         print(len(seq),[rwindex.get(i) for i in seq])

#         print(i,seq)

        # 当前新闻里有某个单词,那这个单词对应的数字列会被赋值1

        #当前新闻没出现的字符是0,1代表Ture

        res[i,seq]=1

    return res

#训练集8982个样本,10000代表10000个常用单词

#一行代表一条新闻

x_train=vect_sequences(train_data)

x_test=vect_sequences(test_data)

display(x_train.shape)

a=rsw_inx.get(1)

b=''.join([rsw_inx.get(i-3,'?') for i in train_data[0]])

display(a,b)

from keras.utils import to_categorical

one_hot_train_labels=to_categorical(train_label)

one_hot_test_labels=to_categorical(test_lable)

from keras import models

from keras import layers

model=models.Sequential()

#128个神经元,隐层一,激活函数relu,10000,单个新闻样本的特征列

# 如果这一列是1,代表出现了某个单词,0,代表没出现这个单词

model.add(layers.Dense(128,activation='relu',input_shape=(10000,)))

#128个神经元,隐层二,激活函数relu

model.add(layers.Dense(128,activation='relu'))

#46分类,所以是46个神经元,softmax处理多分类,经过softmax函数作用后

# 使得某个新闻属于这46类中每个的概率总和等于1

model.add(layers.Dense(46,activation='softmax'))

model.summary()# (10000+1)*128,(128+1)*128,(128+1)*46

# 参数:优化器,rmsprop一阶导,之后做个调和平均放在分母位置,loss多元分类交叉,accuracy看它预估的正确率

#分类问题,不要用mse平方差公式,因为梯度太平坦,要用logi回归的交叉乘

model.compile(optimizer='RMSProp',loss='categorical_crossentropy',metrics=['acc'])

#如果对train(test)_label没做one_hot_encode,可以这样写sparse_categorical_crossentropy

model.compile(optimizer='RMSProp',loss='sparse_categorical_crossentropy',metrics=['acc'])

#验证集,索引0-999,对y先做one_hot_encode编码

#之后再切片,不然会很麻烦

yzj_x=x_train[:1000]

yzj_y=one_hot_train_labels[:1000]

#测试集

csj_x=x_train[1000:]

csj_y=one_hot_train_labels[1000:]

#validation_data验证和测试一起

history=model.fit(csj_x,csj_y,epochs=20,batch_size=512,validation_data=(yzj_x,yzj_y))

import matplotlib.pyplot as plt

#过拟合,太想拟合训练资料,所以在拟合新资料时就有很大偏差

xl_loss=history.history['loss']

xl_zql=history.history['acc']

yz_loss=history.history['val_loss']

yz_zql=history.history['val_acc']

epochs=range(1,1+len(xl_loss))

plt.figure(figsize=(20,9))

plt.rcParams['font.size']=18

ax1=plt.subplot(121)

ax1.plot(epochs,xl_loss,'b',label='xl_loss')

ax1.plot(epochs,yz_loss,'bo',label='yz_loss')

ax1.set_xlabel('epochs')

ax1.set_ylabel('loss')

plt.legend()

plt.title('xl_loss, yz_loss')

ax2=plt.subplot(122)

ax2.plot(epochs,xl_zql,'r',label='xl_zql')

ax2.plot(epochs,yz_zql,'ro',label='yz_zql')

plt.title('xl_zql,yz_zql')

plt.legend()

plt.show()

np.argmin(yz_loss)# 索引5,就是第6次val_loss最小

# 根据上面的训练验证,可以看到第6次迭代,val_loss最小,这次拿

#所有训练数据来跑

model=models.Sequential()

#128个神经元,隐层一,激活函数relu,10000,单个新闻样本的特征列

# 如果这一列是1,代表出现了某个单词,0,代表没出现这个单词

model.add(layers.Dense(128,activation='relu',input_shape=(10000,)))

#128个神经元,隐层二,激活函数relu

model.add(layers.Dense(128,activation='relu'))

#46分类,所以是46个神经元,softmax处理多分类,经过softmax函数作用后

# 使得某个新闻属于这46类中每个的概率总和等于1

model.add(layers.Dense(46,activation='softmax'))

model.compile(optimizer='RMSProp',loss='categorical_crossentropy',metrics=['acc'])

model.fit(x_train,one_hot_train_labels,epochs=6,batch_size=512)

#评估,results返回损失和准确率

results=model.evaluate(x_test,one_hot_test_labels)

#会获得模型对某条新闻属于那一类的概率

#最后一层46个神经元每个预估的概率,总和肯定是1

np.set_printoptions(suppress=True)

pre=model.predict(x_test)

print(np.sum(pre[0]),np.argmax(pre[0]))

np.set_printoptions(suppress=True)

#模型预测的类别

pre_class=np.array([np.argmax(i) for i in pre])

pre_class

#真实类别

test_lable

import pandas as pd

#交叉表

pd.crosstab(index=test_lable,columns=pre_class,rownames=['True_Label'],colnames=['predict_label'])

from sklearn.metrics import classification_report

# 准确率,召回率 support提供的样本,样本资料少,电脑也不知道怎么分

#准确率是电脑预估是几,真的是几的概率

#召回率是真的是几,电脑预估是几的概率

print(classification_report(test_lable,pre_class))

test_copy=test_lable.copy()

display(test_copy[:5])

#随机瞎蒙

np.random.shuffle(test_copy)

display(test_copy[:5])

np.sum(test_copy==test_lable)/len(test_lable)

arr=np.arange(18)

display(arr)

np.random.shuffle(arr)

display(arr)

# 如果不是特别原因,不要某一层神经元突然大幅度减少,会降低验证准确率,降到0.7680

# 之前0.8多

model2=models.Sequential()

#128个神经元,隐层一,激活函数relu,10000,单个新闻样本的特征列

# 如果这一列是1,代表出现了某个单词,0,代表没出现这个单词

model2.add(layers.Dense(128,activation='relu',input_shape=(10000,)))

#10个神经元,隐层二,激活函数relu

model2.add(layers.Dense(10,activation='relu'))

#46分类,所以是46个神经元,softmax处理多分类,经过softmax函数作用后

# 使得某个新闻属于这46类中每个的概率总和等于1

model2.add(layers.Dense(46,activation='softmax'))

model2.compile(optimizer='RMSProp',loss='categorical_crossentropy',metrics=['acc'])

model2.fit(csj_x,csj_y,epochs=20,batch_size=256,validation_data=(yzj_x,yzj_y))

#评估,results返回损失和准确率

results=model2.evaluate(x_test,one_hot_test_labels)

上一篇:GPTool下载指南,轻松一键获取,操作便捷!

下一篇:Android 刷机