Kaggle關(guān)于IMDB情感分類

過去了17天蹦疑,按照學(xué)習(xí)計(jì)劃來說,已經(jīng)嚴(yán)重超時(shí)了萨驶。
主要的問題是在數(shù)據(jù)預(yù)處理部分歉摧。
Kaggle的IMDB情感分析任務(wù)其實(shí)很簡(jiǎn)單,train文件用于訓(xùn)練腔呜,test文件用于測(cè)試叁温。

步驟

  1. 整合train和test(就是說所有語料庫(kù))生成詞袋或詞向量模型。也可以下載已有的word2vec或是glove詞向量模型核畴。
  2. 生成的詞向量模型就是將每一個(gè)詞向量化膝但,方便后面的計(jì)算。依據(jù)生成的詞向量模型對(duì)train和test語料進(jìn)行向量化谤草。
  3. 把向量化的train數(shù)據(jù)和標(biāo)簽輸入分類模型中進(jìn)行預(yù)測(cè)跟束,完成模型訓(xùn)練。
  4. 評(píng)估模型丑孩,并對(duì)test進(jìn)行預(yù)測(cè)冀宴。

具體實(shí)現(xiàn)

1. 數(shù)據(jù)集

數(shù)據(jù)集是tsv格式數(shù)據(jù),說白了是分成了5類:

0 - negative
1 - somewhat negative
2 - neutral
3 - somewhat positive
4 - positive

我們先讀取一下看看温学。TSV文件和CSV的文件的區(qū)別是:前者使用\t作為分隔符略贮,后者使用,作為分隔符。

可以看到總共156060條記錄仗岖,其中打2分的數(shù)據(jù)最多逃延,說明大家都還是很中庸啊。

import pandas as pd
train_data=pd.read_csv(r'C:\Users\jwc19\Desktop\sentiment-analysis-on-movie-reviews\train.tsv',sep='\t',header=0)
test_data=pd.read_csv(r'C:\Users\jwc19\Desktop\sentiment-analysis-on-movie-reviews\test.tsv',sep='\t',header=0)

train_data.head()
image.png
train_data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 156060 entries, 0 to 156059
Data columns (total 4 columns):
PhraseId      156060 non-null int64
SentenceId    156060 non-null int64
Phrase        156060 non-null object
Sentiment     156060 non-null int64
dtypes: int64(3), object(1)
memory usage: 4.8+ MB
train_data.describe()
image.png

以上是數(shù)據(jù)的描述性統(tǒng)計(jì)結(jié)果箩帚,當(dāng)然真友,還可以做一下可視化,這些參考kaggle的泰坦尼克號(hào)任務(wù)操作紧帕。

2. 構(gòu)建word2vec

接下來是要對(duì)語料庫(kù)向量化盔然,這其實(shí)就是一種對(duì)文本特征的抽取。
文中提到了兩種方式:BOW(詞袋)和Word2Vec是嗜,相比而言愈案,Word2Vec所包含的信息更多,而且gensim庫(kù)已經(jīng)打包好了鹅搪,在這里使用word2vec站绪。

在2017年新的特征抽取算法transformer將會(huì)橫掃一切……

在完成詞向量抽取后,將進(jìn)行分類器的訓(xùn)練丽柿。
在這里恢准,我們將train和test數(shù)據(jù)集進(jìn)行合并魂挂,構(gòu)造出一個(gè)維度為200的詞向量模型,使用gensim庫(kù)進(jìn)行構(gòu)建馁筐。

# 合并test和train的數(shù)據(jù)涂召,用于訓(xùn)練詞向量模型
newDf = pd.concat([test_data["Phrase"], train_data["Phrase"]], axis=0) 
newDf.describe()
newDf.to_csv(r"C:\Users\jwc19\Desktop\sentiment-analysis-on-movie-reviews\wordEmbdiing.txt", index=False)

在這里使用gensim的word2vec api來訓(xùn)練模型

