自然语言处理文本分类实战---慕课学习笔记

自然语言处理文本分类实战

自然语言处理文本分类实战---慕课学习笔记_第1张图片

第一章 文本分类应用场景介绍

一、文本分类任务描述:input—model—output

自然语言处理文本分类实战---慕课学习笔记_第2张图片

二、应用场景:

  1. 评论数据

    自然语言处理文本分类实战---慕课学习笔记_第3张图片

    2.情感分析

    自然语言处理文本分类实战---慕课学习笔记_第4张图片

    3.意图识别

    自然语言处理文本分类实战---慕课学习笔记_第5张图片

    4.进阶应用:

自然语言处理文本分类实战---慕课学习笔记_第6张图片 自然语言处理文本分类实战---慕课学习笔记_第7张图片

第二章 文本表征知识

2.1文本表征介绍

2.1.1、文本表示:(转化成电脑能够识别的文字)
自然语言处理文本分类实战---慕课学习笔记_第8张图片
2.1.2、文本表示的方法
自然语言处理文本分类实战---慕课学习笔记_第9张图片

2.2 One Hot编码(独热编码)

2.2.1、工作流程
自然语言处理文本分类实战---慕课学习笔记_第10张图片
  1. 将句子分词
  2. 构建词表并编码
  3. 将编码组成一个数字序列
  4. One Hot编码(用矩阵来代表一句话的输入)
  5. 将上述矩阵用来建模、训练、构建文本分类模型
2.2.2、缺点
自然语言处理文本分类实战---慕课学习笔记_第11张图片
2.2.3、实战
  1. 预料准备
  2. 手动实现
  3. Sklearn实现
# One Hot编码(独热编码)实战
import numpy as np

# 0:语料准备
corpus = ['这 是 第一个 文档',
          '这是 第二个 文档',
          '这是 最后 一个 文档',
          '现在 没有 文档 了']

# 1:手动实现
# 词袋
words = []
for corpu in corpus:
    words.extend(corpu.split())
# 词的列表(去重)
word_list = list(set(words))
# 生成字典
word_dct = {word: index for index, word in enumerate(word_list)}
# 词典大小
vocab_size = len(word_dct)
# print(word_dct)
# {'了': 0, '这是': 1, '这': 2, '最后': 3, '第二个': 4, '第一个': 5, '一个': 6, '是': 7, '没有': 8, '文档': 9, '现在': 10}


def get_one_hot(index):
    # 获得一个one hot编码
    one_hot = [0 for _ in range(vocab_size)]
    one_hot[index] = 1
    return np.array(one_hot)


# print(get_one_hot(1))  # [0 1 0 0 0 0 0 0 0 0 0]

# 第一句话
indexs = [word_dct[word] for word in corpus[0].split()]
# 转换成one hot
one_hot_np = np.array([get_one_hot(index) for index in indexs])
# print(one_hot_np)
'''
[[0 0 1 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 1 0 0 0]
 [0 0 0 0 0 1 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 1 0]]
'''

# 2 Sklearn实现
from sklearn.preprocessing import LabelBinarizer
# 初始化编码器
lb = LabelBinarizer()
# 将所有分好的的词都放进去
lb.fit(words)
lb.classes_

# 初始化句子
sentence = corpus[0].split()
print(sentence)
# ['这', '是', '第一个', '文档']
LB = lb.transform(sentence)
print(LB)
'''
[[0 0 0 0 0 0 0 0 0 1 0]
 [0 0 0 1 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 1 0 0 0]
 [0 0 1 0 0 0 0 0 0 0 0]]
'''
# 解码
LB_inverse = lb.inverse_transform(LB)
print(LB_inverse)
# ['这' '是' '第一个' '文档']

2.3 TF-IDF(词频-逆文件频率)

2.3.1 简介

1、词频(TF)

自然语言处理文本分类实战---慕课学习笔记_第12张图片

2 、逆文件频率(IDF)

自然语言处理文本分类实战---慕课学习笔记_第13张图片

3 、TF-IDF

自然语言处理文本分类实战---慕课学习笔记_第14张图片

4、TF-IDF的缺点

自然语言处理文本分类实战---慕课学习笔记_第15张图片
2.3.2 TF-IDF实战
# 词频-逆文件频率
# 0:语料准备
corpus = ['这 是 第一个 文档',
          '这是 第二个 文档',
          '这是 最后 一个 文档',
          '现在 没有 文档 了 文档']
# 1、手动实现
# 1.1 词袋统计
words_list = []
for corpu in corpus:
    words_list.append(corpu.split())
