keras 文本分類 LSTM


 

 

首先,對需要導入的庫進行導入,讀入數據后,用jieba來進行中文分詞

# encoding: utf-8


#載入接下來分析用的庫
import pandas as pd
import numpy as np
import xgboost as xgb
from tqdm import tqdm
from sklearn.svm import SVC
from keras.models import Sequential
from keras.layers.recurrent import LSTM, GRU
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.embeddings import Embedding
from keras.layers.normalization import BatchNormalization
from keras.utils import np_utils
from sklearn import preprocessing, decomposition, model_selection, metrics, pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.decomposition import TruncatedSVD
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.naive_bayes import MultinomialNB
from keras.layers import GlobalMaxPooling1D, Conv1D, MaxPooling1D, Flatten, Bidirectional, SpatialDropout1D
from keras.preprocessing import sequence, text
from keras.callbacks import EarlyStopping
from nltk import word_tokenize


text = pd.read_csv('./competeDataForA.csv',sep = '\t', encoding ='utf-8')
test = pd.read_csv('./evaluationDataForA.csv',sep = '\t', encoding ='utf-8')
# print(text['id'].head())
# print(text['ocr'].head())
# print(text['label'].head())

print (text.info())

print (text.label.unique())


import jieba
# jieba.enable_parallel() #並行分詞開啟
text['文本分詞'] = text['ocr'].apply(lambda i:jieba.cut(i) )
text['文本分詞'] =[' '.join(i) for i in text['文本分詞']]

test['文本分詞'] = test['ocr'].apply(lambda i:jieba.cut(i) )
test['文本分詞'] =[' '.join(i) for i in test['文本分詞']]


print (text.head())


lbl_enc = preprocessing.LabelEncoder()
y = lbl_enc.fit_transform(text.label.values)

xtrain, xvalid, ytrain, yvalid = train_test_split(text.文本分詞.values, y, 
                                                  stratify=y, 
                                                  random_state=42, 
                                                  test_size=0.1, shuffle=True)
print (xtrain.shape)
print (xvalid.shape)

xtest = test.文本分詞.values


X=text['文本分詞']

X=[i.split() for i in X]
X[:2]

  

 

然后調用Keras對文本進行序列化:

設置最大長度為500,多余值填0;

 

# ##################  LSTM 嘗試  ##############################
# # 使用 keras tokenizer
from keras.preprocessing import sequence, text
token = text.Tokenizer(num_words=None)
max_len = 500

token.fit_on_texts(list(xtrain) + list(xvalid))
xtrain_seq = token.texts_to_sequences(xtrain)
xvalid_seq = token.texts_to_sequences(xvalid)
xtest_seq = token.texts_to_sequences(xtest)

#對文本序列進行zero填充
xtrain_pad = sequence.pad_sequences(xtrain_seq, maxlen=max_len)
xvalid_pad = sequence.pad_sequences(xvalid_seq, maxlen=max_len)
xtest_pad = sequence.pad_sequences(xtest_seq, maxlen=max_len)

word_index = token.word_index

  

import gensim

model = gensim.models.Word2Vec(X,min_count =5,window =8,size=100)   # X是經分詞后的文本構成的list,也就是tokens的列表的列表
embeddings_index = dict(zip(model.wv.index2word, model.wv.vectors))

print('Found %s word vectors.' % len(embeddings_index))

print (len(word_index))
embedding_matrix = np.zeros((len(word_index) + 1, 100))
for word, i in tqdm(word_index.items()):
    embedding_vector = embeddings_index.get(word)
    if embedding_vector is not None:
        embedding_matrix[i] = embedding_vector

  

# 基於前面訓練的Word2vec詞向量,使用1個兩層的LSTM模型
ytrain_enc = np_utils.to_categorical(ytrain)
yvalid_enc = np_utils.to_categorical(yvalid)

model = Sequential()
model.add(Embedding(len(word_index) + 1,
                     100,
                     weights=[embedding_matrix],
                     input_length=max_len,
                     trainable=False))
model.add(SpatialDropout1D(0.3))
model.add(LSTM(100, dropout=0.3, recurrent_dropout=0.3))

model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.8))

model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.8))

model.add(Dense(2))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam')

#在模型擬合時,使用early stopping這個回調函數(Callback Function)
earlystop = EarlyStopping(monitor='val_loss', min_delta=0, patience=3, verbose=0, mode='auto')
model.fit(xtrain_pad, y=ytrain_enc, batch_size=512, epochs=35, 
          verbose=1, validation_data=(xvalid_pad, yvalid_enc), callbacks=[earlystop])

