NLP理论实践-Task2特征提取

1. 基本文本处理技能

1.1 分词的概念(分词的正向最大、逆向最大、双向最大匹配法);

分词就是将连续的字序列按照一定的规范重新组合成词序列的过程。在英文的行文中,单词之间是以空格作为自然分界符的,而中文只是字、句和段能通过明显的分界符来简单划界,唯独词没有一个形式上的分界符,虽然英文也同样存在短语的划分问题,不过在词这一层上,中文比之英文要复杂得多、困难得多。

现有的分词算法可分为三大类:基于字符串匹配的分词方法基于理解的分词方法基于统计的分词方法。按照是否与词性标注过程相结合,又可以分为单纯分词方法和分词与标注相结合的一体化方法。

分词算法设计中的几个基本原则

1、颗粒度越大越好:用于进行语义分析的文本分词,要求分词结果的颗粒度越大,即单词的字数越多,所能表示的含义越确切。

2、切分结果中非词典词越少越好,单字字典词数越少越好,这里的“非词典词”就是不包含在词典中的单字,而“单字字典词”指的是可以独立运用的单字,如“的”、“了”、“和”、“你”、“我”、“他”。

3、总体词数越少越好,在相同字数的情况下,总词数越少,说明语义单元越少,那么相对的单个语义单元的权重会越大,因此准确性会越高。

最大匹配法:最大匹配是指以词典为依据,取词典中最长单词为第一个次取字数量的扫描串,在词典中进行扫描(为提升扫描效率,还可以跟据字数多少设计多个字典,然后根据字数分别从不同字典中进行扫描)。例如:词典中最长词为“中华人民共和国”共7个汉字,则最大匹配起始字数为7个汉字。然后逐字递减,在对应的词典中进行查找。
正向最大匹配法:对句子从左到右进行扫描,尽可能地选择与词典中最长单词匹配的词作为目标分词,然后进行下一次匹配。

逆向最大匹配法:对句子从右到左进行扫描,尽可能地选择与词典中最长单词匹配的词作为目标分词,然后进行下一次匹配。

双向最大匹配法:将正向最大匹配算法和逆向最大匹配算法进行比较,从而确定正确的分词方法。

https://blog.csdn.net/jusang486/article/details/37561365
https://blog.csdn.net/hnlylnjyp/article/details/93490988

1.2 词、字符频率统计;(可以使用Python中的collections.Counter模块,也可以自己寻找其他好用的库)

import jieba
from collections import Counter

data = '北京大学和清华大学是中国的顶尖大学'

print('单词统计')
words = list(jieba.cut(data))
print(Counter(words))

print('字符统计')
print(Counter(list(data)))

2.

2.1 语言模型中unigram、bigram、trigram的概念;

2.1 n-gram模型(考虑句子中单词之间的顺序)

unigram 一元分词,把句子分成一个一个的汉字
bigram 二元分词,把句子从头到尾每两个字组成一个词语
trigram 三元分词,把句子从头到尾每三个字组成一个词语.

当n取1、2、3时,n-gram模型分别称为unigrambigramtrigram语言模型
unigram一元分词,把句子分成一个一个的汉字
bigram二元分词,把句子从头到尾每两个字组成一个词语
trigram三元分词,把句子从头到尾每三个字组成一个词语
比如:
西安交通大学:
unigram 形式为:西/安/交/通/大/学
bigram形式为: 西安/安交/交通/通大/大学
trigram形式为:西安交/安交通/交通大/通大学

https://blog.csdn.net/baimafujinji/article/details/51281816

2.2词袋模型(不考虑句子中单词之间的顺序)

将所有词语装进一个袋子里,不考虑其词法和语序的问题,即每个词语都是独立的。
例句:
句1:Jane wants to go to Shenzhen.
句2:Bob wants to go to Shanghai.
建立一个数组用于映射匹配:[Jane, wants, to, go, Shenzhen, Bob, Shanghai]
构建词袋模型:
句1:[1,1,2,1,1,0,0]
句2:[0,1,2,1,0,1,1]

