Классификация текста: Keras+RNN против традиционного машинного обучения

машинное обучение Нейронные сети

Аннотация: В этой статье реализуется случай обучения классификации текста RNN с помощью Keras, а также подробно представлены основные знания о рекуррентной нейронной сети и сравнение с машинным обучением.

Эта статья опубликована в сообществе HUAWEI CLOUD.«Классификация текста на основе Keras+RNN по сравнению с классификацией текста на основе традиционного машинного обучения», по Истмаунт.

1. Классификация текстов RNN

1.RNN

Рекуррентная нейронная сеть на английском языке — это рекуррентные нейронные сети, называемые RNN. Основная концепция RNN заключается в использовании информации о временных рядах.В традиционной нейронной сети предполагается, что все входы (и выходы) независимы. Однако для многих задач это очень ограничивает. Например, если вы хотите предсказать следующее слово на основе незаконченного предложения, лучший способ сделать это — подключить контекстную информацию. RNN (рекуррентные нейронные сети) являются «рекуррентными», потому что они выполняют одну и ту же задачу для каждого элемента последовательности, и каждый раз результат не зависит от предыдущих вычислений.

Предположим, есть набор данных data0, data1, data2, data3, используйте одну и ту же нейронную сеть для их предсказания и получите соответствующие результаты. Если существует связь между данными, такими как шаги до и после приготовления и нарезки, и порядком английских слов, как нейронная сеть может изучить связь между данными? Вот где используется RNN.

Например, если есть число ABCD, необходимо предсказать следующее число E, и предсказание будет сделано в соответствии с предыдущим порядком ABCD, который называетсяобъем памяти. Прежде чем делать прогнозы, необходимо просмотреть предыдущие воспоминания, а также новые точки памяти на этом этапе и, наконец, вывести результат.Рекуррентная нейронная сеть (RNN) использует этот принцип.

Во-первых, давайте подумаем о том, как люди анализируют отношения или порядок вещей. Люди обычно помнят, что произошло раньше, чтобы помочь нам сделать выводы о последующем поведении, поэтому могут ли компьютеры также помнить, что произошло раньше?

При анализе data0 мы сохраняем результаты анализа в памяти, а затем при анализе data1 нейронная сеть (НС) будет генерировать новые воспоминания, но в это время новая память не связана со старой памятью, как показано на рисунке выше.В RNN мы просто будем вызывать старую память для анализа новой памяти.Если мы продолжим анализировать больше данных, NN соберет всю предыдущую память..

在这里插入图片描述

Ниже приведена типичная модель результатов RNN. В соответствии с моментами времени t-1, t и t + 1 каждый раз имеет разный x. Каждый расчет будет учитывать состояние предыдущего шага и x (t) этого шаг, а затем выведите значение y. В этой математической форме s (t) генерируется после каждого запуска RNN.Когда RNN хочет проанализировать x (t + 1), y (t + 1) в этот момент определяется s (t) и s (t + 1) Совместно созданный s(t) можно рассматривать как воспоминание о предыдущем шаге. Накопление нескольких нейронных сетей NN преобразуется в рекуррентную нейронную сеть, упрощенная схема которой показана в левой части следующего рисунка. Например, если предложения в последовательности состоят из 5 слов, то расширение сети по горизонтали будет иметь пять слоев нейронной сети, по одному на каждое слово.

在这里插入图片描述

Таким образом, вы можете использовать RNN, если ваши данные упорядочены, например, порядок человеческой речи, порядок телефонных номеров, порядок пикселей изображения, порядок букв ABC и т. д. RNN часто используется в обработке естественного языка, машинном переводе, распознавании речи, распознавании изображений и других областях.

2. Текстовая классификация

Классификация текстов предназначена для автоматической классификации и маркировки текстовых наборов в соответствии с определенной системой или стандартом классификации и относится к автоматической классификации, основанной на системе классификации. Классификацию текстов можно проследить до 1950-х годов, когда классификация текстов в основном осуществлялась экспертами, определяющими правила; в 1980-х появились экспертные системы, созданные инженерией знаний; в 1990-х — с помощью методов машинного обучения, путем искусственной инженерии признаков. и модель классификации мелкого слоя для классификации текста.В настоящее время для классификации текстов в основном используются векторы слов и глубокие нейронные сети.

在这里插入图片描述

Г-н Ню Яфэн резюмировал традиционный процесс классификации текстов, как показано на рисунке ниже. В традиционной классификации текстов в основном большинство методов машинного обучения применяются в области классификации текстов. в основном включает:

  • Naive Bayes

  • KNN

  • SVM

  • Методы класса коллекции

  • максимальная энтропия

  • Нейронные сети

在这里插入图片描述

Основной процесс классификации текста с использованием фреймворка Keras выглядит следующим образом:

  • Шаг 1: Предварительная обработка текста, сегментация слов->удаление стоп-слов->статистический выбор первых n слов в качестве характерных слов

  • Шаг 2. Создайте идентификаторы для каждого функционального слова.

  • Шаг 3. Преобразование текста в последовательность идентификаторов и отступ слева

  • Шаг 4: Перетасовка тренировочного набора

  • Шаг 5: Embedded Layer преобразует слова в векторы слов.

  • Шаг 6: Добавьте модель и постройте структуру нейронной сети

  • Шаг 7: Обучите модель

  • Шаг 8: Получите точность, отзыв, значение F1

Обратите внимание, что если вы используете TFIDF вместо векторов слов для представления документа, вы можете напрямую сгенерировать матрицу TFIDF и ввести ее в модель после сегментации слов. В этой статье для проведения экспериментов будет использоваться вектор слов и TFIDF.

Методы классификации текста глубокого обучения включают в себя:

  • Сверточная нейронная сеть (TextCNN)

  • Рекуррентная нейронная сеть (TextRNN)

  • TextRNN+Attention

  • TextRCNN(TextRNN+CNN)

Рекомендовать статью Ню Яфэна: Классификация текстов на основе Word2vec и CNN: обзор и практика

2. Классификация текста на основе традиционного байесовского алгоритма машинного обучения.

1. Мультиномиальная классификация текстов NB+TFIDF

Набор данных использует пользовательский текст г-на Цзи Цзивэя, всего 21 строку данных, включая 2 категории (мобильный телефон Xiaomi, каша Xiaomi). Основной процесс:

  • Получить данные набора данных и цель

  • Вызов библиотеки Jieba для сегментации китайских слов

  • Вычислить значение TF-IDF и преобразовать матрицу частоты слов в векторную матрицу TF-IDF

  • Задействуйте алгоритмы машинного обучения для обучения и прогнозирования

  • Оценка эксперимента и визуальный анализ

Полный код выглядит следующим образом:

# -*- coding: utf-8 -*-
"""
Created on Sat Mar 28 22:10:20 2020
@author: Eastmount CSDN
"""
from jieba import lcut

