NLP理论实践-Task2特征提取
特征提取
- 基本文本处理技能
- 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、颗粒度越大越好:用于进行语义分析的文本分词,要求分词结果的颗粒度越大,即单词的字数越多,所能表示的含义越确切。
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模型分别称为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.uni
和data.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)
还没有评论,来说两句吧...