2.2 unigram、bigram频率统计;(可以使用Python中的collections.Counter模块,也可以自己寻找其他好用的库)

输入的是断好词的文本,每个句子一行。
统计词unigram和bigram的频次,并将它们分别输出到data.unidata.bi两个文件中。

class NGram(object):

    def __init__(self, n):
        # n is the order of n-gram language model
        self.n = n
        self.unigram = {}
        self.bigram = {}

    # scan a sentence, extract the ngram and update their
    # frequence.
    #
    # @param    sentence    list{str}
    # @return   none
    def scan(self, sentence):
        # file your code here
        for line in sentence:
            self.ngram(line.split())
        #unigram
        if self.n == 1:
            try:
                fip = open("data.uni","w")
            except:
                print >> sys.stderr ,"failed to open data.uni"
            for i in self.unigram:
                fip.write("%s %d\n" % (i,self.unigram[i]))
        if self.n == 2:
            try:
                fip = open("data.bi","w")
            except:
                print >> sys.stderr ,"failed to open data.bi"
            for i in self.bigram:
                fip.write("%s %d\n" % (i,self.bigram[i]))
    # caluclate the ngram of the words
    #
    # @param    words       list{str}
    # @return   none
    def ngram(self, words):
        # unigram
        if self.n == 1:
            for word in words:
                if word not in self.unigram:
                    self.unigram[word] = 1
                else:
                    self.unigram[word] = self.unigram[word] + 1

        # bigram
        if self.n == 2:
            num = 0
            stri = ''
            for i in words:
                num = num + 1
                if num == 2:
                    stri  = stri + " "
                stri = stri + i
                if num == 2:
                    if stri not in self.bigram:
                        self.bigram[stri] = 1
                    else:
                        self.bigram[stri] = self.bigram[stri] + 1
                    num = 0
                    stri = ''

if __name__=="__main__":
    import sys
    try:
        fip = open(sys.argv[1],"r")
    except:
        print >> sys.stderr, "failed to open input file"
    sentence = []
    for line in fip:
        if len(line.strip())!=0:
            sentence.append(line.strip())
    uni = NGram(1)
    bi = NGram(2)
    uni.scan(sentence)
    bi.scan(sentence)

https://blog.csdn.net/niuox/article/details/11395397

3. 文本矩阵化:要求采用词袋模型且是词级别的矩阵化

步骤有:
3.1 分词(可采用结巴分词来进行分词操作,其他库也可以);
3.2 去停用词;构造词表。
3.3 每篇文档的向量化。

import jieba
import pandas as pd
import tensorflow as tf
from collections import Counter
from gensim.models import Word2Vec
from sklearn.feature_extraction.text import CountVectorizer


# 读取停用词
def read_stopword(filename):
    stopword = []
    fp = open(filename, 'r')
    for line in fp.readlines():
        stopword.append(line.replace('\n', ''))
    fp.close()
    return stopword


# 切分数据,并删除停用词
def cut_data(data, stopword):
    words = []
    for content in data['content']:
        word = list(jieba.cut(content))
        for w in list(set(word) & set(stopword)):
            while w in word:
                word.remove(w)
        words.append(' '.join(word))
    data['content'] = words
    return data


# 获取单词列表
def word_list(data):
    all_word = []
    for word in data['content']:
        all_word.extend(word)
    all_word = list(set(all_word))
    return all_word


# 计算文本向量
def text_vec(data):
    count_vec = CountVectorizer(max_features=300, min_df=2)
    count_vec.fit_transform(data['content'])
    fea_vec = count_vec.transform(data['content']).toarray()
    return fea_vec


if __name__ == '__main__':
    data = pd.read_csv('./data/cnews/cnews.test.txt', names=['title', 'content'], sep='\t')  # (10000, 2)
    data = data.head(50)

    stopword = read_stopword('./data/stopword.txt')
    data = cut_data(data, stopword)

    fea_vec = text_vec(data)
    print(fea_vec)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值