#--------------------------------载入数据及预处理-------------------------------
data = [
    [0, '小米粥是以小米作为主要食材熬制而成的粥,口味清淡,清香味,具有简单易制,健胃消食的特点'],
    [0, '煮粥时一定要先烧开水然后放入洗净后的小米'], 
    [0, '蛋白质及氨基酸、脂肪、维生素、矿物质'],
    [0, '小米是传统健康食品,可单独焖饭和熬粥'], 
    [0, '苹果,是水果中的一种'],
    [0, '粥的营养价值很高,富含矿物质和维生素,含钙量丰富,有助于代谢掉体内多余盐分'],
    [0, '鸡蛋有很高的营养价值,是优质蛋白质、B族维生素的良好来源,还能提供脂肪、维生素和矿物质'],
    [0, '这家超市的苹果都非常新鲜'], 
    [0, '在北方小米是主要食物之一,很多地区有晚餐吃小米粥的习俗'],
    [0, '小米营养价值高,营养全面均衡 ,主要含有碳水化合物'], 
    [0, '蛋白质及氨基酸、脂肪、维生素、盐分'],
    [1, '小米、三星、华为,作为安卓三大手机旗舰'], 
    [1, '别再管小米华为了!魅族手机再曝光:这次真的完美了'],
    [1, '苹果手机或将重陷2016年困境,但这次它无法再大幅提价了'], 
    [1, '三星想要继续压制华为,仅凭A70还不够'],
    [1, '三星手机屏占比将再创新高,超华为及苹果旗舰'], 
    [1, '华为P30、三星A70爆卖,斩获苏宁最佳手机营销奖'],
    [1, '雷军,用一张图告诉你:小米和三星的差距在哪里'], 
    [1, '小米米聊APP官方Linux版上线,适配深度系统'],
    [1, '三星刚刚更新了自家的可穿戴设备APP'], 
    [1, '华为、小米跨界并不可怕,可怕的打不破内心的“天花板”'],
]

#中文分析
X, Y = [' '.join(lcut(i[1])) for i in data], [i[0] for i in data]
print(X)
print(Y)
#['煮粥 时 一定 要 先烧 开水 然后 放入 洗净 后 的 小米', ...]

#--------------------------------------计算词频------------------------------------
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer

#将文本中的词语转换为词频矩阵
vectorizer = CountVectorizer()

#计算个词语出现的次数
X_data = vectorizer.fit_transform(X)
print(X_data)

#获取词袋中所有文本关键词
word = vectorizer.get_feature_names()
print('【查看单词】')
for w in word:
    print(w, end = " ")
else:
    print("\n")

#词频矩阵
print(X_data.toarray())

#将词频矩阵X统计成TF-IDF值
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(X_data)

#查看数据结构 tfidf[i][j]表示i类文本中的tf-idf权重
weight = tfidf.toarray()
print(weight)

#--------------------------------------数据分析------------------------------------
from sklearn.naive_bayes import MultinomialNB  
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(weight, Y)
print(len(X_train), len(X_test))
print(len(y_train), len(y_test))
print(X_train)

#调用MultinomialNB分类器  
clf = MultinomialNB().fit(X_train, y_train)
pre = clf.predict(X_test)
print("预测结果:", pre)
print("真实结果:", y_test)
print(classification_report(y_test, pre))

#--------------------------------------可视化分析------------------------------------
#降维绘制图形
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt

pca = PCA(n_components=2)
newData = pca.fit_transform(weight)
print(newData)
 
L1 = [n[0] for n in newData]
L2 = [n[1] for n in newData]
plt.scatter(L1, L2, c=Y, s=200)
plt.show()

Результат выглядит следующим образом:

  • Точность ===> 0,67 для 6 данных прогноза

Нарисуйте график, как показано ниже:

在这里插入图片描述

2. Классификация текстов GaussianNB+Word2Vec

Отличие этого метода от предыдущего заключается в том, что Word2Vec используется для вычисления вектора слов, каждая строка набора данных делится на слова, вычисляется вектор слов каждого характеристического слова, а затем преобразуется в матрицу векторов слов, например как 15 строк данных, каждая строка данных имеет 40 слов признаков, каждое слово признаков представлено 20-мерным вектором слов, а именно (15, 40, 20). В то же время, поскольку вектор слов имеет отрицательные числа, вместо алгоритма MultinomialNB необходимо использовать алгоритм GaussianNB.

Для Word2Vec см. предыдущую статью автора:[Искусственный интеллект Python] Девять. gensim word vector установка Word2Vec и вычисление сходства китайского короткого текста "Qing Yu Nian"

  • предложения: входящая последовательность набора данных (список списков токенов), значение по умолчанию — None

  • размер: размер вектора слова, значение по умолчанию 100

  • окно: максимальное расстояние между текущим словом и прогнозируемым словом в одном предложении, значение по умолчанию равно 5

  • Min_count: минимальная частота фильтрации слов, по умолчанию 5

  • worker: количество потоков, значение по умолчанию 3

  • sg: параметр модели, значение 0 для CBOW, 1 для skip-gram, значение по умолчанию 0

  • hs: параметр модели, его значение равно 0 для отрицательной выборки выборки, 1 для иерархического softmax, а значение по умолчанию равно 0.

  • отрицательный: количество отрицательных образцов, значение по умолчанию равно 5

  • ns_exponent: показатель степени, используемый для формирования отрицательных выборок, значение по умолчанию — 0,75.

  • COWAY_MEAN: параметр Context Word Vector, его значение равно 0 означает значение суммы вектора Слова контекста, значение 1 означает среднее значение вектора слов контекста, значение по умолчанию составляет 1

  • альфа: начальная скорость обучения, по умолчанию 0,025

  • min_alpha: минимальная скорость обучения, значение по умолчанию 0,0001.

Полный код выглядит следующим образом:

# -*- coding: utf-8 -*-
"""
Created on Sat Mar 28 22:10:20 2020
@author: Eastmount CSDN
"""
from jieba import lcut
from numpy import zeros
from gensim.models import Word2Vec
from sklearn.model_selection import train_test_split
from tensorflow.python.keras.preprocessing.sequence import pad_sequences

max_features = 20                  #词向量维度
maxlen = 40                        #序列最大长度

#--------------------------------载入数据及预处理-------------------------------
data = [
    [0, '小米粥是以小米作为主要食材熬制而成的粥,口味清淡,清香味,具有简单易制,健胃消食的特点'],
    [0, '煮粥时一定要先烧开水然后放入洗净后的小米'], 
    [0, '蛋白质及氨基酸、脂肪、维生素、矿物质'],
    [0, '小米是传统健康食品,可单独焖饭和熬粥'], 
    [0, '苹果,是水果中的一种'],
    [0, '粥的营养价值很高,富含矿物质和维生素,含钙量丰富,有助于代谢掉体内多余盐分'],
    [0, '鸡蛋有很高的营养价值,是优质蛋白质、B族维生素的良好来源,还能提供脂肪、维生素和矿物质'],
    [0, '这家超市的苹果都非常新鲜'], 
    [0, '在北方小米是主要食物之一,很多地区有晚餐吃小米粥的习俗'],
    [0, '小米营养价值高,营养全面均衡 ,主要含有碳水化合物'], 
    [0, '蛋白质及氨基酸、脂肪、维生素、盐分'],
    [1, '小米、三星、华为,作为安卓三大手机旗舰'], 
    [1, '别再管小米华为了!魅族手机再曝光:这次真的完美了'],
    [1, '苹果手机或将重陷2016年困境,但这次它无法再大幅提价了'], 
    [1, '三星想要继续压制华为,仅凭A70还不够'],
    [1, '三星手机屏占比将再创新高,超华为及苹果旗舰'], 
    [1, '华为P30、三星A70爆卖,斩获苏宁最佳手机营销奖'],
    [1, '雷军,用一张图告诉你:小米和三星的差距在哪里'], 
    [1, '小米米聊APP官方Linux版上线,适配深度系统'],
    [1, '三星刚刚更新了自家的可穿戴设备APP'], 
    [1, '华为、小米跨界并不可怕,可怕的打不破内心的“天花板”'],
]

#中文分析
X, Y = [lcut(i[1]) for i in data], [i[0] for i in data]

#划分训练集和预测集
X_train, X_test, y_train, y_test = train_test_split(X, Y)
#print(X_train)
print(len(X_train), len(X_test))
print(len(y_train), len(y_test))
"""['三星', '刚刚', '更新', '了', '自家', '的', '可', '穿戴', '设备', 'APP']"""

#--------------------------------Word2Vec词向量-------------------------------
word2vec = Word2Vec(X_train, size=max_features, min_count=1) #最大特征 最低过滤频次1
print(word2vec)