print(words_list)
# [['这', '是', '第一个', '文档'], ['这是', '第二个', '文档'], ['这是', '最后', '一个', '文档'], ['现在', '没有', '文档', '了', '文档']]

# 1.2统计词频
from collections import Counter
count_list = []
for words in words_list:
    count = Counter(words)
    count_list.append(count)
print(count_list)
# [Counter({'这': 1, '是': 1, '第一个': 1, '文档': 1}),
# Counter({'这是': 1, '第二个': 1, '文档': 1}),
# Counter({'这是': 1, '最后': 1, '一个': 1, '文档': 1}),
# Counter({'文档': 2, '现在': 1, '没有': 1, '了': 1})]

# 1.3 定义函数
import math


def tf(word, count):
    return count[word]/sum(count.values())


def idf(word, count_list):
    n_contain = sum([1 for count in count_list if word in count])
    return math.log(len(count_list)/(1+n_contain))


def tf_idf(word, count, count_list):
    return tf(word, count)*idf(word, count_list)


# 1.4 输出结果
for index, count in enumerate(count_list):
    print('第{}个文档的TF IDF的信息;'.format(index+1))
    # 分值
    scores = {word: tf_idf(word, count, count_list) for word in count}
    scores_word = sorted(scores.items(), key=lambda x: x[1], reverse=True)
    for word,score in scores_word:
        print('word:{}, TF IDF : {} '.format(word, round(score, 5)))
'''
第1个文档的TF IDF的信息;
word:这, TF IDF : 0.17329 
word:是, TF IDF : 0.17329 
word:第一个, TF IDF : 0.17329 
word:文档, TF IDF : -0.05579 
第2个文档的TF IDF的信息;
word:第二个, TF IDF : 0.23105 
word:这是, TF IDF : 0.09589 
word:文档, TF IDF : -0.07438 
第3个文档的TF IDF的信息;
word:最后, TF IDF : 0.17329 
word:一个, TF IDF : 0.17329 
word:这是, TF IDF : 0.07192 
word:文档, TF IDF : -0.05579 
第4个文档的TF IDF的信息;
word:现在, TF IDF : 0.13863 
word:没有, TF IDF : 0.13863 
word:了, TF IDF : 0.13863 
word:文档, TF IDF : -0.08926 
'''


# 2、Gensim

# 2.1 词袋统计
# 2.2 获取词频
from gensim import corpora
dic = corpora.Dictionary(words_list)  # 这是一个对象
# print(dic)
# doc2bow()传入的是一个词的列表
new_corpus = [dic.doc2bow(words) for words in words_list]
# 第一个元素是词在词典中的id, 第二个是词在文档中出现的次数
print(new_corpus)
# [[(0, 1), (1, 1), (2, 1), (3, 1)],  -----['这', '是', '第一个', '文档']
# [(0, 1), (4, 1), (5, 1)],
# [(0, 1), (5, 1), (6, 1), (7, 1)],
# [(0, 2), (8, 1), (9, 1), (10, 1)]]  ----['现在', '没有', '文档', '了', '文档']

# 2.3 每一个词对应的id
print(dic.token2id)
# {'文档': 0, '是': 1, '第一个': 2, '这': 3, '第二个': 4, '这是': 5, '一个': 6, '最后': 7, '了': 8, '没有': 9, '现在': 10}

from gensim import models
tfidf = models.TfidfModel(new_corpus)
# 保存模型
tfidf.save('tfidf.model')
# 加载模型
tfidf = models.TfidfModel.load('tfidf.model')
tf_idf_vec = []
for corpu in corpus:
    # 先拿到第一个文档
    doc_bow = dic.doc2bow(corpu.lower().split())
    vec = tfidf[doc_bow]
    tf_idf_vec.append(vec)
print(tf_idf_vec)
# 一个列表对应一个文章
# [[(1, 0.5773502691896258),(2, 0.5773502691896258), (3, 0.5773502691896258)],
# [(4, 0.8944271909999159), (5, 0.4472135954999579)],
# [(5, 0.3333333333333333), (6, 0.6666666666666666), (7, 0.6666666666666666)],
# [(8, 0.5773502691896258),(9, 0.5773502691896258), (10, 0.5773502691896258)]]

