中文文本分类实战--数据处理部分
之前用智源上面一个虚假新闻检测的比赛练了练手,数据集可以在比赛官网上下载task1。可以看成中文文本分类任务,之前只是跑了跑模型,没有关注词向量的训练以及多模型融合。目前我在细化,会不断和大家分享,相互学习,欢迎交流,结束后我会把代码更新github
任务介绍
虚假新闻文本检测:文本是新闻信息的主要载体,对新闻文本的研究有助于虚假新闻的有效识别。具体任务为:给定一个新闻事件的文本,判定该事件属于真实新闻还是虚假新闻。
虚假新闻文本检测任务中,训练集共包含38,471条新闻,其中包含真实新闻19,186条,虚假新闻19,285条。初赛测试集共4,000条,复赛测试集3,902条,真假新闻比例与训练集基本一致。
数据字段:
id:新闻id,每条文本中id均不相同,唯一表征一条新闻;
text: 新闻的文本内容;
label: 取值为{0,1},0表示真实新闻,1表示虚假新闻。
每支队伍在参赛期间可随时提交验证集的预测结果,将验证结果在一个文本文件中进行提交,命名为submit.csv,格式如下:
id,label
123,1
456,0
......
其中,对于虚假文本检测任务, id是新闻id,label是该新闻文本对应的预测结果,int类型,取值范围为{0,1},虚假新闻为1,真实新闻为0;
数据集
官方给的数据集有Excel表格给出,该数据集共有38471条数据,其中19186条假新闻,19185条真新闻。每条数据由[id,text,label]三个元素组成,其中qid是每一条数据的唯一id标识,text是中文新闻文本,label是0/1,0表示真实新闻,1表示虚假新闻。测试数据集需要提交到后台判定。对数据集进行分析可以得到:
| 最大句子长度 | 最小句子长度 | 平均数据长度 | 分词后词的个数 |
| 929 | 0 | 50.883678615060695 | 73915 |
相关库函数的载入
import time
import jieba
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer,CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn import metrics
import pandas as pd
import numpy as npfrom gensim.models import Word2Vecfrom keras.layers import *
from keras.models import *
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.engine.topology import Layerfrom tqdm import tqdmmaxlen = 100
(一)数据处理
1.数据清洗
之前做的一个英文文本分类在数据处理上,主要做了标点符号的整理,颜文字等特殊符号的处理,大小写的转换,数字的清理,以及利用一个手写的小字典对数据的拼写错误进行检测。数据清洗后,利用keras的tokenizer接口将句子进行符号化,并padding到等长,为将来向量化做准备。
在中文数据处理上与英文有所不同,主要做了去除指定无用的符号,只保留文本中的文字,利用一个手写的list记录所有停用词,去除停用词并对文本进行分词。数据清洗后,需要将句子进行符号化,由于中文没有分词器tokenizer,我先构建了一个vocab保存所有分好的词,共有73915个单词,根据词典将句子序列化,再将句子padding到等长,为将来向量化做准备,下面上代码
数据清洗的代码:
"去除指定无用的符号,这里我们主要拿空格举例"
puncts = [' ']
def clean_text(x):x=x.strip()for punct in puncts:x=x.replace(punct,'')return x"让文本只保留文字"
def is_chinese(xchar):if xchar>=u'\u4e00' and xchar<=u'\u9fa5':return Trueelse:return False
def keep_chinese_text(x):out_str=''for i in x:if is_chinese(i):out_str=out_str+ireturn out_strdef seg_sentence(sentence,stopwords):"对句子进行分词和去除停用词"sentence_seged=jieba.cut(sentence)outstr=''for word in sentence_seged:if word not in stopwords:outstr+=wordoutstr+=" "return outstr
词典的构建以及文本序列化的代码
def build_vocab(sentences,verbose=True):"追踪训练词汇表,遍历所有文本对单词进行计数"vocab={}for sentence in tqdm(sentences,disable=(not verbose)):for word in sentence.split():try:vocab[word]+=1except KeyError:vocab[word]=1#vocab=sorted(vocab.items(),key=lambda d:d[1],reverse=True) # 分词后共出现70634个单词# vocab=vocab[:vocab_size]print(len(vocab))return vocabdef texts_to_sequences(sentences,vocab,verbose=True):seq_sentences=[]for sentence in tqdm(sentences,disable=(not verbose)):seq_sentence=[]for word in sentence.split():seq_sentence.append(vocab.get(word))seq_sentences.append(seq_sentence)return seq_sentences
数据处理的全部代码
def load_and_prec():#文件读取train_df=pd.read_csv('data/news_classification_dataset.csv')#创建停用词列表stopwords = ['的', '呀', '这', '那', '就', '的话', '如果']train_df["text"]=train_df["text"].apply(lambda x:clean_text(x))train_df["text"]=train_df["text"].apply(lambda x:keep_chinese_text(x))train_df["text"]=train_df["text"].apply(lambda x:seg_sentence(x,stopwords))vocab=build_vocab(train_df["text"],True)# split to train and valtrain_df,val_df=train_test_split(train_df,test_size=0.1,random_state=2019)# print("Train shape: ",train_df.shape) # (34623, 3)# print("Val shape: ",val_df.shape) # (3848, 3)## Get the input valuestrain_X=train_df["text"].valuesval_X=val_df["text"].values## Get the target valuestrain_y=train_df["label"].valuesval_y=val_df["label"].valuesnp.random.seed(2019)trn_idx=np.random.permutation(len(train_X))val_idx=np.random.permutation(len(val_X))train_X=train_X[trn_idx]val_X=val_X[val_idx]train_y=train_y[trn_idx]val_y=val_y[val_idx]# Tokenize the sentencestrain_X=texts_to_sequences(train_X, vocab)val_X=texts_to_sequences(val_X,vocab)# Pad the sentencestrain_X=pad_sequences(train_X,maxlen=maxlen)val_X=pad_sequences(val_X,maxlen=maxlen)return train_df,val_df,train_X,val_X,train_y,val_y,vocab
2. 词向量的训练
def word2vec_model(train_df, val_df, vocab):count=0nb_words=len(vocab)print(nb_words)start=time.clock()all_data=pd.concat([train_df["text"],val_df["text"]])file_name='data/word2vec.model'if not os.path.exists(file_name):model=Word2Vec([[word for word in sentence.split()] for sentence in all_data.values],size=embed_size,window=5,iter=10,workers=11,seed=2019,min_count=2)model.save(file_name)else:model=Word2Vec.load(file_name)print("add word2vec finished...")end=time.clock()print('Running time: %s Seconds' %(end-start))nb_words=min(max_features,len(vocab))embedding_word2vec_matrix=np.zeros((nb_words,embed_size))for word,i in vocab.items():if i>max_features:continueembedding_vector=model[word] if word in model else Noneif embedding_vector is not None:count+=1embedding_word2vec_matrix[i]=embedding_vectorelse:unk_vec=np.random.random(embed_size)*0.5unk_vec=unk_vec-unk_vec.mean()embedding_word2vec_matrix[i]=unk_vecdel model;gc.collect()return embedding_word2vec_matrix
3. 主函数中直接运行即可
if __name__ == '__main__':train_df, val_df, train_X, val_X, train_y, val_y, vocab=load_and_prec()embedding_word2vec_matrix=word2vec_model(train_df,val_df,vocab)print(embedding_word2vec_matrix.shape) #(73915, 200)
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
