charactor級別處理字串及2vec

2021-10-09 00:21:15 字數 3605 閱讀 4012

20200810 -

在一些其他的部落格中,大多數都是針對句子或者文章進行分析,其分析的單位是乙個單詞,這也是word2vec的主要工作。但是,我這裡的乙個需求是,對dga網域名稱進行分析,這裡面沒有單詞的概念。這裡記錄幾個關於這部分內容的處理方式。也就是說,我處理的應該是字元級別的n-gram內容。

定義要處理的內容是字串的陣列,每個元素都是"google"型別的資料。

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的方法,關於這兩者的區別暫時還沒有了解。

在前面的小節中,介紹了countvectorizer這種方式,雖然這種方式可以生成相應的矩陣,但是如果要進行word2vec的操作,需要生成相應的gram片語,然後來進行處理。

針對字串"google",如果是對單個字元進行處理,那麼只需要利用list函式生成即可,然後將這部分內容傳遞。

c1grams =

list

(map

(lambda x:

list

(x), sample_x)

)

對於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
前面也說了, 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是指轉化為向量的維度。

計算單個字元的向量還不能解決問題,還需要計算整體的向量,就比如計算單個單詞的向量還不夠,還需要計算整個文章,整個句子的向量。這部分內容可以看文章[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來計算句子的相似度

APP級別處理未捕獲異常

前言 那麼它們是如何處理沒有try catch 捕獲到的異常 並 進行介面友好提示優化的處理呢。這裡我們通過乙個demo學習一下。一 建立乙個類 crashhandler 實現 uncaughtexceptionhandler 介面 當程式發生未捕獲異常時 由該類進行處理 public class ...

APP級別處理未捕獲異常

前言 那麼它們是如何處理沒有try catch 捕獲到的異常 並 進行介面友好提示優化的處理呢。這裡我們通過乙個demo學習一下。一 建立乙個類 crashhandler 實現 uncaughtexceptionhandler 介面 當程式發生未捕獲異常時 由該類進行處理 public class ...

c template中的個別處理方式

template的作用是把僅型別不同但功能相似的函式合併在一起,但是有時候template中的函式並不能滿足所有的型別呼叫。如下所示 template inline int hash wrap const kty k return int k 所有的數字型別使用該模板都沒有問題,但是string型別...