NLP理论实践-Task2特征提取

偏执的太偏执、 2022-01-06 10:51 278阅读 0赞

特征提取

    1. 基本文本处理技能
    • 1.1 分词的概念(分词的正向最大、逆向最大、双向最大匹配法);
    • 1.2 词、字符频率统计;(可以使用Python中的collections.Counter模块,也可以自己寻找其他好用的库)
  • 2.
    • 2.1 语言模型中unigram、bigram、trigram的概念;
    • 2.1 n-gram模型(考虑句子中单词之间的顺序)
      • 2.2词袋模型(不考虑句子中单词之间的顺序)
    • 2.2 unigram、bigram频率统计;(可以使用Python中的collections.Counter模块,也可以自己寻找其他好用的库)
    1. 文本矩阵化:要求采用词袋模型且是词级别的矩阵化

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模块,也可以自己寻找其他好用的库)

  1. import jieba
  2. from collections import Counter
  3. data = '北京大学和清华大学是中国的顶尖大学'
  4. print('单词统计')
  5. words = list(jieba.cut(data))
  6. print(Counter(words))
  7. print('字符统计')
  8. print(Counter(list(data)))

2.

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

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

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

当n取1、2、3时,n-gram模型分别称为unigram、bigram、trigram语言模型
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两个文件中。

  1. class NGram(object):
  2. def __init__(self, n):
  3. # n is the order of n-gram language model
  4. self.n = n
  5. self.unigram = {
  6. }
  7. self.bigram = {
  8. }
  9. # scan a sentence, extract the ngram and update their
  10. # frequence.
  11. #
  12. # @param sentence list{str}
  13. # @return none
  14. def scan(self, sentence):
  15. # file your code here
  16. for line in sentence:
  17. self.ngram(line.split())
  18. #unigram
  19. if self.n == 1:
  20. try:
  21. fip = open("data.uni","w")
  22. except:
  23. print >> sys.stderr ,"failed to open data.uni"
  24. for i in self.unigram:
  25. fip.write("%s %d\n" % (i,self.unigram[i]))
  26. if self.n == 2:
  27. try:
  28. fip = open("data.bi","w")
  29. except:
  30. print >> sys.stderr ,"failed to open data.bi"
  31. for i in self.bigram:
  32. fip.write("%s %d\n" % (i,self.bigram[i]))
  33. # caluclate the ngram of the words
  34. #
  35. # @param words list{str}
  36. # @return none
  37. def ngram(self, words):
  38. # unigram
  39. if self.n == 1:
  40. for word in words:
  41. if word not in self.unigram:
  42. self.unigram[word] = 1
  43. else:
  44. self.unigram[word] = self.unigram[word] + 1
  45. # bigram
  46. if self.n == 2:
  47. num = 0
  48. stri = ''
  49. for i in words:
  50. num = num + 1
  51. if num == 2:
  52. stri = stri + " "
  53. stri = stri + i
  54. if num == 2:
  55. if stri not in self.bigram:
  56. self.bigram[stri] = 1
  57. else:
  58. self.bigram[stri] = self.bigram[stri] + 1
  59. num = 0
  60. stri = ''
  61. if __name__=="__main__":
  62. import sys
  63. try:
  64. fip = open(sys.argv[1],"r")
  65. except:
  66. print >> sys.stderr, "failed to open input file"
  67. sentence = []
  68. for line in fip:
  69. if len(line.strip())!=0:
  70. sentence.append(line.strip())
  71. uni = NGram(1)
  72. bi = NGram(2)
  73. uni.scan(sentence)
  74. bi.scan(sentence)

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

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

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

  1. import jieba
  2. import pandas as pd
  3. import tensorflow as tf
  4. from collections import Counter
  5. from gensim.models import Word2Vec
  6. from sklearn.feature_extraction.text import CountVectorizer
  7. # 读取停用词
  8. def read_stopword(filename):
  9. stopword = []
  10. fp = open(filename, 'r')
  11. for line in fp.readlines():
  12. stopword.append(line.replace('\n', ''))
  13. fp.close()
  14. return stopword
  15. # 切分数据,并删除停用词
  16. def cut_data(data, stopword):
  17. words = []
  18. for content in data['content']:
  19. word = list(jieba.cut(content))
  20. for w in list(set(word) & set(stopword)):
  21. while w in word:
  22. word.remove(w)
  23. words.append(' '.join(word))
  24. data['content'] = words
  25. return data
  26. # 获取单词列表
  27. def word_list(data):
  28. all_word = []
  29. for word in data['content']:
  30. all_word.extend(word)
  31. all_word = list(set(all_word))
  32. return all_word
  33. # 计算文本向量
  34. def text_vec(data):
  35. count_vec = CountVectorizer(max_features=300, min_df=2)
  36. count_vec.fit_transform(data['content'])
  37. fea_vec = count_vec.transform(data['content']).toarray()
  38. return fea_vec
  39. if __name__ == '__main__':
  40. data = pd.read_csv('./data/cnews/cnews.test.txt', names=['title', 'content'], sep='\t') # (10000, 2)
  41. data = data.head(50)
  42. stopword = read_stopword('./data/stopword.txt')
  43. data = cut_data(data, stopword)
  44. fea_vec = text_vec(data)
  45. print(fea_vec)

发表评论

表情:
评论列表 (有 0 条评论,278人围观)

还没有评论,来说两句吧...

相关阅读

    相关 NLP理论实践问题记录

    问题记录 Task1 问题 1 当训练样本很多的时候,每次打开程序再次读取都要耗费很长的时间,持久化的话可否压缩占用的空间,有没有更好地节约时间的方法?