我想使用朴素的贝叶斯将文档分类为相对大量的类。我想确认一篇文章中的实体名称是否真的是该实体,这是基于该文章是否与该实体已被正确验证的文章类似。
说,我们在一篇文章中找到了“通用汽车”的文字。我们有一组数据,其中包含文章和内部提到的正确实体。因此,如果我们在新文章中找到“通用汽车”,那么它是否属于先前数据中包含已知正版的那类文章提及“通用汽车”与没有提到该实体的文章类别?
(我不是为每个实体创建一个类,并试图将每篇新文章分类到每个可能的类中。我已经有了一种启发式方法来查找实体名称的合理提及,我只想验证其中的合理性。该方法已检测到的每篇文章的实体名称数量有限。)
鉴于潜在的类和文章的数量非常大而朴素的贝叶斯相对简单,我想在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
为相对于entity_word_sum
,entity_id
增加total_entity_word
。对于该文中已知的每个实体,都会重复这一过程。
对于每篇文章,无论每个单词total_entity_word_sum
word_count
中包含的实体如何,都会同样增加。
total_entity_word
doc_count
中的total_entity_sum
word_count
each_entity_word
entity_id
in
对于doc_count
x 而言each_entity_sum
以上entity_id
的{{1}}
word_count
x total_entity_word
word_count
中的each_entity_word
减去doc_count
在total_entity_sum
中针对该实体的该字词)(doc_count
中的each_entity_sum
减去doc_count
中该each_entity_sum
的{{1}} doc_count
total_entity_word
doc_count
each_entity_sum
doc_count
{/ 1}}
total_entity_word
each_entity_word
x 的实体ID超过{ {1}}中的{1}}。对于一篇新文章,将其拆分为单词,然后只选择('我','想要','到','使用'...)中的单词对total_entity_word
或{ {1}}。在db平台中,我正在使用(mysql)IN子句进行了相对较好的优化。
在sql中也没有product()聚合函数,所以当然你可以只使用sum(log(x))或exp(sum(log(x)))来得到product(x)的等价物。
所以,如果我收到一篇新文章,将其分成不同的单词,并将这些单词放入一个大的IN()子句和一个潜在的实体id进行测试,我怎样才能得到文章落下的天真贝叶斯概率进入sql中的实体id的类?
编辑:
尝试#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'...);
答案 0 :(得分:6)
使用R到Postgres(或MySQL等)界面
或者,我建议使用已建立的stats包以及db的连接器。如果您想从Naive Bayes切换到更复杂的东西,这将使您的应用程序更加灵活:
http://rpgsql.sourceforge.net/
bnd.pr> data(airquality)
bnd.pr> db.write.table(airquality, no.clobber = F)
bnd.pr> bind.proxy("airquality")
bnd.pr> summary(airquality)
Table name: airquality
Database: test
Host: localhost
Dimensions: 6 (columns) 153 (rows)
bnd.pr> print(airquality)
Day Month Ozone Solar.R Temp
1 1 5 41 190 67
2 2 5 36 118 72
3 3 5 12 149 74
4 4 5 18 313 62
5 5 5 NA NA 56
6 6 5 28 NA 66
7 7 5 23 299 65
8 8 5 19 99 59
9 9 5 8 19 61
10 10 5 NA 194 69
Continues for 143 more rows and 1 more cols...
bnd.pr> airquality[50:55, ]
Ozone Solar.R Wind Temp Month Day
50 12 120 11.5 73 6 19
51 13 137 10.3 76 6 20
52 NA 150 6.3 77 6 21
53 NA 59 1.7 76 6 22
54 NA 91 4.6 76 6 23
55 NA 250 6.3 76 6 24
bnd.pr> airquality[["Ozone"]]
[1] 41 36 12 18 NA 28 23 19 8 NA 7 16 11 14 18 14 34 6
[19] 30 11 1 11 4 32 NA NA NA 23 45 115 37 NA NA NA NA NA
[37] NA 29 NA 71 39 NA NA 23 NA NA 21 37 20 12 13 NA NA NA
[55] NA NA NA NA NA NA NA 135 49 32 NA 64 40 77 97 97 85 NA
[73] 10 27 NA 7 48 35 61 79 63 16 NA NA 80 108 20 52 82 50
[91] 64 59 39 9 16 78 35 66 122 89 110 NA NA 44 28 65 NA 22
[109] 59 23 31 44 21 9 NA 45 168 73 NA 76 118 84 85 96 78 73
[127] 91 47 32 20 23 21 24 44 21 28 9 13 46 18 13 24 16 13
[145] 23 36 7 14 30 NA 14 18 20
然后,您需要安装e1071软件包才能使用Naive Bayes。在R提示符下:
[ramanujan:~/base]$R
R version 2.7.2 (2008-08-25)
Copyright (C) 2008 The R Foundation for Statistical Computing
ISBN 3-900051-07-0
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.
R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.
Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.
~/.Rprofile loaded.
Welcome at Sun Apr 19 00:45:30 2009
> install.packages("e1071")
> install.packages("mlbench")
> library(e1071)
> ?naiveBayes
> example(naiveBayes)
更多信息:
答案 1 :(得分:2)
这是SQL Server的简单版本。我在一个免费的SQL Express实现上运行它,它非常快。
http://sqldatamine.blogspot.com/2013/07/classification-using-naive-bayes.html
答案 2 :(得分:0)
我没有时间计算NB
公式的所有表达式,但这是主要的想法:
SET @entity = 123;
SELECT EXP(SUM(LOG(probability))) / (EXP(SUM(LOG(probability))) + EXP(SUM(LOG(1 - probability))))
FROM (
SELECT @entity AS _entity,
/* Above is required for efficiency, subqueries using _entity will be DEPENDENT and use the indexes */
(
SELECT SUM(word_count)
FROM total_entity_word
WHERE word = d.word
)
/
(
SELECT doc_count
FROM each_entity_sum
WHERE entity_id = _entity
) AS pwordentity,
/* I've just referenced a previously selected field */
(
SELECT 1 - pwordentity
) AS pwordnotentity,
/* Again referenced a previously selected field */
... etc AS probability
FROM total_entity_word
) q
请注意,您可以通过在相关子查询中使用它们来轻松引用SELECT
中的上一个字段(如示例所示)。
答案 3 :(得分:0)
如果使用Oracle,则内置数据挖掘
我不确定你正在运行什么数据库,但是如果你使用的是Oracle,数据挖掘功能会被纳入数据库:
http://www.oracle.com/technology/products/bi/odm/index.html
......包括Naive Bayes:
http://download.oracle.com/docs/cd/B28359_01/datamine.111/b28129/algo_nb.htm
以及其他一些人:
http://www.oracle.com/technology/products/bi/odm/odm_techniques_algorithms.html
这对我来说很惊讶。绝对是Oracle在该领域开源替代方案中的竞争优势之一。
答案 4 :(得分:0)
这是一篇博文,详细介绍了您要查找的内容:http://nuncupatively.blogspot.com/2011/07/naive-bayes-in-sql.html
我在SQL中编写了许多版本的NB分类器。上面提到的改变分析包的答案不能扩展到我的大数据和处理时间要求。我有一个表,每个单词/类组合有一行(nrows =单词*类)和一个系数列。我有另一个表格,其中包含document_id和word的列。我只是将这些表一起加入单词,按文档分组,并对系数求和,然后调整类概率的总和。这给我留下了一个document_id,class,score表。然后我选择了最低分(因为我做了一个补充天真的贝叶斯方法,我发现在多类情况下效果更好)。
作为旁注,我发现许多转换/算法修改大大改善了我的保持预测。他们在Jason Rennie关于“解决朴素贝叶斯文本分类器的可怜假设”的工作中进行了描述,并在此总结:http://www.ist.temple.edu/~vucetic/cis526fall2007/liang.ppt