【NLP】NO1:自然语言处理的完整机器处理流程

参考文章:https://www.jianshu.com/p/b87e01374a65在这里插入图片描述

二、中文自然处理的主要步骤

(1)语料清洗
1.人工去重、对齐、删除和标注
2.基于规则提取内容、正则表达式匹配
3.根据词性和命名实体提取

英文文本处理不同点:
(1)基于空格分词
(2)进行拼写检查、词干提取、词型还原
都是为了找到词的原始形式

  • 词干提取:更加激,可能找到不是词的词干
  • 词型还原:保守,一般能找到词的词干
#nltk中提供多种方法,一般wordnet比较好,不会把单词过分精简
from nltk.stem import WordNetLemmatizer
a = WordNetLemmatizer()
data['word'] = data['word'].apply(lambda x:a.WordNetLemmatizer(x))

1 去掉非文本部分
利用正则表达式或者直接替换,去除不提供任何其他信息的标签:html标签、标点符号等

#正则表达式
import re
p = re.complie('正则表达式')
word = re.sub(p,' ',word)
#直接替换
data['word'] = data['word'].str.replace('[^\w\s]','')

(2)中文分词—难点在于歧义和新词
1.基于字符串匹配的分词方法
2.基于理解的分词方法
3.基于统计的分词方法
4.基于规则的分词方法

#英文文本:基于空格分词
data['word'] = data['word'].apply(lambda x:" ".join(x for x in x.split()))
#中文分词:调用工具
import jieba
data['word'] = data['word'].apply(lambda x: list(jieba.cut(x)))

常用的中文分词有中科院计算所NLPIR、哈工大LTP、清华大学THULAC、斯坦福分词器、Hanlp分词器和jieba分词

1、jieba 的分词算法
1.基于统计词典,构造前缀词典,基于前缀词典对句子进行切分,得到所有切分可能,根据切分位置,构造一个有向无环图(DAG);
2.基于DAG图,采用动态规划计算最大概率路径(最有可能的分词结果),根据最大概率路径分词;
3.对于新词(词库中没有的词),采用有汉字成词能力的 HMM 模型进行切分。

2、结巴分词应用

import jieba
#默认模式:精确分词
word = jieba.cut(word,cut_all=False)
#全模式:所有可能是词语的都扫描出来,优点是速度快,缺点是不能解决歧义
word = jieba.cut(word,cut_all=True)
#搜索引擎模式:在精确模式的基础上,对长词再次切分,提高召回率
word = jieba.cut_search(word)
#输入格式
print(" ".join(word))
#分词后返回list格式
word = jieba.lcut(word)
word = jieba.lcut_search(word)
#获取中文词性
import jieba.posseg as psg
[(x.word,x.flag) for x in psg.lcut(word)]
#获取中文分词结果中的top n
from collections import Counter
top5 = Counter(word).most_common(5)
#添加自定义词
jieba.add_word("和平精英")
#添加自定义字典
jieba.load_userdict('dict.txt')

(3) 词性标注
1.定义词的词性, 如形容词、 动词等, 在情感分析、 知识推理中用, 在文本分类中不用
2.基于统计的方法: 最大熵模型、 HMM 模型、 最大概率输出词性模型
3.基于规则的方法

(4) 去停用词

  • 停用词就是没有任何意义的单词,去掉他们对理解整个句子语义没有任何影响。
  • 为了节省存储空间和提高搜索效率,nlp首要任务时去掉停用词
  • 例如随处可见的词和语气助词、副词、介词和连接词
import nltk
from nltk.tokenize import word_tokenize
nltk.download()
----------------------------------------------------------
#导入英文停用词表
from nltk.corpus import stopwords
stop = stopwords.words('english')
#去除停用词
data['word'] = data['word'].apply(lambda sen:" ".join(x for x in sen.split(' ') if x not in stop))
#提取新特征:停用词的个数
data['stopwords'] = data['word'].apply(lambda sen: len([x for x in sen.split() if x in stop]))
'''
导入从网上下载好的“中文停用词”表:一般有“中文停用词表”、“哈工大停用词表”、“百度停用词表”、“四川大学机器智能实验室停用词表”等,可以先对停用词表进行修改,保留一些需要的停用词。
'''
def stopwords_list(filepath):
    stopwords = [line.strip() for line in open(filepath,'r',encoding='utf-8').readlines()]
    return stopwords

def move_stopwords(sentence):
    stopwords = stopwords_list(filepath)
    outstr = ''
    for word in sentence:
        if word not in sentence:
            if word != '\t' and '\n':
                outstr += word
                outstr += " "
    return outstr

data['word'] = data['word'].apply(lambda x:move_stopwords(x))

(5)特征选择
常见DF、MI、IG、CHI、WLLR、WFO
1 词语数量
(负面评论的词语会比正面评论多)

扫描二维码关注公众号,回复: 11043296 查看本文章
#英文字符按照空格分词
data['word_count'] = data['word'].apply(lambda x:len(str(x).split(" ")))

2 字符数量

data['char_count'] = data['word'].str.len() #包含了空格,不需要的话提前去掉

3 平均词汇长度