#映射特征词
w2i = {w:i for i, w in enumerate(word2vec.wv.index2word)}
print("【显示词语】")
print(word2vec.wv.index2word)
print(w2i)
"""['小米', '三星', '是', '维生素', '蛋白质', '及', 'APP', '氨基酸',..."""
"""{',': 0, '的': 1, '小米': 2, '、': 3, '华为': 4, ....}"""

#词向量计算
vectors = word2vec.wv.vectors
print("【词向量矩阵】")
print(vectors.shape)
print(vectors)

#自定义函数-获取词向量
def w2v(w):
    i = w2i.get(w)
    return vectors[i] if i else zeros(max_features)

#自定义函数-序列预处理
def pad(ls_of_words):
    a = [[w2v(i) for i in x] for x in ls_of_words]
    a = pad_sequences(a, maxlen, dtype='float')
    return a

#序列化处理 转换为词向量
X_train, X_test = pad(X_train), pad(X_test)
print(X_train.shape)
print(X_test.shape)
"""(15, 40, 20) 15个样本 40个特征 每个特征用20词向量表示"""

#拉直形状 (15, 40, 20)=>(15, 40*20) (6, 40, 20)=>(6, 40*20)
X_train = X_train.reshape(len(y_train), maxlen*max_features)
X_test = X_test.reshape(len(y_test), maxlen*max_features)
print(X_train.shape)
print(X_test.shape)

#--------------------------------建模与训练-------------------------------
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split

#调用GaussianNB分类器  
clf = GaussianNB().fit(X_train, y_train)
pre = clf.predict(X_test)
print("预测结果:", pre)
print("真实结果:", y_test)
print(classification_report(y_test, pre))

Результат выглядит следующим образом:

  • Точность ===> 0,83 для 6 данных прогноза

3. Keras реализует текстовую классификацию RNN

1. Набор данных IMDB и предварительная обработка последовательности

(1) набор данных IMDBФреймворк Keras предоставляет нам некоторые часто используемые встроенные наборы данных. Например, набор данных распознавания рукописного ввода MNIST в области распознавания изображений, набор данных imdb обзоров фильмов в области классификации текстов и так далее. Эти базы данных можно вызвать с помощью одной строки кода:

  • (trainX, trainY), (testX, testY) = imdb.load_data(path="imdb.npz", num_words=max_features)

Эти наборы данныхs3.amazonaws.com для скачивания, но иногда сайт нельзя использовать, нужно качать данные на локалку, а потом вызывать для анализа. Ссылка на облако Baidu набора данных Keras:

Автор помещает загруженные данные в папку C:\Users\Administrator.keras\datasets, как показано на следующем рисунке.

在这里插入图片描述

Набор данных представляет собой базу данных фильмов в Интернете (IMDb), онлайн-базу данных киноактеров, фильмов, телешоу, телезвезд и кинопродукции.

Данные и формат файла imdb.npz следующие:

[list([1, 14, 22, 16, 43, 530, 973, 1622, 1385, 65, 458, 4468, 66, 3941, 4, 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670, 2, 9, 35, 480, 284, 5, 150, 4, 172, ...])
 list([1, 194, 1153, 194, 8255, 78, 228, 5, 6, 1463, 4369, 5012, 134, 26, 4, 715, 8, 118, 1634, 14, 394, 20, 13, 119, 954, 189, 102, 5, 207, 110, 3103, 21, 14, 69, ...])
 list([1, 14, 47, 8, 30, 31, 7, 4, 249, 108, 7, 4, 5974, 54, 61, 369, 13, 71, 149, 14, 22, 112, 4, 2401, 311, 12, 16, 3711, 33, 75, 43, 1829, 296, 4, 86, 320, 35, ...])
 ...
 list([1, 11, 6, 230, 245, 6401, 9, 6, 1225, 446, 2, 45, 2174, 84, 8322, 4007, 21, 4, 912, 84, 14532, 325, 725, 134, 15271, 1715, 84, 5, 36, 28, 57, 1099, 21, 8, 140, ...])
 list([1, 1446, 7079, 69, 72, 3305, 13, 610, 930, 8, 12, 582, 23, 5, 16, 484, 685, 54, 349, 11, 4120, 2959, 45, 58, 1466, 13, 197, 12, 16, 43, 23, 2, 5, 62, 30, 145, ...])
 list([1, 17, 6, 194, 337, 7, 4, 204, 22, 45, 254, 8, 106, 14, 123, 4, 12815, 270, 14437, 5, 16923, 12255, 732, 2098, 101, 405, 39, 14, 1034, 4, 1310, 9, 115, 50, 305, ...])] train sequences

Каждый список представляет собой предложение, и каждое число в предложении представляет собой номер слова. Итак, как получить слово, соответствующее числу? На этом этапе вам нужно использовать файл imdb_word_index.json, формат которого следующий:

{"fawn": 34701, "tsukino": 52006,..., "paget": 18509, "expands": 20597}

Всего в формате "ключ-значение" хранится 88 584 слова. Ключ представляет слово, а значение представляет собой номер (слова). Чем выше частота слова (количество раз, когда слово появляется в корпусе), тем меньше число. Например, «the: 1» имеет наибольшее количество вхождений, и число равно 1.

(2) Предварительная обработка последовательностиВ процессе векторного преобразования глубокого обучения обычно требуется дополнение последовательности pad_sequences(). Его основное использование заключается в следующем:

keras.preprocessing.sequence.pad_sequences(
    sequences, 
	maxlen=None,
	dtype='int32',
	padding='pre',
	truncating='pre', 
	value=0.
	)

Смысл параметров следующий:

  • последовательности: двухуровневый вложенный список чисел с плавающей запятой или целых чисел

  • maxlen: нет или целое число, максимальная длина последовательности. Последовательности, превышающие эту длину, будут обрезаны, а последовательности меньше этой длины будут дополнены 0 в конце.

  • dtype: тип данных возвращаемого массива numpy

  • padding: pre или post, который определяет, добавлять ли 0 в начале или в конце последовательности, когда ее нужно заполнить 0

  • усечение: до или после, которое определяет, следует ли усекать с начала или с конца, когда последовательность должна быть усечена

  • значение: число с плавающей запятой, это значение заменит значение по умолчанию 0 заполняется во время заполнения

  • Возвращаемое значение представляет собой двумерный тензор длины maxlen.

Основное использование заключается в следующем:

from keras.preprocessing.sequence import pad_sequences

print(pad_sequences([[1, 2, 3], [1]], maxlen=2))
"""[[2 3] [0 1]]"""
print(pad_sequences([[1, 2, 3], [1]], maxlen=3, value=9))
"""[[1 2 3] [9 9 1]]"""

print(pad_sequences([[2,3,4]], maxlen=10))
"""[[0 0 0 0 0 0 0 2 3 4]]"""
print(pad_sequences([[1,2,3,4,5],[6,7]], maxlen=10))
"""[[0 0 0 0 0 1 2 3 4 5] [0 0 0 0 0 0 0 0 6 7]]"""

