Clasificación de texto-Word2vec + LSTM

Tabla de contenido

1. Combate práctico de la clasificación de textos LSTM.

 1. Lectura y preprocesamiento de datos

2. Codificación de secuencia de texto

3. Incrustación + LSTM (incluida la introducción a los parámetros de LSTM)

4. Word2vec+LSTM bidireccional

2. Concéntrate en

Evite 10 años de desvíos


        LSTM (memoria larga a corto plazo) es un tipo especial de red neuronal recurrente (RNN) que se utiliza para procesar el modelado y la predicción de datos de secuencia y datos de series de tiempo. En comparación con la estructura RNN tradicional, LSTM introduce un mecanismo de activación que puede capturar y recordar mejor las dependencias a largo plazo.

         La idea clave de LSTM es lograr la memoria a largo plazo controlando el flujo y olvidándose de la información. Consta de una serie de celdas llamadas "celdas de memoria", cada celda de memoria tiene un estado interno (estado de celda) y tres puertas (puertas): puerta de entrada (puerta de entrada), puerta de olvido (puerta de olvido) y puerta de salida.

1. Combate práctico de la clasificación de textos LSTM.

 1. Lectura y preprocesamiento de datos

# 导包
import re
import os
from sqlalchemy import create_engine
import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings('ignore')
import sklearn
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve,roc_auc_score
import xgboost as xgb
from xgboost.sklearn import XGBClassifier
import lightgbm as lgb
import matplotlib.pyplot as plt
import gc

from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras import models
from tensorflow.keras import layers
from tensorflow.keras import optimizers

# 2、数据读取+预处理
data=pd.read_excel('Inshorts Cleaned Data.xlsx')
 
def data_preprocess(data):
    df=data.drop(['Publish Date','Time ','Headline'],axis=1).copy()
    df.rename(columns={'Source ':'Source'},inplace=True)
    df=df[df.Source.isin(['YouTube','India Today'])].reset_index(drop=True)
    df['y']=np.where(df.Source=='YouTube',1,0)
    df=df.drop(['Source'],axis=1)
    return df
 
df=data.pipe(data_preprocess)
print(df.shape)
df.head()

# 导入英文停用词
from nltk.corpus import stopwords  
from nltk.tokenize import sent_tokenize
stop_english=stopwords.words('english')  
stop_spanish=stopwords.words('spanish') 
stop_english

# 4、文本预处理:处理简写、小写化、去除停用词、词性还原
from nltk.stem import WordNetLemmatizer
from nltk.corpus import stopwords  
from nltk.tokenize import sent_tokenize
import nltk
 
def replace_abbreviation(text):
    
    rep_list=[
        ("it's", "it is"),
        ("i'm", "i am"),
        ("he's", "he is"),
        ("she's", "she is"),
        ("we're", "we are"),
        ("they're", "they are"),
        ("you're", "you are"),
        ("that's", "that is"),
        ("this's", "this is"),
        ("can't", "can not"),
        ("don't", "do not"),
        ("doesn't", "does not"),
        ("we've", "we have"),
        ("i've", " i have"),
        ("isn't", "is not"),
        ("won't", "will not"),
        ("hasn't", "has not"),
        ("wasn't", "was not"),
        ("weren't", "were not"),
        ("let's", "let us"),
        ("didn't", "did not"),
        ("hadn't", "had not"),
        ("waht's", "what is"),
        ("couldn't", "could not"),
        ("you'll", "you will"),
        ("i'll", "i will"),
        ("you've", "you have")
    ]
    result = text.lower()
    for word_replace in rep_list:
        result=result.replace(word_replace[0],word_replace[1])
#     result = result.replace("'s", "")
    
    return result
 
def drop_char(text):
    result=text.lower()
    result=re.sub('[^\w\s]',' ',result) # 去掉标点符号、特殊字符
    result=re.sub('\s+',' ',result) # 多空格处理为单空格
    return result
 
def stemed_words(text,stop_words,lemma):
    
    word_list = [lemma.lemmatize(word, pos='v') for word in text.split() if word not in stop_words]
    result=" ".join(word_list)
    return result
 
def text_preprocess(text_seq):
    stop_words = stopwords.words("english")
    lemma = WordNetLemmatizer()
    
    result=[]
    for text in text_seq:
        if pd.isnull(text):
            result.append(None)
            continue
        text=replace_abbreviation(text)
        text=drop_char(text)
        text=stemed_words(text,stop_words,lemma)
        result.append(text)
    return result
 
df['short']=text_preprocess(df.Short)
df[['Short','short']]

# 5、划分训练、测试集
test_index=list(df.sample(2000).index)
df['label']=np.where(df.index.isin(test_index),'test','train')
df['label'].value_counts()

2. Codificación de secuencia de texto

        Ordene por frecuencia de palabras, cree un diccionario de palabras de alta frecuencia con una longitud de 6000 y serialice el texto.

from tensorflow.keras.preprocessing.text import Tokenizer
def word_dict_fit(train_text_list,num_words):
    '''
        train_text_list: ['some thing today ','some thing today2']
    '''
    tok_params={
        'num_words':num_words,  # 词典的长度,仅保留词频top的num_words个词
        'filters':'!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',
        'lower':True, 
        'split':' ', 
        'char_level':False, 
        'oov_token':None, # 设定词典外的词编码
    }
    tok = Tokenizer(**tok_params) # 分词
    tok.fit_on_texts(train_text_list)
    
    return tok

