charactor级别处理字符串及2vec

20200810 -

0. 引言

本篇文章来记录一些自然语言中处理字符或者字符串的一些方法。(本人非专业人士,主要就是从网上顺着思路来弄一些东西,参考时请结合自己的实际情况)

1. gram处理

在一些其他的博客中,大多数都是针对句子或者文章进行分析,其分析的单位是一个单词,这也是word2vec的主要工作。但是,我这里的一个需求是,对DGA域名进行分析,这里面没有单词的概念。这里记录几个关于这部分内容的处理方式。也就是说,我处理的应该是字符级别的n-gram内容。
定义要处理的内容是字符串的数组,每个元素都是"google"类型的数据。

1.1 利用sklearn中的CountVectorizer来处理字符

CountVectorizer这个函数,平时多用来处理word级别的内容,这里摘述一段代码,是针对Webshell检测内容的。

from sklearn.feature_extraction.text import CountVectorizer
CV = CountVectorizer(ngram_range = (2, 2), decode_error = 'ignore', max_features = max_features, token_pattern = r'\b\w+\b', min_df = 1, max_df = 1.0) 
x = CV.fit_transform(x).toarray()

该代码主要的作用就是生成按照空格分割的2-gram单词的矩阵;然后平时还会加上tf-idf来处理。

from sklearn.feature_extraction.text import TfidfTransformer
transformer = TfidfTransformer(smooth_idf = False)
x_tfidf = transformer.fit_transform(x)
x = x_tfidf.toarray()

以上内容中,在初始化的时候,决定了它是处理单词级别的2-gram。通过调整参数,是可以达到处理字符的目的的。

cv = CountVectorizer(analyzer='char',ngram_range=(2,2))

后续的代码都是一致的;对于fit_transform之后返回的对象,如果要获取相应的数组,使用toarray方法,不过也可以使用todense的方法,关于这两者的区别暂时还没有了解。

1.2 利用nltk中的gram处理

在前面的小节中,介绍了CountVectorizer这种方式,虽然这种方式可以生成相应的矩阵,但是如果要进行word2vec的操作,需要生成相应的gram词组,然后来进行处理。

1.2.1 1-gram

针对字符串"google",如果是对单个字符进行处理,那么只需要利用list函数生成即可,然后将这部分内容传递。

c1grams = list(map(lambda x: list(x), sample_x))

1.2.2 2-gram

对于2-gram,可以使用nltk中的grams函数来执行,下面代码摘述自问答[1]。

>>> from nltk import word_tokenize, ngrams
>>> s = "foo bar sentence"

# Word ngrams.
>>> list(ngrams(word_tokenize(s), 2))
[('foo', 'bar'), ('bar', 'sentence')]

# Character ngrams.
>>> list(ngrams(s, 2))
[('f', 'o'), ('o', 'o'), ('o', ' '), (' ', 'b'), ('b', 'a'), ('a', 'r'), ('r', ' '), (' ', 's'), ('s', 'e'), ('e', 'n'), ('n', 't'), ('t', 'e'), ('e', 'n'), ('n', 'c'), ('c', 'e')]

但是上述的代码中,其生成的2-gram是不能直接用于word2vec的,需要进行一些简单的操作才行;同时2-gram这种,在nltk中是具备直接函数的[2]。

from nltk import bigrams

2. word2vec将字符转化维向量

前面也说了, word2vec很多时候都是将单词转化为向量。但实际上,其函数工作时,在处理传进来的参数时并不会到底是单词还是单个字符,还是2-gram字符连接[3]。不过,关于这部分内容我没有深入研究过,我只是直接进行了使用。
比如前面获得了1-gram字符集级别的模型,直接传入word2vec即可。

from gensim.models import Word2Vec
model = Word2Vec(c1grams,min_count=1, size = 300)

word2vec只能处理,列表中元素是字符串的形式,那么前面2-gram就没办法直接传递,需要经过下面的代码进行处理。

from gensim.models import Word2Vec
c2grams = list(map(lambda x: list(map(lambda x: "".join(x), ngrams(x, 2))), sample_x))
model = Word2Vec(c1grams,min_count=1, size = 300)

代码中参数size是指转化为向量的维度。

3. 计算一个字符串的整体向量

计算单个字符的向量还不能解决问题,还需要计算整体的向量,就比如计算单个单词的向量还不够,还需要计算整个文章,整个句子的向量。这部分内容可以看文章[4],其中介绍的第一个方式是直接相加取平均,这也是这个阶段我使用的一种方式;另外一种是使用tf-idf计算后,加权平均,最后一种是论文中的方法,这里不再描述。文章[5]给出了第一种方法的代码。

参考文章

[1]How to find character bigrams and trigrams?
[2]n-grams in python, four, five, six grams?
[3]word2vec models consist of characters instead of words
[4]Word2Vec 怎么将得到的词向量变成句子向量,以及怎么衡量得到词向量的好坏
[5]在python中如何用word2vec来计算句子的相似度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值