主要參數(shù)介紹如下:

  1. sentences:我們要分析的語料,可以是一個(gè)列表敏沉,或者從文件中遍歷讀出(word2vec.LineSentence(filename) )果正。

  2. size:詞向量的維度,默認(rèn)值是100盟迟。這個(gè)維度的取值一般與我們的語料的大小相關(guān)秋泳,如果是不大的語料,比如小于100M的文本語料攒菠,則使用默認(rèn)值一般就可以了迫皱。如果是超大的語料,建議增大維度要尔。

  3. window:即詞向量上下文最大距離舍杜,window越大,則和某一詞較遠(yuǎn)的詞也會(huì)產(chǎn)生上下文關(guān)系赵辕。默認(rèn)值為5既绩,在實(shí)際使用中,可以根據(jù)實(shí)際的需求來動(dòng)態(tài)調(diào)整這個(gè)window的大小还惠。如果是小語料則這個(gè)值可以設(shè)的更小饲握。對(duì)于一般的語料這個(gè)值推薦在[5;10]之間蚕键。

  4. sg:即我們的word2vec兩個(gè)模型的選擇了救欧。如果是0, 則是CBOW模型锣光;是1則是Skip-Gram模型笆怠;默認(rèn)是0即CBOW模型。

  5. hs:即我們的word2vec兩個(gè)解法的選擇了誊爹。如果是0蹬刷, 則是Negative Sampling;是1的話并且負(fù)采樣個(gè)數(shù)negative大于0频丘, 則是Hierarchical Softmax办成。默認(rèn)是0即Negative Sampling。

  6. negative:即使用Negative Sampling時(shí)負(fù)采樣的個(gè)數(shù)搂漠,默認(rèn)是5迂卢。推薦在[3,10]之間。這個(gè)參數(shù)在我們的算法原理篇中標(biāo)記為neg。

  7. cbow_mean:僅用于CBOW在做投影的時(shí)候而克,為0靶壮,則算法中的xw為上下文的詞向量之和,為1則為上下文的詞向量的平均值拍摇。在我們的原理篇中亮钦,是按照詞向量的平均值來描述的。個(gè)人比較喜歡用平均值來表示xw,默認(rèn)值也是1,不推薦修改默認(rèn)值充活。

  8. min_count:需要計(jì)算詞向量的最小詞頻。這個(gè)值可以去掉一些很生僻的低頻詞蜡娶,默認(rèn)是5混卵。如果是小語料,可以調(diào)低這個(gè)值窖张。

  9. iter:隨機(jī)梯度下降法中迭代的最大次數(shù)幕随,默認(rèn)是5。對(duì)于大語料宿接,可以增大這個(gè)值赘淮。

  10. alpha:在隨機(jī)梯度下降法中迭代的初始步長(zhǎng)。算法原理篇中標(biāo)記為η睦霎,默認(rèn)是0.025梢卸。

  11. min_alpha: 由于算法支持在迭代的過程中逐漸減小步長(zhǎng),min_alpha給出了最小的迭代步副女。

from nltk.corpus import stopwords
StopWords = stopwords.words('english')

import logging
import gensim
from gensim.models import word2vec
# 設(shè)置輸出日志
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
sentences=word2vec.LineSentence(r"C:\Users\jwc19\Desktop\sentiment-analysis-on-movie-reviews\wordEmbdiing.txt")
sentences=list(sentences)
for idx,sentence in enumerate(sentences):
    sentence = [w for w in sentence if w not in StopWords]
    sentences[idx]=sentence

print(type(sentences))
model=gensim.models.Word2Vec(sentences,size=200, min_count=2,sg=1,iter=2)
model.wv.save_word2vec_format("./word2Vec02" + ".bin", binary=True) 

搞定之后運(yùn)行模型蛤高,還可以看看效果