# 3、Sklearn
from sklearn.feature_extraction.text import TfidfVectorizer
# 初始化对象
tfidf_vec = TfidfVectorizer()
# 加载所有语料
tf_idf_matrix = tfidf_vec.fit_transform(corpus)
# 得到语料库中所有不重复的词
print(tfidf_vec.get_feature_names())
# ['一个', '文档', '最后', '没有', '现在', '第一个', '第二个', '这是']
# 得到所有单词对应的id
print(tfidf_vec.vocabulary_)
# {'第一个': 5, '文档': 1, '这是': 7, '第二个': 6, '最后': 2, '一个': 0, '现在': 4, '没有': 3}
# 获得tf idf 矩阵输出
print(tf_idf_matrix.toarray())
'''
[[0.         0.46263733 0.         0.         0.         0.88654763    0.         0.        ]
 [0.         0.37919167 0.         0.         0.         0.            0.72664149 0.5728925 ]
 [0.58783765 0.30675807 0.58783765 0.         0.         0.            0.         0.46345796]
 [0.         0.59380024 0.         0.56894695 0.56894695 0.            0.         0.        ]]
'''

2.4 Word2vec

2.4.1 基础介绍

单词嵌入向量(Word Embedding)

  • 理想的词表征:
  1. 大小合适
  2. 增量更新
  3. 语义相似度
  4. 怎么做?
自然语言处理文本分类实战---慕课学习笔记_第16张图片
  • One-Hot VS Word Embedding
自然语言处理文本分类实战---慕课学习笔记_第17张图片
  • 学习方法

    自然语言处理文本分类实战---慕课学习笔记_第18张图片
2.4.2 Word2vec实战

数据集:

今日头条中文新闻(短文本)分类

地址:https://storage.googleapis.com/cluebenchmark/tasks/tnews_public.zip

import pandas as pd
import json
import jieba

'''
0:gensim词向量实践
    1、读取预处理的数据集
    2、训练
    3、结果
'''
# 1、下载数据
# 1.1 数据预处理


def get_sentence(data_file):
    # 读取文件
    f = open(data_file, 'r', encoding='utf-8')
    reader = f.readlines()
    sentence = []
    for line in reader:
        line = json.loads(line.strip())
        sentence.append(line['sentence'])
    return sentence


train_sentence = get_sentence('train.json')
test_sentence = get_sentence('test.json')
dev_sentence = get_sentence('dev.json')

# 2、载入数据
train_data = train_sentence + test_sentence + dev_sentence
# print(len(train_data))  # 73360
# 分词
train_data = [list(jieba.cut(sentence)) for sentence in train_data]


# 3、构建词向量模型
from gensim.models.word2vec import LineSentence
from gensim.models import word2vec
import gensim
import logging
logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s', level=logging.INFO)

# 构建模型
from gensim.models import FastText
# print(help(FastText))
# model = FastText(test_sentence, vector_size=4, window=3, min_count=1)

# 4、训练模型     skip-gram(sg = 1) & CBOW(sg =  0)
model = word2vec.Word2Vec(train_data, sg=0, workers=8, min_count=5, vector_size=200)
# 5、保存模型
model_save_path = 'word2vec.model'
model.save(model_save_path)
# 6、载入模型
model = word2vec.Word2Vec.load(model_save_path)
# 输出向量维度(1x200)  上面定义的vector_size=200
print(model.wv['智能'].shape)
'''
输出:
(200,)
'''

# 查找一个上下文最近的词
print(model.wv.most_similar(['智能'], topn=10))
'''
输出:
[('金融', 0.970018208026886), 
('生态', 0.9675754308700562), 
('赋能', 0.9635003209114075), 
('服务', 0.9610007405281067),
('电商', 0.9590190052986145), 
('创新', 0.9575081467628479),
('布局', 0.956716775894165),
('建设', 0.9556843042373657), 
('助力', 0.9543666839599609), 
('云', 0.9498512148857117)]
'''

第三章 文本分类任务

3.1 分类任务

3.1.1、图解
自然语言处理文本分类实战---慕课学习笔记_第19张图片
3.1.2、分类任务的分类:
  1. 二分类(两种状态互斥)
  2. 多分类
  3. 多标签分类
自然语言处理文本分类实战---慕课学习笔记_第20张图片
3.1.3、多分类详解:
自然语言处理文本分类实战---慕课学习笔记_第21张图片

一对一策略:

自然语言处理文本分类实战---慕课学习笔记_第22张图片

一对其余策略:

自然语言处理文本分类实战---慕课学习笔记_第23张图片
3.1.4 多标签问题与二、多分类问题关系
自然语言处理文本分类实战---慕课学习笔记_第24张图片 自然语言处理文本分类实战---慕课学习笔记_第25张图片 自然语言处理文本分类实战---慕课学习笔记_第26张图片

在建模上区别:

image-20211216114953485

3.2 激活函数