def avg_word(sentence):
    words = sentence.split()
    avg = (sum(len(word) for word in words) / len(words)
data['avg_word'] = data['word'].apply(lambda x:avg_word(x))

4 特殊字符的数量

data['hash_tags'] = data['word'].apply(lambda sen:len([x for x in sen.split() if x.startswith('#')]))

5 数字的数量

data['number'] = data['word'].apply(lambda sen:len(x for x in sen.split() if x.isdigit()))

6 大写单词的数量

data['upper'] = data['word'].apply(lambda sen:len(x for x in sen.split() if x.isupper()))

7 全部转化为小写

data['word'] = data['word'].apply(lambda sen:" ".join(x.lower() for x in sen.split()))

(6)特征工程
把分词后的字和词语表示成计算机能够计算的类型,即转换为向量。
1.词袋模型BOW
1)将分词后的词,取并集,再去重
2)基于gensim序列化词,构建词袋模型
最常用的是TF-IDF。

  • 基于词频,将文本转换成向量,不考虑词序。
  • 主要思想:如果某个词在一篇文档中出现的频率高,也即 TF 高;并且在语料库中其他文档中很少出现,即 DF 低,也即 IDF 高,则认为这个词具有很好的类别区分能力。
  • TF表示词频
  • IDF表示反文档频率,包含词条t的文档越少,IDF越大
    在这里插入图片描述
from sklearn.feature_extraction.text import TfidfVectorizer
corpus = ["This is sample document.", "another random document.", "third sample document text"]
vector = TfidfVectorizer()
tf_data = vector.fit_transform(corpus)
print(tf_data)    #(句子下标, 单词特征下标)   权重
print(vector.vocabulary_)    #单词特征
df1 = pd.DataFrame(tf_data.toarray(), columns=vector.get_feature_names()) # to DataFrame
df1

在这里插入图片描述
2.词向量模型
将词转换为向量矩阵,常用的是one-hot(词语间相互独立、维度灾难)、word2vec(稠密向量、意思相近的词被映射到向量空间中相近的位置,主要包括skip-gram和CBOW两种模型,高效训练方式是负采样和层序softmax)、Doc2vec、wordrank和fastrank。
①skip-gram模型

  • 基于概率的判别模型

  • 输入的是一句话,输出的是这句话的概率,等于这些单词的联合概率。

  • 考虑了先后顺序,大大增加了字典的大小

  • 一般为2、3维

在这里插入图片描述

from sklearn.feature_extraction.text import CountVectorizer
vector = CountVectorizer(min_df=1, ngram_range=(2,2))# (2,2)表示2维,(3,3)表示3维
X = vector.fit_transform(data)# 将分词好的文本转换为矩阵
print(vector.vocabulary_ )# 得到特征
print(X) #(句子下标, 单词特征下标)   频数
df1 = pd.DataFrame(X.toarray(), columns=vector.get_feature_names())

在这里插入图片描述
②word2vec

  • 固定长度的连续向量,一般为100-500
  • 意义相近的词之间的向量距离小,以稠密向量形式表示单词
  • 优点:(1)维度低,节省计算(2)保留相对位置的语义
  • 两种形式利用词的上下文预测当前词CBOW、利用当前词预测上下文skip-gram
  • 句子用词向量表示:句子的平均词向量(单词加权取平均)
  • 会自己去掉低频词,可以不需要在预处理部分去除
  • 英文还可以使用glove模型进行词嵌入/文本向量表示
#英文还可以使用glove模型进行词嵌入/文本向量表示
from gensim.scripts.glove2word2vec import glove2wordvec
glove2wordvec(data)
#中文使用word2vec构建词向量
from gensim.models import Word2Vec  
import jieba
#定义停用词、标点符号
punctuation = [",","。", ":", ";", ".", "'", '"', "’", "?", "/", "-", "+", "&", "(", ")"]
sentences = [
"长江是中国第一大河,干流全长6397公里(以沱沱河为源),一般称6300公里。流域总面积一百八十余万平方公里,年平均入海水量约九千六百余亿立方米。以干流长度和入海水量论,长江均居世界第三位。",
"黄河,中国古代也称河,发源于中华人民共和国青海省巴颜喀拉山脉,流经青海、四川、甘肃、宁夏、内蒙古、陕西、山西、河南、山东9个省区,最后于山东省东营垦利县注入渤海。干流河道全长5464千米,仅次于长江,为中国第二长河。黄河还是世界第五长河。",
"黄河,是中华民族的母亲河。作为中华文明的发祥地,维系炎黄子孙的血脉.是中华民族民族精神与民族情感的象征。",
"黄河被称为中华文明的母亲河。公元前2000多年华夏族在黄河领域的中原地区形成、繁衍。",
"在兰州的“黄河第一桥”内蒙古托克托县河口镇以上的黄河河段为黄河上游。",
"黄河上游根据河道特性的不同,又可分为河源段、峡谷段和冲积平原三部分。 ",
"黄河,是中华民族的母亲河。"
]
#分词、去标点符号
sentences = [jieba.lcut(sen) for sen in sentences]
tokenized = []
for sentence in sentences:
    words = []
    for word in sentence:
        if word not in punctuation:          
            words.append(word)
    tokenized.append(words)
#训练模型
#sg=1表示skip-gram算法,对低频词敏感、默认sg=0,表示CBOW算法
#size表示输出词向量的维度,一般在100-200之间,太小会导致词映射因为冲突而影响结果,太大会消耗内存
#window是当前词与目标词之间的最大距离
#min_count最小词频
#negative和sample是对结果进行微调,表示更高频率的词被随机采样到所设置的阈值
#hs=1表示softmax被使用,默认hs=0
model = Word2Vec(tokenized,sg=1,size=100,window=5,min_count=2,negative=1,sample=0.001,hs=1,workers=4)
#保存模型
model.save('model')
#加载模型
model = Word2Vec.load('model')

(7)模型训练
1.机器学习:XGBOOST、LightGBM、GBDT
2.深度学习:CNN、RNN、LSTM、TextCNN、FastText、Bert

(8)评价指标
1.错误率、精度、准确率、召回率、F1分数、混淆矩阵
2.ROC曲线、AUC面积

发布了60 篇原创文章 · 获赞 55 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/MARY197011111/article/details/99852102