print(pad_sequences([[1, 2, 3], [1]], maxlen=2, padding='post'))
"""结束位置补: [[2 3] [1 0]]"""
print(pad_sequences([[1, 2, 3], [1]], maxlen=4, truncating='post'))
"""起始位置补: [[0 1 2 3] [0 0 0 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)

2. Обучение модели встраивания слов

На этом этапе мы будем тренироваться с помощью модели встраивания слов, Конкретный процесс включает в себя:

  • Импорт набора данных IMDB

  • Преобразование набора данных в последовательность

  • Создать встраиваемое слово вложение модели вложения

  • обучение нейронной сети

Полный код выглядит следующим образом:

# -*- coding: utf-8 -*-
"""
Created on Sat Mar 28 17:08:28 2020
@author: Eastmount CSDN
"""
from keras.datasets import imdb  #Movie Database
from keras.preprocessing import sequence
from keras.models import Sequential
from keras.layers import Dense, Flatten, Embedding

#-----------------------------------定义参数-----------------------------------
max_features = 20000       #按词频大小取样本前20000个词
input_dim = max_features   #词库大小 必须>=max_features
maxlen = 80                #句子最大长度
batch_size = 128           #batch数量
output_dim = 40            #词向量维度
epochs = 2                 #训练批次

#--------------------------------载入数据及预处理-------------------------------
#数据获取
(trainX, trainY), (testX, testY) = imdb.load_data(path="imdb.npz", num_words=max_features) 
print(trainX.shape, trainY.shape)  #(25000,) (25000,)
print(testX.shape, testY.shape)    #(25000,) (25000,)

#序列截断或补齐为等长
trainX = sequence.pad_sequences(trainX, maxlen=maxlen)
testX = sequence.pad_sequences(testX, maxlen=maxlen)
print('trainX shape:', trainX.shape)
print('testX shape:', testX.shape)

#------------------------------------创建模型------------------------------------
model = Sequential()

#词嵌入:词库大小、词向量维度、固定序列长度
model.add(Embedding(input_dim, output_dim, input_length=maxlen))

#平坦化: maxlen*output_dim
model.add(Flatten())

#输出层: 2分类
model.add(Dense(units=1, activation='sigmoid'))

#RMSprop优化器 二元交叉熵损失
model.compile('rmsprop', 'binary_crossentropy', ['acc'])

#训练
model.fit(trainX, trainY, batch_size, epochs)

#模型可视化
model.summary()

Результат выглядит следующим образом:

(25000,) (25000,)
(25000,) (25000,)
trainX shape: (25000, 80)
testX shape: (25000, 80)

Epoch 1/2
25000/25000 [==============================] - 2s 98us/step - loss: 0.6111 - acc: 0.6956
Epoch 2/2
25000/25000 [==============================] - 2s 69us/step - loss: 0.3578 - acc: 0.8549
Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding_2 (Embedding)      (None, 80, 40)            800000    
_________________________________________________________________
flatten_2 (Flatten)          (None, 3200)              0         
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 3201      
=================================================================
Total params: 803,201
Trainable params: 803,201
Non-trainable params: 0
_________________________________________________________________

​Матрица отображения показана на следующем рисунке:

在这里插入图片描述

3. Текстовая классификация RNN

Полный код для классификации текста по RNN в наборе данных фильмов IMDB показан ниже:

# -*- coding: utf-8 -*-
"""
Created on Sat Mar 28 17:08:28 2020
@author: Eastmount CSDN
"""
from keras.datasets import imdb  #Movie Database
from keras.preprocessing import sequence
from keras.models import Sequential
from keras.layers import Dense, Flatten, Embedding
from keras.layers import SimpleRNN

#-----------------------------------定义参数-----------------------------------
max_features = 20000       #按词频大小取样本前20000个词
input_dim = max_features   #词库大小 必须>=max_features
maxlen = 40                #句子最大长度
batch_size = 128           #batch数量
output_dim = 40            #词向量维度
epochs = 3                 #训练批次
units = 32                 #RNN神经元数量

#--------------------------------载入数据及预处理-------------------------------
#数据获取
(trainX, trainY), (testX, testY) = imdb.load_data(path="imdb.npz", num_words=max_features) 
print(trainX.shape, trainY.shape)  #(25000,) (25000,)
print(testX.shape, testY.shape)    #(25000,) (25000,)

#序列截断或补齐为等长
trainX = sequence.pad_sequences(trainX, maxlen=maxlen)
testX = sequence.pad_sequences(testX, maxlen=maxlen)
print('trainX shape:', trainX.shape)
print('testX shape:', testX.shape)

#-----------------------------------创建RNN模型-----------------------------------
model = Sequential()

#词嵌入 词库大小、词向量维度、固定序列长度
model.add(Embedding(input_dim, output_dim, input_length=maxlen))

#RNN Cell
model.add(SimpleRNN(units, return_sequences=True))   #返回序列全部结果
model.add(SimpleRNN(units, return_sequences=False))  #返回序列最尾结果

#输出层 2分类
model.add(Dense(units=1, activation='sigmoid'))

#模型可视化
model.summary()

#-----------------------------------建模与训练-----------------------------------
#激活神经网络 
model.compile(optimizer = 'rmsprop',              #RMSprop优化器
              loss = 'binary_crossentropy',       #二元交叉熵损失
              metrics = ['accuracy']              #计算误差或准确率
              )

#训练
history = model.fit(trainX, 
                    trainY, 
                    batch_size=batch_size, 
                    epochs=epochs, 
                    verbose=2,
                    validation_split=.1            #取10%样本作验证
                    )  

#-----------------------------------预测与可视化-----------------------------------
import matplotlib.pyplot as plt
accuracy = history.history['accuracy']
val_accuracy = history.history['val_accuracy']
plt.plot(range(epochs), accuracy)
plt.plot(range(epochs), val_accuracy)
plt.show()

Результат показан ниже, обучение трех эпох.

  • Точность обучающих данных ===> 0,9075

  • val_accuracy ===> 0,7844 для оценочных данных

Эпоху можно представить графически с помощью следующего рисунка.

(25000,) (25000,)
(25000,) (25000,)
trainX shape: (25000, 40)
testX shape: (25000, 40)
Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding_2 (Embedding)      (None, 40, 40)            800000    
_________________________________________________________________
simple_rnn_3 (SimpleRNN)     (None, 40, 32)            2336      
_________________________________________________________________
simple_rnn_4 (SimpleRNN)     (None, 32)                2080      
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 33        
=================================================================
Total params: 804,449
Trainable params: 804,449
Non-trainable params: 0
_________________________________________________________________

Train on 22500 samples, validate on 2500 samples
Epoch 1/3
 - 11s - loss: 0.5741 - accuracy: 0.6735 - val_loss: 0.4462 - val_accuracy: 0.7876
Epoch 2/3
 - 14s - loss: 0.3572 - accuracy: 0.8430 - val_loss: 0.4928 - val_accuracy: 0.7616
Epoch 3/3
 - 12s - loss: 0.2329 - accuracy: 0.9075 - val_loss: 0.5050 - val_accuracy: 0.7844

Нарисованные кривые точности и val_accuracy показаны на следующем рисунке:

  • loss: 0.2329 - accuracy: 0.9075 - val_loss: 0.5050 - val_accuracy: 0.7844

在这里插入图片描述

4. RNN реализует текстовую классификацию китайского набора данных.

1. Классификация текстов RNN+Word2Vector

Первый шаг — импортировать набор текстовых данных и преобразовать его в векторы слов.

data = [
    [0, '小米粥是以小米作为主要食材熬制而成的粥,口味清淡,清香味,具有简单易制,健胃消食的特点'],
    [0, '煮粥时一定要先烧开水然后放入洗净后的小米'], 
    [0, '蛋白质及氨基酸、脂肪、维生素、矿物质'],
    [0, '小米是传统健康食品,可单独焖饭和熬粥'], 
    [0, '苹果,是水果中的一种'],
    [0, '粥的营养价值很高,富含矿物质和维生素,含钙量丰富,有助于代谢掉体内多余盐分'],
    [0, '鸡蛋有很高的营养价值,是优质蛋白质、B族维生素的良好来源,还能提供脂肪、维生素和矿物质'],
    [0, '这家超市的苹果都非常新鲜'], 
    [0, '在北方小米是主要食物之一,很多地区有晚餐吃小米粥的习俗'],
    [0, '小米营养价值高,营养全面均衡 ,主要含有碳水化合物'], 
    [0, '蛋白质及氨基酸、脂肪、维生素、盐分'],
    [1, '小米、三星、华为,作为安卓三大手机旗舰'], 
    [1, '别再管小米华为了!魅族手机再曝光:这次真的完美了'],
    [1, '苹果手机或将重陷2016年困境,但这次它无法再大幅提价了'], 
    [1, '三星想要继续压制华为,仅凭A70还不够'],
    [1, '三星手机屏占比将再创新高,超华为及苹果旗舰'], 
    [1, '华为P30、三星A70爆卖,斩获苏宁最佳手机营销奖'],
    [1, '雷军,用一张图告诉你:小米和三星的差距在哪里'], 
    [1, '小米米聊APP官方Linux版上线,适配深度系统'],
    [1, '三星刚刚更新了自家的可穿戴设备APP'], 
    [1, '华为、小米跨界并不可怕,可怕的打不破内心的“天花板”'],
]

#中文分析
X, Y = [lcut(i[1]) for i in data], [i[0] for i in data]

#划分训练集和预测集
X_train, X_test, y_train, y_test = train_test_split(X, Y)
#print(X_train)
print(len(X_train), len(X_test))
print(len(y_train), len(y_test))
"""['三星', '刚刚', '更新', '了', '自家', '的', '可', '穿戴', '设备', 'APP']"""

#--------------------------------Word2Vec词向量-------------------------------
word2vec = Word2Vec(X_train, size=max_features, min_count=1) #最大特征 最低过滤频次1
print(word2vec)

#映射特征词
w2i = {w:i for i, w in enumerate(word2vec.wv.index2word)}
print("【显示词语】")
print(word2vec.wv.index2word)
print(w2i)
"""['小米', '三星', '是', '维生素', '蛋白质', '及', 'APP', '氨基酸',..."""
"""{',': 0, '的': 1, '小米': 2, '、': 3, '华为': 4, ....}"""

#词向量计算
vectors = word2vec.wv.vectors
print("【词向量矩阵】")
print(vectors.shape)
print(vectors)

#自定义函数-获取词向量
def w2v(w):
    i = w2i.get(w)
    return vectors[i] if i else zeros(max_features)

#自定义函数-序列预处理
def pad(ls_of_words):
    a = [[w2v(i) for i in x] for x in ls_of_words]
    a = pad_sequences(a, maxlen, dtype='float')
    return a

#序列化处理 转换为词向量
X_train, X_test = pad(X_train), pad(X_test)

На данный момент вывод следующий:

15 6
15 6
Word2Vec(vocab=120, size=20, alpha=0.025)
【显示词语】
[',', '的', '、', '小米', '三星', '是', '维生素', '蛋白质', '及',  
 '脂肪', '华为', '苹果', '可', 'APP', '氨基酸', '在', '手机', '旗舰', 
 '矿物质', '主要', '有', '小米粥', '作为', '刚刚', '更新', '设备', ...]
{',': 0, '的': 1, '、': 2, '小米': 3, '三星': 4, '是': 5, 
 '维生素': 6, '蛋白质': 7, '及': 8, '脂肪': 9, '和': 10, 
 '华为': 11, '苹果': 12, '可': 13, 'APP': 14, '氨基酸': 15, ...}
【词向量矩阵】
(120, 20)
[[ 0.00219526  0.00936278  0.00390177 ... -0.00422463  0.01543128
   0.02481441]
 [ 0.02346811 -0.01520025 -0.00563479 ... -0.01656673 -0.02222313
   0.00438196]
 [-0.02253242 -0.01633896 -0.02209039 ...  0.01301584 -0.01016752
   0.01147605]
 ...
 [ 0.01793107  0.01912305 -0.01780855 ... -0.00109831  0.02460653
  -0.00023512]
 [-0.00599797  0.02155897 -0.01874896 ...  0.00149929  0.00200266
   0.00988515]
 [ 0.0050361  -0.00848463 -0.0235001  ...  0.01531716 -0.02348576
   0.01051775]]

Второй шаг — установить структуру нейронной сети RNN, использовать модель Bi-GRU, а также провести обучение и прогнозирование.

#--------------------------------建模与训练-------------------------------
model = Sequential()

#双向RNN
model.add(Bidirectional(GRU(units), input_shape=(maxlen, max_features)))  

#输出层 2分类
model.add(Dense(units=1, activation='sigmoid'))

#模型可视化
model.summary()

#激活神经网络 
model.compile(optimizer = 'rmsprop',              #RMSprop优化器
              loss = 'binary_crossentropy',       #二元交叉熵损失
              metrics = ['acc']                   #计算误差或准确率
              )

#训练
history = model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, 
                    verbose=verbose, validation_data=(X_test, y_test))

#----------------------------------预测与可视化------------------------------
#预测
score = model.evaluate(X_test, y_test, batch_size=batch_size)
print('test loss:', score[0])
print('test accuracy:', score[1])

#可视化
acc = history.history['acc']
val_acc = history.history['val_acc']

# 设置类标
plt.xlabel("Iterations")
plt.ylabel("Accuracy")

#绘图
plt.plot(range(epochs), acc, "bo-", linewidth=2, markersize=12, label="accuracy")
plt.plot(range(epochs), val_acc, "gs-", linewidth=2, markersize=12, label="val_accuracy")
plt.legend(loc="upper left")
plt.title("RNN-Word2vec")
plt.show()

Результат показан на рисунке ниже, а значения точности и val_accuracy оказались очень неудовлетворительными. Как это решить?

在这里插入图片描述

Модель нейронной сети и результаты обучения Epoch показаны на следующем рисунке:

  • test loss: 0.7160684466362

  • test accuracy: 0.33333334

在这里插入图片描述

Вот еще один пункт знаний — Ранняя остановка. EarlyStopping — это тип обратных вызовов, обратные вызовы используются для указания, какая конкретная операция выполняется в начале и в конце каждой эпохи. В обратных вызовах есть несколько заданных интерфейсов, которые можно использовать напрямую, например, acc, val_acc, loss и val_loss. EarlyStopping — это обратный вызов, используемый для остановки обучения заранее, который может остановить продолжение обучения, когда потери в обучающем наборе не уменьшаются (то есть степень уменьшения меньше определенного порога). В приведенной выше программе, когда наши потери не уменьшаются, мы можем вызывать обратные вызовы, чтобы остановить обучение. рекомендуемая статья:[Глубокое обучение] Ранняя остановка использования и навыков keras - zwqjoy

Наконец, приведен полный код для этой части:

# -*- coding: utf-8 -*-
"""
Created on Sat Mar 28 22:10:20 2020
@author: Eastmount CSDN
"""
from jieba import lcut
from numpy import zeros
import matplotlib.pyplot as plt
from gensim.models import Word2Vec
from sklearn.model_selection import train_test_split
from tensorflow.python.keras.preprocessing.sequence import pad_sequences
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense, GRU, Bidirectional
from tensorflow.python.keras.callbacks import EarlyStopping

#-----------------------------------定义参数----------------------------------
max_features = 20                  #词向量维度
units = 30                         #RNN神经元数量
maxlen = 40                        #序列最大长度
epochs = 9                         #训练最大轮数
batch_size = 12                    #每批数据量大小
verbose = 1                        #训练过程展示
patience = 1                       #没有进步的训练轮数

callbacks = [EarlyStopping('val_acc', patience=patience)]

#--------------------------------载入数据及预处理-------------------------------
data = [
    [0, '小米粥是以小米作为主要食材熬制而成的粥,口味清淡,清香味,具有简单易制,健胃消食的特点'],
    [0, '煮粥时一定要先烧开水然后放入洗净后的小米'], 
    [0, '蛋白质及氨基酸、脂肪、维生素、矿物质'],
    [0, '小米是传统健康食品,可单独焖饭和熬粥'], 
    [0, '苹果,是水果中的一种'],
    [0, '粥的营养价值很高,富含矿物质和维生素,含钙量丰富,有助于代谢掉体内多余盐分'],
    [0, '鸡蛋有很高的营养价值,是优质蛋白质、B族维生素的良好来源,还能提供脂肪、维生素和矿物质'],
    [0, '这家超市的苹果都非常新鲜'], 
    [0, '在北方小米是主要食物之一,很多地区有晚餐吃小米粥的习俗'],
    [0, '小米营养价值高,营养全面均衡 ,主要含有碳水化合物'], 
    [0, '蛋白质及氨基酸、脂肪、维生素、盐分'],
    [1, '小米、三星、华为,作为安卓三大手机旗舰'], 
    [1, '别再管小米华为了!魅族手机再曝光:这次真的完美了'],
    [1, '苹果手机或将重陷2016年困境,但这次它无法再大幅提价了'], 
    [1, '三星想要继续压制华为,仅凭A70还不够'],
    [1, '三星手机屏占比将再创新高,超华为及苹果旗舰'], 
    [1, '华为P30、三星A70爆卖,斩获苏宁最佳手机营销奖'],
    [1, '雷军,用一张图告诉你:小米和三星的差距在哪里'], 
    [1, '小米米聊APP官方Linux版上线,适配深度系统'],
    [1, '三星刚刚更新了自家的可穿戴设备APP'], 
    [1, '华为、小米跨界并不可怕,可怕的打不破内心的“天花板”'],
]

#中文分析
X, Y = [lcut(i[1]) for i in data], [i[0] for i in data]

#划分训练集和预测集
X_train, X_test, y_train, y_test = train_test_split(X, Y)
#print(X_train)
print(len(X_train), len(X_test))
print(len(y_train), len(y_test))
"""['三星', '刚刚', '更新', '了', '自家', '的', '可', '穿戴', '设备', 'APP']"""

#--------------------------------Word2Vec词向量-------------------------------
word2vec = Word2Vec(X_train, size=max_features, min_count=1) #最大特征 最低过滤频次1
print(word2vec)

#映射特征词
w2i = {w:i for i, w in enumerate(word2vec.wv.index2word)}
print("【显示词语】")
print(word2vec.wv.index2word)
print(w2i)
"""['小米', '三星', '是', '维生素', '蛋白质', '及', 'APP', '氨基酸',..."""
"""{',': 0, '的': 1, '小米': 2, '、': 3, '华为': 4, ....}"""

#词向量计算
vectors = word2vec.wv.vectors
print("【词向量矩阵】")
print(vectors.shape)
print(vectors)

#自定义函数-获取词向量
def w2v(w):
    i = w2i.get(w)
    return vectors[i] if i else zeros(max_features)

#自定义函数-序列预处理
def pad(ls_of_words):
    a = [[w2v(i) for i in x] for x in ls_of_words]
    a = pad_sequences(a, maxlen, dtype='float')
    return a

#序列化处理 转换为词向量
X_train, X_test = pad(X_train), pad(X_test)

#--------------------------------建模与训练-------------------------------
model = Sequential()

#双向RNN
model.add(Bidirectional(GRU(units), input_shape=(maxlen, max_features)))  

#输出层 2分类
model.add(Dense(units=1, activation='sigmoid'))

#模型可视化
model.summary()

#激活神经网络 
model.compile(optimizer = 'rmsprop',              #RMSprop优化器
              loss = 'binary_crossentropy',       #二元交叉熵损失
              metrics = ['acc']                   #计算误差或准确率
              )

#训练
history = model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, 
                    verbose=verbose, validation_data=(X_test, y_test))

#----------------------------------预测与可视化------------------------------
#预测
score = model.evaluate(X_test, y_test, batch_size=batch_size)
print('test loss:', score[0])
print('test accuracy:', score[1])

#可视化
acc = history.history['acc']
val_acc = history.history['val_acc']

# 设置类标
plt.xlabel("Iterations")
plt.ylabel("Accuracy")

#绘图
plt.plot(range(epochs), acc, "bo-", linewidth=2, markersize=12, label="accuracy")
plt.plot(range(epochs), val_acc, "gs-", linewidth=2, markersize=12, label="val_accuracy")
plt.legend(loc="upper left")
plt.title("RNN-Word2vec")
plt.show()

2. Классификация текста LSTM+Word2Vec

Далее мы используем LSTM и Word2Vec для классификации текста. Структура всей нейронной сети очень проста: первый слой — это слой встраивания, который преобразует слова в тексте в векторы, затем проходит через слой слоя LSTM, используя скрытое состояние последнего момента в LSTM; Завершите строительство всей сети.

Обратите внимание на преобразование формы матрицы.

  • X_train = X_train.reshape(len(y_train), maxlen*max_features)

  • X_test = X_test.reshape(len(y_test), maxlen*max_features)

Полный код выглядит следующим образом:

# -*- coding: utf-8 -*-
"""
Created on Sat Mar 28 22:10:20 2020
@author: Eastmount CSDN
"""
from jieba import lcut
from numpy import zeros
import matplotlib.pyplot as plt
from gensim.models import Word2Vec
from sklearn.model_selection import train_test_split
from tensorflow.python.keras.preprocessing.sequence import pad_sequences
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense, LSTM, GRU, Embedding
from tensorflow.python.keras.callbacks import EarlyStopping

#-----------------------------------定义参数----------------------------------
max_features = 20                  #词向量维度
units = 30                         #RNN神经元数量
maxlen = 40                        #序列最大长度
epochs = 9                         #训练最大轮数
batch_size = 12                    #每批数据量大小
verbose = 1                        #训练过程展示
patience = 1                       #没有进步的训练轮数

callbacks = [EarlyStopping('val_acc', patience=patience)]

#--------------------------------载入数据及预处理-------------------------------
data = [
    [0, '小米粥是以小米作为主要食材熬制而成的粥,口味清淡,清香味,具有简单易制,健胃消食的特点'],
    [0, '煮粥时一定要先烧开水然后放入洗净后的小米'], 
    [0, '蛋白质及氨基酸、脂肪、维生素、矿物质'],
    [0, '小米是传统健康食品,可单独焖饭和熬粥'], 
    [0, '苹果,是水果中的一种'],
    [0, '粥的营养价值很高,富含矿物质和维生素,含钙量丰富,有助于代谢掉体内多余盐分'],
    [0, '鸡蛋有很高的营养价值,是优质蛋白质、B族维生素的良好来源,还能提供脂肪、维生素和矿物质'],
    [0, '这家超市的苹果都非常新鲜'], 
    [0, '在北方小米是主要食物之一,很多地区有晚餐吃小米粥的习俗'],
    [0, '小米营养价值高,营养全面均衡 ,主要含有碳水化合物'], 
    [0, '蛋白质及氨基酸、脂肪、维生素、盐分'],
    [1, '小米、三星、华为,作为安卓三大手机旗舰'], 
    [1, '别再管小米华为了!魅族手机再曝光:这次真的完美了'],
    [1, '苹果手机或将重陷2016年困境,但这次它无法再大幅提价了'], 
    [1, '三星想要继续压制华为,仅凭A70还不够'],
    [1, '三星手机屏占比将再创新高,超华为及苹果旗舰'], 
    [1, '华为P30、三星A70爆卖,斩获苏宁最佳手机营销奖'],
    [1, '雷军,用一张图告诉你:小米和三星的差距在哪里'], 
    [1, '小米米聊APP官方Linux版上线,适配深度系统'],
    [1, '三星刚刚更新了自家的可穿戴设备APP'], 
    [1, '华为、小米跨界并不可怕,可怕的打不破内心的“天花板”'],
]

#中文分析
X, Y = [lcut(i[1]) for i in data], [i[0] for i in data]

#划分训练集和预测集
X_train, X_test, y_train, y_test = train_test_split(X, Y)
#print(X_train)
print(len(X_train), len(X_test))
print(len(y_train), len(y_test))
"""['三星', '刚刚', '更新', '了', '自家', '的', '可', '穿戴', '设备', 'APP']"""

#--------------------------------Word2Vec词向量-------------------------------
word2vec = Word2Vec(X_train, size=max_features, min_count=1) #最大特征 最低过滤频次1
print(word2vec)

#映射特征词
w2i = {w:i for i, w in enumerate(word2vec.wv.index2word)}
print("【显示词语】")
print(word2vec.wv.index2word)
print(w2i)
"""['小米', '三星', '是', '维生素', '蛋白质', '及', 'APP', '氨基酸',..."""
"""{',': 0, '的': 1, '小米': 2, '、': 3, '华为': 4, ....}"""

#词向量计算
vectors = word2vec.wv.vectors
print("【词向量矩阵】")
print(vectors.shape)
print(vectors)

#自定义函数-获取词向量
def w2v(w):
    i = w2i.get(w)
    return vectors[i] if i else zeros(max_features)

#自定义函数-序列预处理
def pad(ls_of_words):
    a = [[w2v(i) for i in x] for x in ls_of_words]
    a = pad_sequences(a, maxlen, dtype='float')
    return a

#序列化处理 转换为词向量
X_train, X_test = pad(X_train), pad(X_test)
print(X_train.shape)
print(X_test.shape)
"""(15, 40, 20) 15个样本 40个特征 每个特征用20词向量表示"""

#拉直形状 (15, 40, 20)=>(15, 40*20) (6, 40, 20)=>(6, 40*20)
X_train = X_train.reshape(len(y_train), maxlen*max_features)
X_test = X_test.reshape(len(y_test), maxlen*max_features)

#--------------------------------建模与训练-------------------------------
model = Sequential()

#构建Embedding层 128代表Embedding层的向量维度
model.add(Embedding(max_features, 128))

#构建LSTM层
model.add(LSTM(128, dropout=0.2, recurrent_dropout=0.2))

#构建全连接层
#注意上面构建LSTM层时只会得到最后一个节点的输出,如果需要输出每个时间点的结果需将return_sequences=True
model.add(Dense(units=1, activation='sigmoid'))

#模型可视化
model.summary()

#激活神经网络 
model.compile(optimizer = 'rmsprop',              #RMSprop优化器
              loss = 'binary_crossentropy',       #二元交叉熵损失
              metrics = ['acc']                   #计算误差或准确率
              )

#训练
history = model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, 
                    verbose=verbose, validation_data=(X_test, y_test))

#----------------------------------预测与可视化------------------------------
#预测
score = model.evaluate(X_test, y_test, batch_size=batch_size)
print('test loss:', score[0])
print('test accuracy:', score[1])

#可视化
acc = history.history['acc']
val_acc = history.history['val_acc']

# 设置类标
plt.xlabel("Iterations")
plt.ylabel("Accuracy")

#绘图
plt.plot(range(epochs), acc, "bo-", linewidth=2, markersize=12, label="accuracy")
plt.plot(range(epochs), val_acc, "gs-", linewidth=2, markersize=12, label="val_accuracy")
plt.legend(loc="upper left")
plt.title("LSTM-Word2vec")
plt.show()

Результат показан ниже, но он все еще не идеален.

  • test loss: 0.712007462978363

  • test accuracy: 0.33333334

Соответствующий график показан ниже.

在这里插入图片描述

3. Текстовая классификация LSTM+TFIDF

В то же время дополнить код классификации текстов LSTM+TFIDF.

# -*- coding: utf-8 -*-
"""
Created on Sat Mar 28 22:10:20 2020
@author: Eastmount CSDN
"""
from jieba import lcut
from numpy import zeros
import matplotlib.pyplot as plt
from gensim.models import Word2Vec
from sklearn.model_selection import train_test_split
from tensorflow.python.keras.preprocessing.sequence import pad_sequences
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense, LSTM, GRU, Embedding
from tensorflow.python.keras.callbacks import EarlyStopping

#-----------------------------------定义参数----------------------------------
max_features = 20                  #词向量维度
units = 30                         #RNN神经元数量
maxlen = 40                        #序列最大长度
epochs = 9                         #训练最大轮数
batch_size = 12                    #每批数据量大小
verbose = 1                        #训练过程展示
patience = 1                       #没有进步的训练轮数

callbacks = [EarlyStopping('val_acc', patience=patience)]

#--------------------------------载入数据及预处理-------------------------------
data = [
    [0, '小米粥是以小米作为主要食材熬制而成的粥,口味清淡,清香味,具有简单易制,健胃消食的特点'],
    [0, '煮粥时一定要先烧开水然后放入洗净后的小米'], 
    [0, '蛋白质及氨基酸、脂肪、维生素、矿物质'],
    [0, '小米是传统健康食品,可单独焖饭和熬粥'], 
    [0, '苹果,是水果中的一种'],
    [0, '粥的营养价值很高,富含矿物质和维生素,含钙量丰富,有助于代谢掉体内多余盐分'],
    [0, '鸡蛋有很高的营养价值,是优质蛋白质、B族维生素的良好来源,还能提供脂肪、维生素和矿物质'],
    [0, '这家超市的苹果都非常新鲜'], 
    [0, '在北方小米是主要食物之一,很多地区有晚餐吃小米粥的习俗'],
    [0, '小米营养价值高,营养全面均衡 ,主要含有碳水化合物'], 
    [0, '蛋白质及氨基酸、脂肪、维生素、盐分'],
    [1, '小米、三星、华为,作为安卓三大手机旗舰'], 
    [1, '别再管小米华为了!魅族手机再曝光:这次真的完美了'],
    [1, '苹果手机或将重陷2016年困境,但这次它无法再大幅提价了'], 
    [1, '三星想要继续压制华为,仅凭A70还不够'],
    [1, '三星手机屏占比将再创新高,超华为及苹果旗舰'], 
    [1, '华为P30、三星A70爆卖,斩获苏宁最佳手机营销奖'],
    [1, '雷军,用一张图告诉你:小米和三星的差距在哪里'], 
    [1, '小米米聊APP官方Linux版上线,适配深度系统'],
    [1, '三星刚刚更新了自家的可穿戴设备APP'], 
    [1, '华为、小米跨界并不可怕,可怕的打不破内心的“天花板”'],
]

#中文分词
X, Y = [' '.join(lcut(i[1])) for i in data], [i[0] for i in data]
print(X)
print(Y)
#['煮粥 时 一定 要 先烧 开水 然后 放入 洗净 后 的 小米', ...]

#--------------------------------------计算词频------------------------------------
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer

#将文本中的词语转换为词频矩阵
vectorizer = CountVectorizer()

#计算个词语出现的次数
X_data = vectorizer.fit_transform(X)
print(X_data)

#获取词袋中所有文本关键词
word = vectorizer.get_feature_names()
print('【查看单词】')
for w in word:
    print(w, end = " ")
else:
    print("\n")

#词频矩阵
print(X_data.toarray())

#将词频矩阵X统计成TF-IDF值
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(X_data)

#查看数据结构 tfidf[i][j]表示i类文本中的tf-idf权重
weight = tfidf.toarray()
print(weight)

#数据集划分
X_train, X_test, y_train, y_test = train_test_split(weight, Y)
print(X_train.shape, X_test.shape)
print(len(y_train), len(y_test))
#(15, 117) (6, 117) 15 6

#--------------------------------建模与训练-------------------------------
model = Sequential()

#构建Embedding层 128代表Embedding层的向量维度
model.add(Embedding(max_features, 128))

#构建LSTM层
model.add(LSTM(128, dropout=0.2, recurrent_dropout=0.2))

#构建全连接层
#注意上面构建LSTM层时只会得到最后一个节点的输出,如果需要输出每个时间点的结果需将return_sequences=True
model.add(Dense(units=1, activation='sigmoid'))

#模型可视化
model.summary()

#激活神经网络 
model.compile(optimizer = 'rmsprop',              #RMSprop优化器
              loss = 'binary_crossentropy',       #二元交叉熵损失
              metrics = ['acc']                   #计算误差或准确率
              )

#训练
history = model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, 
                    verbose=verbose, validation_data=(X_test, y_test))

#----------------------------------预测与可视化------------------------------
#预测
score = model.evaluate(X_test, y_test, batch_size=batch_size)
print('test loss:', score[0])
print('test accuracy:', score[1])

#可视化
acc = history.history['acc']
val_acc = history.history['val_acc']

# 设置类标
plt.xlabel("Iterations")
plt.ylabel("Accuracy")

#绘图
plt.plot(range(epochs), acc, "bo-", linewidth=2, markersize=12, label="accuracy")
plt.plot(range(epochs), val_acc, "gs-", linewidth=2, markersize=12, label="val_accuracy")
plt.legend(loc="upper left")
plt.title("LSTM-TFIDF")
plt.show()

Вывод выглядит следующим образом:

  • test loss: 0.7694947719573975

  • test accuracy: 0.33333334

Соответствующие графики выглядят следующим образом:

在这里插入图片描述

4. Сравнительный анализ машинного обучения и глубокого обучения

В итоге мы провели простое сравнение и обнаружили, что машинное обучение лучше, чем глубокое. Почему? Что мы можем сделать, чтобы улучшить?

  • Мультиномиальный NB+TFIDF: точность теста = 0,67.

  • GaussianNB+Word2Vec: точность теста = 0,83

  • RNN+Word2Vector: точность теста = 0,33333334

  • LSTM+Word2Vec: точность теста = 0,33333334

  • Lstm + tfidf: точность тестирования = 0.33333334

Автор делает простой анализ на основе статей больших парней и собственного опыта, причины таковы:

  • ОдинИз-за предварительной обработки набора данных приведенный выше код не фильтрует стоп-слова, а большое количество знаков препинания и стоп-слов влияет на эффект классификации текста. В то же время настройка размерности вектора слов также нуждается в отладке.

  • два этоПричина размера набора данных. В случае небольшого количества данных рекомендуется CNN, а переобучение RNN заставит вас плакать без слез. Если объем данных большой, возможно, RNN будет работать лучше. В последние годы хорошим выбором для инноваций являются RLSTM и RCNN. Но если это просто приложение, обычные методы машинного обучения достаточно хороши (особенно наборы новостных данных), а если учесть временные затраты, байесовский, несомненно, лучший выбор.

  • ТретийCNN и RNN имеют разное применение. CNN хороша в изучении и захвате пространственных характеристик, а RNN хороша в захвате характеристик временных рядов. С точки зрения структуры RNN лучше. Для основных задач NLP, таких как перевод и генерация текста, введение seq2seq (двух независимых RNN) превзошло многие предыдущие тесты. Введение Attention должно решить проблему длинных предложений. Его суть состоит в том, чтобы добавить дополнительный softmax для изучения отношения сопоставления между словами и словами. Это немного похоже на подключаемый модуль хранилища. Его основной источник взят из статьи под названием " нейронная машина Тьюринга».

  • ЧетыреРазные наборы данных адаптируются к разным методам, и у каждого метода есть свои сильные стороны. Некоторые GRU анализа настроений лучше, чем CNN, и CNN могут иметь преимущества в соревнованиях по классификации новостей и классификации текстов. Преимущество CNN заключается в скорости.По сути, на больших данных CNN может увеличить параметры, соответствовать большему количеству частот местных фраз и получить лучшие результаты. Если вы хотите сделать систему, и у двух алгоритмов есть свои сильные стороны, пришло время для появления ансамбля.

  • пятьВ области классификации тональности текста ГРУ лучше, чем CNN, и с увеличением длины предложения это преимущество ГРУ будет еще больше увеличиваться. Когда классификация тональности предложения определяется всем предложением, GRU будет легче правильно классифицировать, а когда классификация тональности предложения определяется несколькими локальными ключевыми фразами, CNN будет легче правильно классифицировать.

Короче говоря, в реальном эксперименте мы пытаемся выбрать алгоритм, подходящий для нашего набора данных, который также является частью эксперимента.Нам нужно сравнить различные алгоритмы, различные параметры и различные модели обучения, чтобы найти лучший алгоритм. В последующем автор продолжит изучение таких алгоритмов, как TextCNN, Attention, BiLSTM, GAN и т. д., и надеется добиться прогресса со всеми.

Ссылки и рекомендуемые статьи:Для китайской классификации длинных текстов лучше CNN или RNN? - Знаю почти

5. Резюме

Пишите сюда, эта статья окончена. Я надеюсь, что это будет полезно для вас, и читатели могут указать на любые недостатки или ошибки в статье. Эти эксперименты являются одними из распространенных проблем, которые я решаю в своем диссертационном исследовании или оценке проекта.Я надеюсь, что читатели воспримут эти проблемы и глубоко задумаются, исходя из своих собственных потребностей, и я надеюсь, что каждый сможет применить то, что он узнал.

Короче говоря, в этой статье реализуется случай обучения классификации текста RNN с помощью Keras и подробно представлены основные знания о рекуррентной нейронной сети и сравнение с машинным обучением. Наконец, как новичок в области искусственного интеллекта, я надеюсь, что смогу продолжать совершенствоваться и углубляться, а затем применять его к распознаванию изображений, сетевой безопасности, враждебным образцам и другим областям, а также помогать всем писать простые академические статьи.

Спасибо за встречу со всеми вами в HUAWEI CLOUD! Я надеюсь расти вместе с вами в сообществе HUAWEI CLOUD. Оригинальный адрес:blog.CSDN.net/east mount/Ах…(Автор: Nazhang House Eastmount, 9 ноября 2021 г., ночь в Ухане)

использованная литература:

Еще раз спасибо за вклад справочных предшественников и преподавателей, а также ссылается на ряд статей автора о искусственном интеллекте Python и анализ данных. Пожалуйста, загрузите исходный код на Github.

[1] Наборы данных Keras imdb и MNIST не могут быть загружены для решения проблем - требуется программист

[2] Подробный пример официального веб-сайта 4.42 (imdb.py) - примечания к исследованию keras четыре - wyx100

[3] Классификация текстов Кераса

[4] Текстовая классификация TextCNN (реализована keras) - настоятельно рекомендую статью преподавателя Asia-Lee

[5] Внедрение классификации текста Keras - сильный толчок к знакомству со статьей учителя Ван Илей.

[6 ]Введение в обработку естественного языка (2) — Keras реализует классификацию текста заголовков новостей BiLSTM+Attention — ilivecode

[7] Использование глубокого обучения (CNN RNN Attention) для решения крупномасштабных задач классификации текста — обзор и практика — Zhihu Qingsong

[8] Классификация текстов на основе Word2vec и CNN: обзор и практика — Ню Яфэн Серена

[9] GitHub.com/КРАС-команда/…

[10] [Глубокое обучение] Ранняя остановка использования и навыков keras - zwqjoy

[11] Почему у глубокого обучения есть явление, когда точность проверки выше, чем точность обучения? - ИКОЗ

[12] Keras реализует классификацию текста CNN - vivian_ll

[13] Боевая классификация текста Кераса (вкл.) - weixin_34351321

[14] Для китайской классификации длинных текстов лучше CNN или RNN? - Знаю почти

Нажмите «Подписаться», чтобы впервые узнать о новых технологиях HUAWEI CLOUD~