首先,對需要導入的庫進行導入,讀入數據后,用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