pred_lstm_2 = model.predict_classes(xtest_pad)
pred_lstm_2 = pd.DataFrame(pred_lstm_2)
pred_lstm_2_res = pd.concat([test['id'],pred_lstm_2], axis=1)
pred_lstm_2_res.rename(columns={0:'label'},inplace=True)
pred_lstm_2_res.to_csv('pred_lstm_2_res.csv',sep = ',', index = False, encoding = 'utf-8')

  

LSTM有三種dropout:

model.add(LSTM(100, dropout=0.2, recurrent_dropout=0.2))

第一個dropout是x和hidden之間的dropout,第二個是hidden-hidden之間的dropout

 

第三個是層-層之間的dropout

model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length))
model.add(Dropout(0.2))
model.add(LSTM(100))
model.add(Dropout(0.2))

 

Keras分詞器Tokenizer

0. 前言

Tokenizer是一個用於向量化文本,或將文本轉換為序列(即單個字詞以及對應下標構成的列表,從1算起)的類。是用來文本預處理的第一步:分詞。結合簡單形象的例子會更加好理解些。

1. 語法

官方語法如下1:

Code.1.1 分詞器Tokenizer語法

keras.preprocessing.text.Tokenizer(num_words=None,
                                   filters='!"#$%&()*+,-./:;<=>?@[\]^_`{|}~\t\n',
                                   lower=True,
                                   split=" ",
                                   char_level=False)

  

1.1 構造參數
num_words:默認是None處理所有字詞,但是如果設置成一個整數,那么最后返回的是最常見的、出現頻率最高的num_words個字詞。
filters:過濾一些特殊字符,默認上文的寫法就可以了。
lower:全部轉為小寫
split:字符串,單詞的分隔符,如空格

1.2 返回值
字符串列表

1.3 類方法
下面是相關的類方法,部分示例在下一節中均有描述應用。


1.4 屬性

  • document_count 處理的文檔數量
  • word_index 一個dict,保存所有word對應的編號id,從1開始
  • word_counts 一個dict,保存每個word在所有文檔中出現的次數
  • word_docs 一個dict,保存每個word出現的文檔的數量
  • index_docs 一個dict,保存word的id出現的文檔的數量

 

  • word_counts:字典,將單詞(字符串)映射為它們在訓練期間出現的次數。僅在調用fit_on_texts之后設置。
  • word_docs: 字典,將單詞(字符串)映射為它們在訓練期間所出現的文檔或文本的數量。僅在調用fit_on_texts之后設置。
  • word_index: 字典,將單詞(字符串)映射為它們的排名或者索引。僅在調用fit_on_texts之后設置。
  • document_count: 整數。分詞器被訓練的文檔(文本或者序列)數量。僅在調用fit_on_texts或fit_on_sequences之后設置。

2. 簡單示例

Code.2.1 簡單示例

>>>from keras.preprocessing.text import Tokenizer
Using TensorFlow backend.

#  創建分詞器 Tokenizer 對象
>>>tokenizer = Tokenizer()

#  text
>>>text = ["今天 北京 下 雨 了", "我 今天 加班 了"]

#  fit_on_texts 方法
>>>tokenizer.fit_on_texts(text)

#  word_counts屬性
>>>tokenizer.word_counts
OrderedDict([('今天', 2),
             ('北京', 1),
             ('下', 1),
             ('雨', 1),
             ('了', 2),
             ('我', 1),
             ('加班', 1)])

#  word_docs屬性
>>>tokenizer.word_docs
defaultdict(int, {'下': 1, '北京': 1, '今天': 2, '雨': 1, '了': 2, '我': 1, '加班': 1})

#  word_index屬性
>>>tokenizer.word_index
{'今天': 1, '了': 2, '北京': 3, '下': 4, '雨': 5, '我': 6, '加班': 7}

#  document_count屬性
>>>tokenizer.document_count
2

  

3. 常用示例

還以上面的tokenizer對象為基礎,經常會使用texts_to_sequences()方法 和 序列預處理方法 keras.preprocessing.sequence.pad_sequences一起使用

有關pad_sequences用法見python函數——序列預處理pad_sequences()序列填充

Code.3.1 常用示例

>>>tokenizer.texts_to_sequences(["下 雨 我 加班"])
[[4, 5, 6, 7]]

>>>keras.preprocessing.sequence.pad_sequences(tokenizer.texts_to_sequences(["下 雨 我 加班"]), maxlen=20)
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7]],dtype=int32)

 

 

Keras基本使用方法:

https://blog.csdn.net/qq_41185868/article/details/84067803

Python中利用LSTM模型進行時間序列預測分析

http://www.cnblogs.com/arkenstone/p/5794063.html

 

 

參考:https://blog.csdn.net/wcy23580/article/details/84885734

           https://zhuanlan.zhihu.com/p/50657430


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM