我会尽力描述我的想法。
在MS SQL数据库中存储了文本内容。这些内容每天以流的形式传入。一些人每天会浏览这些内容,如果内容符合某些标准,他们会将其标记为已验证。只有一个类别,要么是“有效”,要么不是。
我想基于已验证的内容创建一个模型,保存它,并使用这个模型来“预验证”或标记新传入的内容。同时,定期根据新验证的内容更新模型。希望我已经清楚地解释了我的想法。
我考虑使用Spark流处理来基于创建的模型进行数据分类,并使用朴素贝叶斯算法。但您会如何处理模型的创建、更新和存储呢?大约有20万个已验证的结果(文本),长度各不相同。我需要这么多来构建模型吗?以及如何在Spark流处理中使用这个模型呢?
提前感谢您。
回答:
哇,这个问题非常宽泛,与机器学习
的关系比与Apache Spark
的关系更密切,不过我会尝试给你一些提示或步骤(我不会替你做所有的工作)。
-
导入你需要的所有库
from pyspark.mllib.classification import LogisticRegressionWithSGD, LogisticRegressionModelfrom pyspark.mllib.linalg import SparseVectorfrom pyspark.mllib.regression import LabeledPointimport re
-
将你的数据加载到RDD中
msgs = [("我爱星球大战但今天不能看", 1.0), ("我不爱星球大战而且人们今天想看", 0.0), ("我不喜欢不能看星球大战", 1.0), ("爱星球大战的人是我的朋友", 1.0), ("我更喜欢在Netflix上看星球大战", 0.0), ("乔治·卢卡斯不应该卖掉这个系列", 1.0), ("迪士尼制作的电影比其他人都好", 0.0)]rdd = sc.parallelize(msgs)
-
标记化你的数据(如果你使用ML,可能会更容易)
rdd = rdd.map(lambda (text, label): ([w.lower() for w in re.split(" +", text)], label))
-
删除所有不必要的词(通常称为停用词)和符号,例如
,.&
commons = ["和", "但", "到"]rdd = rdd.map(lambda (tokens, label): (filter(lambda token: token not in commons, tokens), label))
-
创建一个包含整个数据集中所有
distinct
词的字典,听起来很大,但实际上并没有你想象的那么多,我敢打赌它们能装进你的主节点(然而还有其他处理方法,但为了简单起见,我会保持这种方式)。# 查找不同的词words = rdd.flatMap(lambda (tokens, label): tokens).distinct().collect()diffwords = len(words)
-
将你的
features
转换为DenseVector或SparseVector,我显然推荐第二种方式,因为通常SparseVector
需要更少的空间来表示,但这取决于数据。注意,有更好的替代方案如hashing
,但我试图保持我冗长的方法忠诚。之后将tuple
转换为LabeledPointdef sparsify(length, tokens): indices = [words.index(t) for t in set(tokens)] quantities = [tokens.count(words[i]) for i in indices] return SparseVector(length, [(indices[i], quantities[i]) for i in xrange(len(indices))])rdd = rdd.map(lambda (tokens, label): LabeledPoint(label, sparsify(diffwords, tokens)))
-
拟合你喜欢的模型,在这种情况下,我由于后续的动机使用了LogisticRegressionWithSGD。
lrm = LogisticRegressionWithSGD.train(rdd)
-
保存你的模型。
lrm.save(sc, "mylovelymodel.model")
-
加载你的LogisticRegressionModel到另一个应用程序中。
lrm = LogisticRegressionModel.load(sc, "mylovelymodel.model")
-
预测类别。
lrm.predict(SparseVector(37,[2,4,5,13,15,19,23,26,27,29],[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0]))# 输出 0
请注意,我没有评估模型的准确性
,不过看起来很不错,不是吗?