如果你真的要引入 400 万个15,000 个特征来分析大概十几个词,那么大部分特征都不会被使用。这建议使用某种基于磁盘的数据库来代替功能,并仅提取您需要的那些。即使对于一个长句子和一个低效的数据库,4 次搜索 x 50 个单词仍然比您现在看到的要少得多——在最坏的情况下可能是数百毫秒,但肯定不会是多秒。
首先查看带有 NDBM 或 GDBM 后端的 anydbm,然后根据熟悉程度和可用性考虑其他后端。
您的后续 cmet 似乎表明对您正在做什么和/或事情应该如何运作存在基本的误解。让我们用词典中的五个单词做一个简单的例子。
# training
d = { 'good': 1, 'bad': -1, 'excellent': 1, 'poor': -1, 'great': 1 }
c = classifier(d)
with open(f, "classifier.pickle", "w") as f:
pickle.dump(c, f)
sentences = ['I took a good look', 'Even his bad examples were stunning']
# classifying, stupid version
for sentence in sentences:
with open(f, "classifier.pickle", "r") as f:
c = pickle.load(f)
sentiment = c(sentence)
# basically, for word in sentence.split(): if word in d: sentiment += d[word]
print sentiment, sentence
# classifying, slightly less stupid version
with open(f, "classifier.pickle", "r") as f:
c = pickle.load(f)
# FastCGI init_end here
for sentence in sentences:
sentiment = c(sentence)
print sentiment, sentence
愚蠢的版本似乎是你目前正在经历的。稍微不那么愚蠢的版本加载分类器一次,然后在每个输入句子上运行它。这就是 FastCGI 将为您做的事情:您可以在进程启动中执行一次加载部分,然后运行一个服务,在输入语句进入时运行它。这很节省资源,但需要做一些工作,因为将您的脚本转换为 FastCGI 并设置服务器基础架构很麻烦。如果您期望大量使用,那绝对是您的最佳选择。
但请注意,模型中的五个特征中实际上只需要两个特征。句子中的大多数单词没有情感分数,并且情感数据库中的大多数单词不需要为这些输入计算分数。因此,数据库实现看起来会类似于(DBM 部分的粗略伪代码)
with opendbm("sentiments.db") as d:
for sentence in sentences:
sentiment = 0
for word in sentence.split():
try:
sentiment += d[word]
except KeyError:
pass
print sentiment, sentence
每笔交易的成本较高,因此不如 FastCGI 版本优化,后者仅在启动时将整个模型加载到内存中;但它不需要你保持状态或设置 FastCGI 基础设施,而且它比为每个句子加载整个模型的愚蠢版本要高效得多。
(实际上,对于没有 FastCGI 的 Web 服务,您可以在 for 中有效地使用 opendbm,而不是相反。)