通过 gensim 将词向量(Word2Vec)学习机运用于文本分类中,参考文献:Document Classification by Inversion of Distributed Language Representations(ACL 2015)。
首先,我们需要到 kaggle 上的 Yelp recruiting contest 下载我们要用到的数据,可能需要注册并登陆自己的 kaggle 账号。
https://www.kaggle.com/c/yelp-recruiting/download/yelp_training_set.zip
https://www.kaggle.com/c/yelp-recruiting/download/yelp_test_set.zip
接着,解压数据,并从中获取本文需要的有关信息。
在本次分析中,我们将使用一个非常简单的语法解析规则,如下所示:
import re
contractions = re.compile(r"'|-|\"")
# 所有非字符数值
symbols = re.compile(r'(\W+)', re.U)
# 删除单个字符
singles = re.compile(r'(\s\S\s)', re.I|re.U)
# 分隔符(任何空格)
seps = re.compile(r'\s+')
# 文本清洗(注意操作顺序)
def clean(text):
text = text.lower()
text = contractions.sub('', text)
text = symbols.sub(r' \1 ', text)
text = singles.sub(' ', text)
text = seps.sub(' ', text)
return text
# 定义分句函数
alteos = re.compile(r'([!\?])')
def sentences(l):
l = alteos.sub(r' \1 .', l).rstrip("(\.)*\n")
return l.split(".")
然后我们需要将上述规则嵌入一个能够产生带星级评论的评论生成器。
from zipfile import ZipFile
import json
def YelpReviews(label):
with ZipFile("yelp_%s_set.zip"%label, 'r') as zf:
with zf.open("yelp_%s_set/yelp_%s_set_review.json"%(label,label)) as f:
for line in f:
rev = json.loads(line)
yield {'y':rev['stars'],\
'x':[clean(s).split() for s in sentences(rev['text'])]}
例如:
YelpReviews("test").next()
由于文件相对较小,我们可以将其中的所有内容都写入内存列表之中,这将花费一些时间。
revtrain = list(YelpReviews("training"))
print len(revtrain), "training reviews"
## 打乱数据排列顺序
import numpy as np
np.random.shuffle(revtrain)
229907 training reviews
最后,我们还需再写一个函数,以便于我们按语料库顺序找到那些拥有确定星级的评论,并获取其中的每一个句子。
def StarSentences(reviews, stars=[1,2,3,4,5]):
for r in reviews:
if r['y'] in stars:
for s in r['x']:
yield s
首先,我们需要安装一个现成的 Word2Vec 包。
from gensim.models import Word2Vec
import multiprocessing
## 构建一个 w2v 学习机
basemodel = Word2Vec(
workers=multiprocessing.cpu_count(), # 获得你当前的 CPU 的核数
iter=3) # 该项参数的值越大,模型效果越好,构建时消耗的资源也越多
print basemodel
Word2Vec(vocab=0, size=100, alpha=0.025)
通过句子构建词库(我们也可以运用一个外生的无标注词库来对基础模型进行预训练)
basemodel.build_vocab(StarSentences(revtrain))
着,我们对每个基础的模型进行一次 深层复制(deep copy) ,以此来进行评论星级分类的训练。这一步的计算量比较大……
from copy import deepcopy
starmodels = [deepcopy(basemodel) for i in range(5)]
for i in range(5):
slist = list(StarSentences(revtrain, [i+1]))
print i+1, "stars (", len(slist), ")"
starmodels[i].train( slist, total_examples=len(slist) )
以上内容转自 数析学院,原文还包括模型反演以及测试集案例,有需要的同学可以直接查看 原文