文章目錄 一、數據感知—訓練與測試數據 二:文檔分詞(精確—全—搜索引擎模式)—詞性標注 三、用 TF-IDF 和詞袋表示文檔特征 3.1 方法一:使用 CounterVectorizer 和 TfidfTransformer 計算 TF-IDF 3.2 方法二:直接使用 TfidfVectorizer 四、jieba 分詞 五、訓練word2vec模型
開發環境 jupyter notebook
一、數據感知—訓練與測試數據
import numpy
as np
import pandas
as pd
output_dir
= u
'output_word2vec'
import os
if not os
. path
. exists
( output_dir
) : os
. mkdir
( output_dir
)
train_data
= pd
. read_csv
( 'data/sohu_train.txt' , sep
= '\t' , header
= None , dtype
= np
. str_
, encoding
= 'utf8' , names
= [ u
'頻道' , u
'文章' ] )
train_data
. head
( )
train_data
. groupby
( u
'頻道' ) [ u
'頻道' ] . count
( )
train_data
[ u
'文章長度' ] = train_data
[ u
'文章' ] . apply ( len )
train_data
. groupby
( u
'頻道' ) [ u
'文章長度' ] . agg
( [ np
. min , np
. max ] )
~~~~ ? ? ? ? 頻~~ ? ? 道文章0 娛樂 《青蛇》造型師默認新《紅樓夢》額妝抄襲(圖) 凡是看過電影《青蛇》的人,都不會忘記青白二蛇的… 1 娛樂 6.16日劇榜 <最后的朋友> 亮最后殺招成功登頂 《最后的朋友》本周的電視劇排行榜單依然只… 2 娛樂 超乎想象的好看《納尼亞傳奇2:凱斯賓王子》 現時資訊如此發達,搜狐電影評審團幾乎人人在沒有看… 3 娛樂 吳宇森:赤壁大戰不會出現在上集 “希望《赤壁》能給你們不一樣的感覺。”對于自己剛剛拍完的影片… 4 娛樂 組圖:《多情女人癡情男》陳浩民現場耍寶 陳浩民:外面的朋友大家好,現在是搜狐現場直播,歡迎《…
test_data
= pd
. read_csv
( 'data/sohu_test.txt' , sep
= '\t' , header
= None , dtype
= np
. str_
, encoding
= 'utf8' , names
= [ u
'頻道' , u
'文章' ] )
test_data
. head
( )
test_data
. groupby
( u
'頻道' ) [ u
'頻道' ] . count
( )
test_data
[ u
'文章長度' ] = train_data
[ u
'文章' ] . apply ( len )
test_data
. groupby
( u
'頻道' ) [ u
'文章長度' ] . agg
( [ np
. min , np
. max ] )
stopwords
= set ( )
with open ( 'data/stopwords.txt' , 'rb' ) as infile
: for line
in infile
: line
= line
. decode
( 'utf8' ) . rstrip
( '\n' ) if line
: stopwords
. add
( line
. lower
( ) )
二:文檔分詞(精確—全—搜索引擎模式)—詞性標注
2.1 三種不同分詞方式
import jieba text
= u
'小明碩士畢業于中國科學院計算所,后在日本京都大學深造' """
精確模式: 試圖將句子最精確的分開,適合文本分析jieba.lcut,結果返回一個列表jieba.cut,結果返回一個迭代器 全模式: 把句子中所有可以成詞的詞語都掃描出來,速度非常快,但是不能解決歧義 搜索引擎模式:在精確模式的基礎上對長詞再次切分,適合用于搜索引擎分詞
""" print ( u
'精確模式分詞: ' + u
'/' . join
( jieba
. lcut
( text
) ) )
print ( u
'全模式分詞: ' + u
'/' . join
( jieba
. lcut
( text
, cut_all
= True ) ) )
print ( u
'搜索引擎模式: ' + u
'/' . join
( jieba
. lcut_for_search
( text
) ) )
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
依次輸出:
精確模式分詞
: 小明
/ 碩士
/ 畢業
/ 于
/ 中國科學院
/ 計算所
/ ,
/ 后
/ 在
/ 日本京都大學
/ 深造 全模式分詞
: 小
/ 明
/ 碩士
/ 畢業
/ 于
/ 中國
/ 中國科學院
/ 科學
/ 科學院
/ 學院
/ 計算
/ 計算所
// / 后
/ 在
/ 日本
/ 日本京都大學
/ 京都
/ 京都大學
/ 大學
/ 深造 搜索引擎模式
: 小明
/ 碩士
/ 畢業
/ 于
/ 中國
/ 科學
/ 學院
/ 科學院
/ 中國科學院
/ 計算
/ 計算所
/ ,
/ 后
/ 在
/ 日本
/ 京都
/ 大學
/ 日本京都大學
/ 深造
2.2 詞性標注
from jieba
import posseg
as psg text
= u
'小明碩士畢業于中國科學院計算所,后在日本京都大學深造'
"""jieba.posseg.lcut 進行詞性標注結果為 jieba.posseg.pair 類型的列表每個pair對象中,word屬性表示詞語,flag表示詞性詞性符合的解釋可見:https://gist.github.com/luw2007/6016931
""" res
= psg
. lcut
( text
)
print ( 'repr: ' + repr ( res
[ 0 ] ) )
print ( '詞: {}, 詞性: {}' . format ( res
[ 0 ] . word
, res
[ 0 ] . flag
) )
print ( '詞性標注: ' + ' ' . join
( [ '{}/{}' . format ( x
. word
, x
. flag
) for x
in res
] ) )
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
輸出:
repr : pair
( '小明' , 'nr' )
詞
: 小明
, 詞性
: nr
詞性標注
: 小明
/ nr 碩士
/ n 畢業
/ n 于
/ p 中國科學院
/ nt 計算所
/ n ,
/ x 后在
/ t 日本京都大學
/ nt 深造
/ v
三、用 TF-IDF 和詞袋表示文檔特征
import jieba
import pandas
as pd
from sklearn
. feature_extraction
. text
import CountVectorizer
, TfidfTransformer
, TfidfVectorizer contents
= [ u
'小明喜歡看電影,小紅也喜歡看電影。' , u
'小明還喜歡看足球比賽。' ]
stopwords
= { u
',' , u
'。' }
3.1 方法一:使用 CounterVectorizer 和 TfidfTransformer 計算 TF-IDF
"""計算TF(每個詞的出現次數,未歸一)tokenizer: 定義一個函數,接受文本,返回分詞的liststop_words: 定義停用詞詞典,會在結果中刪除詞典中包含的詞
""" tf
= CountVectorizer
( tokenizer
= jieba
. lcut
, stop_words
= stopwords
)
res1
= tf
. fit_transform
( contents
)
tf
. vocabulary_ pd
. DataFrame
( res1
. toarray
( ) , columns
= [ x
[ 0 ] for x
in sorted ( tf
. vocabulary_
. items
( ) , key
= lambda x
: x
[ 1 ] ) ] )
~~ ? ? 也喜歡小明小紅電影看足球比賽還0 1 2 1 1 2 2 0 0 1 0 1 1 0 0 1 1 1
"""use_idf: 表示在TF矩陣的基礎上計算IDF,并相乘得到TF-IDFsmooth_idf: 表示計算IDF時,分子上的總文檔數+1sublinear_tf: 表示使用 1+log(tf)替換原來的tfnorm: 表示對TF-IDF矩陣的每一行使用l2范數歸一化
""" tfidf
= TfidfTransformer
( norm
= 'l2' , use_idf
= True , smooth_idf
= True , sublinear_tf
= False )
res2
= tfidf
. fit_transform
( res1
) tfidf
. idf_
pd
. DataFrame
( res2
. toarray
( ) , columns
= [ x
[ 0 ] for x
in sorted ( tf
. vocabulary_
. items
( ) , key
= lambda x
: x
[ 1 ] ) ] )
~ ? 也喜歡小明小紅電影看足球比賽還0 0.307784 0.437982 0.218991 0.307784 0.615568 0.437982 0.000000 0.000000 1 0.000000 0.379303 0.379303 0.000000 0.000000 0.379303 0.533098 0.533098
3.2 方法二:直接使用 TfidfVectorizer
tfidf
= TfidfVectorizer
( tokenizer
= jieba
. lcut
, stop_words
= stopwords
, norm
= 'l2' , use_idf
= True , smooth_idf
= True , sublinear_tf
= False )
res
= tfidf
. fit_transform
( contents
) tfidf
. idf_
tfidf
. vocabulary_
輸出:
{ '也' : 0 , '喜歡' : 1 , '小明' : 2 , '小紅' : 3 , '電影' : 4 , '看' : 5 , '足球比賽' : 6 , '還' : 7 } pd
. DataFrame
( { '詞' : [ x
[ 0 ] for x
in sorted ( tfidf
. vocabulary_
. items
( ) , key
= lambda x
: x
[ 1 ] ) ] , 'IDF' : tfidf
. idf_
} , columns
= [ '詞' , 'IDF' ] )
輸出:
| | 詞
| IDF
|
| - - - - | - - - - - - - - | - - - - - - - - |
| 0 | 也
| 1.405465 |
| 1 | 喜歡
| 1.000000 |
| 2 | 小明
| 1.000000 |
| 3 | 小紅
| 1.405465 |
| 4 | 電影
| 1.405465 |
| 5 | 看
| 1.000000 |
| 6 | 足球比賽
| 1.405465 |
| 7 | 還
| 1.405465 | pd
. DataFrame
( res
. toarray
( ) , columns
= [ x
[ 0 ] for x
in sorted ( tfidf
. vocabulary_
. items
( ) , key
= lambda x
: x
[ 1 ] ) ] )
~~~ ? ? ? 也喜歡小明小紅電影看足球比賽還0 0.307784 0.437982 0.218991 0.307784 0.615568 0.437982 0.000000 0.000000 1 0.000000 0.379303 0.379303 0.000000 0.000000 0.379303 0.533098 0.533098
四、jieba 分詞
import jieba
article_words
= [ ] for article
in train_data
[ u
'文章' ] : curr_words
= [ ] for word
in jieba
. cut
( article
) : if word
not in stopwords
: curr_words
. append
( word
) article_words
. append
( curr_words
)
seg_word_file
= os
. path
. join
( output_dir
, 'seg_words.txt' )
with open ( seg_word_file
, 'wb' ) as outfile
: for words
in article_words
: outfile
. write
( u
' ' . join
( words
) . encode
( 'utf8' ) + '\n' )
print ( u
'分詞結果保存到文件:{}' . format ( seg_word_file
) )
五、訓練word2vec模型
from gensim
. models
import Word2Vec
from gensim
. models
. word2vec
import LineSentence
sentences
= LineSentence
( seg_word_file
)
"""訓練word2vec模型 參數說明:sentences: 包含句子的list,或迭代器size: 詞向量的維數,size越大需要越多的訓練數據,同時能得到更好的模型alpha: 初始學習速率,隨著訓練過程遞減,最后降到 min_alphawindow: 上下文窗口大小,即預測當前這個詞的時候最多使用距離為window大小的詞max_vocab_size: 詞表大小,如果實際詞的數量超過了這個值,過濾那些頻率低的workers: 并行度iter: 訓練輪數min_count: 忽略出現次數小于該值的詞
""" model
= Word2Vec
( sentences
= sentences
, size
= 100 , iter = 10 , min_count
= 20 )
model_file
= os
. path
. join
( output_dir
, 'model.w2v' )
model
. save
( model_file
)
5.1 word2vec模型的使用
model2
= Word2Vec
. load
( model_file
)
def invest_similar ( * args
, ** kwargs
) : res
= model2
. most_similar
( * args
, ** kwargs
) print u
'\n' . join
( [ u
'{}:{}' . format ( x
[ 0 ] , x
[ 1 ] ) for x
in res
] )
invest_similar
( u
'攝影' , topn
= 1 ) """女人 + 先生 - 男人 = 女士先生 - 女士 = 男人 - 女人,這個向量的方向就代表了性別!"""
invest_similar
( positive
= [ u
'女人' , u
'先生' ] , negative
= [ u
'男人' ] , topn
= 1 )
model2
. similarity
( u
'攝影' , u
'攝像' )
model2
[ u
'攝影' ]
總結
以上是生活随笔 為你收集整理的自然语言(NLP)处理流程—IF-IDF统计—jieba分词—Word2Vec模型训练使用 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。