我想使用朴素贝叶斯将文档分类为数量相对较多的类。我希望根据该文章是否与已正确验证该实体的文章相似,来确认文章中提及的实体名称是否真的是该实体。
比如说,我们在一篇文章中找到了“通用汽车”这一文本。我们有一组数据,其中包含文章和其中提到的正确实体。因此,如果我们发现新文章中提到的“通用汽车”,它是否应该属于先前数据中包含已知正品的那类文章提及“通用汽车”与未提及该实体的文章类别?
(我不是为每个实体创建一个类,并试图将每篇新文章分类到每个可能的类中。我已经有一种启发式方法来查找实体名称的合理提及,我只想验证有限数量的合理性该方法已经检测到的每篇文章的实体名称提及。)
鉴于潜在的课程和文章的数量非常大,而且朴素贝叶斯相对简单,我想在 sql 中完成整个事情,但是我在评分查询方面遇到了麻烦......
这是我到目前为止所拥有的:
CREATE TABLE `each_entity_word` (
`word` varchar(20) NOT NULL,
`entity_id` int(10) unsigned NOT NULL,
`word_count` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`word`, `entity_id`)
);
CREATE TABLE `each_entity_sum` (
`entity_id` int(10) unsigned NOT NULL DEFAULT '0',
`word_count_sum` int(10) unsigned DEFAULT NULL,
`doc_count` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`entity_id`)
);
CREATE TABLE `total_entity_word` (
`word` varchar(20) NOT NULL,
`word_count` int(10) unsigned NOT NULL,
PRIMARY KEY (`word`)
);
CREATE TABLE `total_entity_sum` (
`word_count_sum` bigint(20) unsigned NOT NULL,
`doc_count` int(10) unsigned NOT NULL,
`pkey` enum('singleton') NOT NULL DEFAULT 'singleton',
PRIMARY KEY (`pkey`)
);
标记数据中的每篇文章都被拆分为不同的单词,并且对于每个实体的每篇文章,每个单词都被添加到each_entity_word
和/或其word_count
递增和doc_count
递增 in entity_word_sum
,两者都相对于 an entity_id
。对于该文章中提到的每个已知实体都重复此操作。
对于每篇文章,无论每个单词中包含的实体如何,total_entity_word
total_entity_word_sum
都类似地递增。
- P(word|any document) 应该等于该
单词
的
word_count
intotal_entity_word
doc_count
total_entity_sum
- P(word|document 提到实体x ) 应该等于
word_count
ineach_entity_word
对于entity_id
x超过doc_count
ineach_entity_sum
对于entity_id
x - P(word|document没有提到实体x ) 应该等于 (
word_count
intotal_entity_word
减去它的word_count
ineach_entity_word
代表那个实体的那个词) 超过 (thedoc_count
intotal_entity_sum
减去doc_count
那个实体 ineach_entity_sum
) - P(文档提及实体x)应该等于
doc_count
该each_entity_sum
实体 id 超过doc_count
intotal_entity_word
- P(文档未提及实体x)应等于 1 减(
doc_count
ineach_entity_sum
代表x的实体 id overdoc_count
intotal_entity_word
)。
对于进来的新文章,将其拆分为单词,然后选择 where word in ('I', 'want', 'to', 'use'...) 反对each_entity_word
or total_entity_word
。在我使用的数据库平台(mysql)中,IN 子句得到了相对较好的优化。
sql 中也没有 product() 聚合函数,所以当然你可以只做 sum(log(x)) 或 exp(sum(log(x))) 来获得 product(x) 的等价物。
因此,如果我收到一篇新文章,将其拆分为不同的单词并将这些单词放入一个大的 IN() 子句和一个潜在的实体 id 进行测试,我怎样才能获得文章落入该实体的朴素贝叶斯概率id在sql中的类?
编辑:
尝试#1:
set @entity_id = 1;
select @entity_doc_count = doc_count from each_entity_sum where entity_id=@entity_id;
select @total_doc_count = doc_count from total_entity_sum;
select
exp(
log(@entity_doc_count / @total_doc_count) +
(
sum(log((ifnull(ew.word_count,0) + 1) / @entity_doc_count)) /
sum(log(((aew.word_count + 1) - ifnull(ew.word_count, 0)) / (@total_doc_count - @entity_doc_count)))
)
) as likelihood,
from total_entity_word aew
left outer join each_entity_word ew on ew.word=aew.word and ew.entity_id=@entity_id
where aew.word in ('I', 'want', 'to', 'use'...);