model=gensim.models.KeyedVectors.load_word2vec_format("word2Vec.bin",binary=True)
model["flower"]
array([-0.2378106 , -0.00272736,  0.31298155,  0.03572753, -0.32978794,
        0.5877859 ,  0.24954697,  0.10183911,  0.30661255,  0.280979  ,
        0.04722883, -0.01303975,  0.08539272,  0.04781984, -0.17838825,
        0.13571365, -0.07219279,  0.04345001, -0.10493791,  0.05438785,
        0.33817822,  0.15342301, -0.01376961,  0.5400121 ,  0.41749138,
        0.0906916 ,  0.04341062, -0.15571249, -0.17380357, -0.1934123 ,
       -0.02405222, -0.22066571, -0.14180358, -0.09150579, -0.2944634 ,
        0.07576216, -0.1660684 ,  0.20156585,  0.1215609 ,  0.5412449 ,
       -0.1711439 ,  0.3214155 , -0.3667486 , -0.18460636, -0.15220495,
       -0.07949002,  0.22074243, -0.04971108, -0.09505122,  0.29928744,
        0.03575212, -0.13769385,  0.18068919,  0.31546128,  0.10954601,
        0.18582347, -0.04675937, -0.03966061,  0.20546672, -0.04146346,
       -0.0196472 ,  0.0578943 ,  0.20681728, -0.04692319, -0.1698708 ,
       -0.09567603, -0.11117092,  0.30465436, -0.04794674, -0.06839596,
       -0.02868674, -0.20524485,  0.0295146 , -0.01159863, -0.15453497,
        0.48093846, -0.3897168 ,  0.02332748,  0.0439175 ,  0.23415217,
       -0.06639539, -0.03457333, -0.2735414 ,  0.03905383,  0.038656  ,
        0.23679397, -0.33047786,  0.31122783,  0.00199052, -0.30952674,
       -0.10884447, -0.40330866,  0.25768963, -0.16997696,  0.12618165,
       -0.08964632, -0.01782297,  0.12821278,  0.00424662, -0.11926408,
        0.04985361, -0.16177899, -0.06548072, -0.018849  ,  0.07923622,
       -0.00496559, -0.0372107 ,  0.05142358, -0.3297481 ,  0.23669559,
        0.16632096,  0.12055472,  0.36679494,  0.11643603,  0.05669545,
       -0.26389235, -0.06538889,  0.09600764, -0.15645082, -0.00284773,
        0.12941402,  0.08277974,  0.09082151, -0.12873018,  0.13429202,
       -0.00188877, -0.10478543,  0.20682792, -0.18579291, -0.18376978,
       -0.15438502,  0.6078415 , -0.05618986, -0.00372298, -0.34480548,
       -0.00986845,  0.20730568, -0.28601113,  0.08377945,  0.2517998 ,
        0.08157796,  0.24523894, -0.34019017,  0.10557748,  0.02105924,
        0.03729287, -0.52203006,  0.1191924 , -0.32391408, -0.25671792,
       -0.24574052,  0.21722569,  0.05409996, -0.1944298 ,  0.05195828,
       -0.30965397,  0.31671712,  0.23532335,  0.34292328, -0.04460131,
       -0.24952726,  0.1692848 , -0.2680034 , -0.20551267,  0.31070685,
       -0.01980814,  0.24538256,  0.11438795, -0.52290195, -0.25548056,
       -0.12335302, -0.32273138, -0.15207022,  0.03945559, -0.02261233,
       -0.11034735, -0.27235347, -0.17029978, -0.37533283, -0.0962036 ,
       -0.21412134, -0.04120854,  0.12733105, -0.22446166, -0.26129523,
       -0.01468701,  0.24803281,  0.0242933 ,  0.12278723, -0.06079411,
        0.14851114,  0.04741063, -0.16954847, -0.1654084 ,  0.3050954 ,
        0.0125294 , -0.03766926,  0.06326802, -0.11463621, -0.02890763],
      dtype=float32)