def word_dict_apply_sequences(tok_model,text_list,len_vec):
    '''
        text_list: ['some thing today ','some thing today2']
    '''
    list_tok = tok_model.texts_to_sequences(text_list) # 编码映射
    
    pad_params={
        'sequences':list_tok,
        'maxlen':len_vec,  # 补全后向量长度
        'padding':'pre', # 'pre' or 'post',在前、在后补全
        'truncating':'pre', # 'pre' or 'post',在前、在后删除长度多余的部分
        'value':0, # 补全0
    }
    seq_tok = pad_sequences(**pad_params) # 补全编码向量,返回二维array
    return seq_tok

num_words,len_vec = 6000,40
tok_model= word_dict_fit(df[df.label=='train'].short,num_words)
tok_train = word_dict_apply_sequences(tok_model,df[df.label=='train'].short,len_vec)
tok_test = word_dict_apply_sequences(tok_model,df[df.label=='test'].short,len_vec)
tok_test

3. Incrustación + LSTM (incluida la introducción a los parámetros de LSTM)

        La entrada de la capa LSTM es un tensor tridimensional (batch_size, timesteps, input_dim), por lo que los datos utilizados pueden ser una serie de tiempo o una incrustación de datos de texto; la salida establece return_sequences en False y devuelve una hoja 2D de tamaño ( tamaño_lote, unidades) cantidad.

'''
LSTM层核心参数
    units:输出维度
    activation:激活函数
    recurrent_activation: RNN循环激活函数
    use_bias: 布尔值,是否使用偏置项
    dropout:0~1之间的浮点数,神经元失活比例
    recurrent_dropout:0~1之间的浮点数,循环状态的神经元失活比例
    return_sequences: True时返回RNN全部输出序列(3D),False时输出序列的最后一个输出(2D)
'''
def init_lstm_model(max_features, embed_size):
    model = Sequential()
    model.add(Embedding(input_dim=max_features, output_dim=embed_size))
    model.add(Bidirectional(LSTM(units=32,activation='relu', recurrent_dropout=0.1)))
    model.add(Dropout(0.25,seed=1))
    model.add(Dense(64))
    model.add(Dropout(0.3,seed=1))
    model.add(Dense(1, activation='sigmoid'))

    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
    
    return model

def model_fit(model, x, y,test_x,test_y):
    return model.fit(x, y, batch_size=100, epochs=2, validation_data=(test_x,test_y))

embed_size = 128
lstm_model=init_lstm_model(num_words, embed_size)
model_train=model_fit(lstm_model,tok_train,np.array(df[df.label=='train'].y),tok_test,np.array(df[df.label=='test'].y))
lstm_model.summary()

def ks_auc_value(y_value,df,model):
    y_pred=model.predict(df)
    fpr,tpr,thresholds= roc_curve(list(y_value),list(y_pred))
    ks=max(tpr-fpr)
    auc= roc_auc_score(list(y_value),list(y_pred))
    return ks,auc

ks_auc_value(df[df.label=='train'].y,tok_train,model)
'''
output:
    (0.8611593007957995, 0.9749818730610305)

'''

ks_auc_value(df[df.label=='test'].y,tok_test,model)
'''
output:
    (0.7191120926957301, 0.9123405591831509)

'''

4. Word2vec+LSTM bidireccional

        El LSTM bidireccional se compone de dos LSTM unidireccionales, que se entrenan de adelante hacia atrás y de atrás hacia adelante en secuencia. Como se puede ver anteriormente, debido a la pequeña cantidad de datos, los resultados de Embedding + LSTM tienen un cierto problema de sobreajuste, por lo que se utiliza el modelo de preentrenamiento de Word2vec + LSTM bidireccional para entrenamiento y evaluación. El conjunto de entrenamiento y el conjunto de pruebas de los resultados de la evaluación final se reducen significativamente.

def init_lstm_model(max_features, embed_size ,embedding_matrix):
    
    model = Sequential()
    model.add(Embedding(input_dim=max_features, output_dim=embed_size,weights=[embedding_matrix],trainable=False))
    model.add(Bidirectional(layers.LSTM(units=32,activation='relu', recurrent_dropout=0.1)))
    model.add(Dropout(0.3,seed=1))
    model.add(Dense(64,activation='relu'))
    model.add(Dropout(0.3,seed=1))
    model.add(Dense(1, activation='sigmoid'))

    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
    
    return model

def model_fit(model, x, y,test_x,test_y):
    return model.fit(x, y, batch_size=100, epochs=5, validation_data=(test_x,test_y))

num_words,embed_size = 6000,128
lstm_model=init_lstm_model(num_words, embed_size ,embedding_matrix)
model_train=model_fit(lstm_model,tok_train,np.array(df[df.label=='train'].y),tok_test,np.array(df[df.label=='test'].y))

ks_auc_value(df[df.label=='train'].y,tok_train,model)
'''
output:
    (0.7223217797649937, 0.922939132379851)

'''

ks_auc_value(df[df.label=='test'].y,tok_test,model)
'''
output:
    (0.7046603930606234, 0.9140880065296716)

'''

2. Concéntrate en

Evite 10 años de desvíos

        Siga el modelo de control de riesgos y análisis de datos de Python de la cuenta pública de Weixin y responda a la  categoría de texto 4  para obtener los datos y el código de este artículo.

        Hay más teorías y códigos compartidos esperándote.

Supongo que te gusta

Origin blog.csdn.net/a7303349/article/details/132405222
Recomendado
Clasificación