3.2.1 Softmax
自然语言处理文本分类实战---慕课学习笔记_第27张图片
3.2.2 Sigmoid
自然语言处理文本分类实战---慕课学习笔记_第28张图片

3.3 交叉熵

自然语言处理文本分类实战---慕课学习笔记_第29张图片 自然语言处理文本分类实战---慕课学习笔记_第30张图片
3.4 实战—激活函数练习
# 激活函数练习
# sigmoid
import numpy as np
import matplotlib.pyplot as plt


def sigmoid(x):
    return 1.0/(1+np.exp(-x))


# print(sigmoid(1))
'''
0.7310585786300049
'''
sigmoid_input = np.arange(-10, 10)
sigmoid_output = sigmoid(sigmoid_input)
# print(sigmoid_output)

'''
[4.53978687e-05 1.23394576e-04 3.35350130e-04 9.11051194e-04
 2.47262316e-03 6.69285092e-03 1.79862100e-02 4.74258732e-02
 1.19202922e-01 2.68941421e-01 5.00000000e-01 7.31058579e-01
 8.80797078e-01 9.52574127e-01 9.82013790e-01 9.93307149e-01
 9.97527377e-01 9.99088949e-01 9.99664650e-01 9.99876605e-01]
'''
# plt.plot(sigmoid_input, sigmoid_output)
# plt.xlabel('sigmoid_input')
# plt.ylabel('sigmoid_output')
# plt.show()


# softmax
import math

softmax_input = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
z_exp = [math.exp(i) for i in softmax_input]
print(z_exp)
'''
[2.718281828459045, 7.38905609893065, 20.085536923187668, 54.598150033144236, 
2.718281828459045, 7.38905609893065, 20.085536923187668]
'''
sum_z_exp = sum(z_exp)
softmax_output = [round(ex/sum_z_exp, 2) for ex in z_exp]
print(softmax_output)
'''
[0.02, 0.06, 0.17, 0.47, 0.02, 0.06, 0.17]
'''
# 画图
plt.plot(softmax_input, softmax_output)
plt.xlabel('softmax_input')
plt.ylabel('softmax_output')
plt.show()

text_RNN步骤简要介绍

1、embedded层:将句子或文章平铺为词向量

2、进入多层卷积层(卷积核大小不同):算出每个卷积核卷积后的特征值

3、进入池化层:提取出上一步最大的特征值(max pooling)

4、连接:将最大的特征值拼接在一起

5、套一个dropout:防止过拟合

6、进入全连接层:分类(两类或者多类)

自然语言处理文本分类实战---慕课学习笔记_第31张图片

第四章 模型评估

1、评价指标

自然语言处理文本分类实战---慕课学习笔记_第32张图片

2、混淆矩阵:(指标:准确率、召回率、精确率)

自然语言处理文本分类实战---慕课学习笔记_第33张图片

3、预测的效果?

假设样本不平衡:(<0.5 分为0,>0.5分为1)

自然语言处理文本分类实战---慕课学习笔记_第34张图片

实例

自然语言处理文本分类实战---慕课学习笔记_第35张图片 自然语言处理文本分类实战---慕课学习笔记_第36张图片

如果不使用模型,直接计算:

自然语言处理文本分类实战---慕课学习笔记_第37张图片
1、Recall(召回率)
自然语言处理文本分类实战---慕课学习笔记_第38张图片
2、Precision(精确率)
image-20211222141252445
3、F1
image-20211222141605873
4、FPR
image-20211222141702517
5、ROC
自然语言处理文本分类实战---慕课学习笔记_第39张图片
6、AUC(ROC线下面积)
自然语言处理文本分类实战---慕课学习笔记_第40张图片

线越靠近左上角效果越好 (SKlearn调用roc_auc_score)

第五章 知识扩展

自然语言处理文本分类实战---慕课学习笔记_第41张图片自然语言处理文本分类实战---慕课学习笔记_第42张图片

中文NLP语料库:

自然语言处理文本分类实战---慕课学习笔记_第43张图片

​ https://www.cluebenchmarks.com/

NLP学习框架:BERT

自然语言处理文本分类实战---慕课学习笔记_第44张图片 自然语言处理文本分类实战---慕课学习笔记_第45张图片

国内可以一件加载模型:

自然语言处理文本分类实战---慕课学习笔记_第46张图片

免费的GPU:

自然语言处理文本分类实战---慕课学习笔记_第47张图片 自然语言处理文本分类实战---慕课学习笔记_第48张图片 自然语言处理文本分类实战---慕课学习笔记_第49张图片

你可能感兴趣的:(文本分类,自然语言处理)