到這里,word2vec的生成就已經(jīng)搞定了碑幅。要感謝google的colab戴陡,替我節(jié)省了大量的時(shí)間,我用筆記本跑了4個(gè)小時(shí)的模型沟涨,在colab上只用了幾分鐘……
接下來是將語料庫(kù)進(jìn)行向量化恤批。我在這里卡了有一周,因?yàn)樵谏蓋ord2vec的時(shí)候裹赴,會(huì)將頻率低于2的低頻詞干掉喜庞,但是在語料庫(kù)數(shù)據(jù)向量化的時(shí)候會(huì)遇到低頻詞未登記(UNK)的情況,怎么解決篮昧,查了很多材料赋荆。后來才發(fā)現(xiàn),我特么傻了懊昨,在轉(zhuǎn)換的時(shí)候直接寫判斷過濾掉不就行了……

import logging
import gensim
from gensim.models import word2vec
model=gensim.models.KeyedVectors.load_word2vec_format("./sample_data/word2Vec03.bin",binary=True)

index2word=model.index2word
print(len(index2word))
index2word_set=set(model.index2word)
print(len(index2word_set))
print(model)
# text是輸入的已經(jīng)分好詞的語料庫(kù)文本
# model是之前生成的word2vec模型
# num_features是word2vec模型中每個(gè)詞維度大小窄潭,這里是200
def word2vec(text,model,num_features):
    featureVec = np.zeros((200,),dtype="float32")
    nwords=0
    for word in text:
        if word in index2word_set:
            nwords+=1
            featureVec=np.add(featureVec,model[word])
    featureVec = np.divide(featureVec,nwords)
    return featureVec
# print(word2vec(token))
def getAvgFeatureVecs(phrases,model,num_features):
    counter=0
    phraseFeatureVecs = np.zeros((len(phrases),num_features),dtype="float32")
    for phrase in phrases:
        if counter % 2000==0:
            print("Phrase %d of %d" % (counter, len(phrases)))
        phraseFeatureVecs[counter]=word2vec(phrase, model, num_features)
        counter = counter+1
    return phraseFeatureVecs

from nltk.corpus import stopwords
import re
def phrase_to_wordlist(phrase, remove_stopwords=False):
    phrase_text = re.sub("[^a-zA-Z]"," ", phrase)
    words = phrase_text.lower().split()
    if remove_stopwords:
        stops = set(stopwords.words("english"))
        words = [w for w in words if not w in stops]
    return(words)

clean_train_phrases = []
for phrase in train_data["Phrase"]:
    clean_train_phrases.append( phrase_to_wordlist( phrase, remove_stopwords=True ))
    
num_features=200
trainDataVecs = getAvgFeatureVecs( clean_train_phrases, model, num_features )


clean_test_phrases = []
for phrase in test_data["Phrase"]:
    clean_test_phrases.append( phrase_to_wordlist( phrase, remove_stopwords=True ))
    
num_features=200
testDataVecs = getAvgFeatureVecs( clean_test_phrases, model, num_features )

現(xiàn)在好了吧,可以送進(jìn)去訓(xùn)練了吧。
但是……又遇到問題了嫉你,在使用sklearn訓(xùn)練的時(shí)候報(bào)錯(cuò)

ValueError: Input contains NaN, infinity or a value too large for dtype('float32').

原因是我們?cè)谧稣Z料庫(kù)向量化處理的時(shí)候有一些無意義的評(píng)論月帝,所包含的內(nèi)容都在停用詞之中,向量化之后就變成了空值幽污,所以嚷辅,向量化之后還需要對(duì)數(shù)據(jù)值進(jìn)行空值檢驗(yàn),將其中為空的向量指定一個(gè)缺省值距误。我在這里省事就指定為0了

trainDataVecs[np.isnan(trainDataVecs)] = 0
testDataVecs[np.isnan(testDataVecs)] = 0
from sklearn.ensemble import RandomForestClassifier
forest = RandomForestClassifier( n_estimators = 100 )

print ("Fitting a random forest to labeled training data...")
forest = forest.fit( trainDataVecs, train["Sentiment"] )

訓(xùn)練后進(jìn)行預(yù)測(cè)簸搞,輸出預(yù)測(cè)結(jié)果

# Test & extract results 
result = forest.predict( testDataVecs )

# Write the test results 
output = pd.DataFrame( data={"id":test["PhraseId"], "sentiment":result} )
output.to_csv( "Word2Vec_AverageVectors.csv", index=False, quoting=3 )

到這里大致就完成了,但是准潭,我們希望使用RNN來處理趁俊,接下來就是構(gòu)建LSTM作為分類器。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末刑然,一起剝皮案震驚了整個(gè)濱河市寺擂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌泼掠,老刑警劉巖怔软,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異择镇,居然都是意外死亡挡逼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門沐鼠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挚瘟,“玉大人,你說我怎么就攤上這事饲梭〕烁牵” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵憔涉,是天一觀的道長(zhǎng)订框。 經(jīng)常有香客問我,道長(zhǎng)兜叨,這世上最難降的妖魔是什么穿扳? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮国旷,結(jié)果婚禮上矛物,老公的妹妹穿的比我還像新娘。我一直安慰自己跪但,他們只是感情好履羞,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般忆首。 火紅的嫁衣襯著肌膚如雪爱榔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天糙及,我揣著相機(jī)與錄音详幽,去河邊找鬼。 笑死浸锨,一個(gè)胖子當(dāng)著我的面吹牛唇聘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播柱搜,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼雳灾,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了冯凹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤炒嘲,失蹤者是張志新(化名)和其女友劉穎宇姚,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夫凸,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡浑劳,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了夭拌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片魔熏。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鸽扁,靈堂內(nèi)的尸體忽然破棺而出蒜绽,到底是詐尸還是另有隱情,我是刑警寧澤桶现,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布躲雅,位于F島的核電站,受9級(jí)特大地震影響骡和,放射性物質(zhì)發(fā)生泄漏相赁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一慰于、第九天 我趴在偏房一處隱蔽的房頂上張望钮科。 院中可真熱鬧,春花似錦婆赠、人聲如沸绵脯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽桨嫁。三九已至植兰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間璃吧,已是汗流浹背楣导。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留畜挨,地道東北人筒繁。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像巴元,于是被迫代替她去往敵國(guó)和親毡咏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • BERT發(fā)展史(三)全方位多角度理解Word2Vec 建議先閱讀之前兩篇文章: BERT發(fā)展史(一)從詞嵌入講起 ...
    LITD閱讀 3,430評(píng)論 0 13
  • 前面的文章主要從理論的角度介紹了自然語言人機(jī)對(duì)話系統(tǒng)所可能涉及到的多個(gè)領(lǐng)域的經(jīng)典模型和基礎(chǔ)知識(shí)逮刨。這篇文章呕缭,甚至之后...
    我偏笑_NSNirvana閱讀 13,924評(píng)論 2 64
  • 目前詞向量主要用的技術(shù) word2vec fasttext glove 1 one-host編碼 one-hot編...
    georgeguo閱讀 2,314評(píng)論 0 2
  • 詞向量也稱為詞嵌入,是指將詞轉(zhuǎn)換成為向量的形式修己。 為何需要詞向量 對(duì)于非結(jié)構(gòu)化的數(shù)據(jù):音頻恢总,圖片,文字睬愤。前面兩種的...
    shohokuooo閱讀 9,835評(píng)論 3 51
  • 今天是第四天片仿,我昨天沒有寫日志。因?yàn)閟說撈不到可以不寫不要糊弄尤辱。我倒是沒有糊弄砂豌,直接自我欺騙-_-|| 今天早上我...
    miqiqi閱讀 293評(píng)論 0 0