机器学习邮件优先级排序 - Python
我正在开发一个用Python编写的优先邮件收件箱,最终目标是使用机器学习算法来给一些邮件打标签,判断它们是重要的还是不重要的。接下来我会先介绍一些背景信息,然后再说我的问题。
到目前为止,我已经写了代码来提取邮件中的数据,并处理这些数据,以找出最重要的邮件。这是通过以下几个邮件特征来实现的:
- 发件人地址的出现频率
- 邮件线程的活跃度
- 收到邮件的日期(回复之间的时间)
- 邮件正文或主题中的常见词汇
我现在的代码会根据每封邮件的重要性给它们打分(或者说加权),这个分数在0.1到1之间,然后给每封邮件贴上“重要”或“不重要”的标签(在这里用1和0表示)。如果分数大于0.5,就会被认为是优先邮件。这些数据会存储在一个CSV文件中(如下所示)。
From Subject Body Date Rank Priority
test@test.com HelloWorld Body Words 10/10/2012 0.67 1
rest@test.com ByeWorld Body Words 10/10/2012 0.21 0
best@test.com SayWorld Body Words 10/10/2012 0.91 1
just@test.com HeyWorld Body Words 10/10/2012 0.48 0
etc …………………………………………………………………………
我有两组邮件数据(一个用于训练,一个用于测试)。上面提到的内容适用于我的训练邮件数据。现在我正在尝试训练一个学习算法,以便能够预测测试数据的重要性。
为此,我一直在研究SCIKIT和NLTK这两个工具。不过,我在把教程中学到的知识应用到我的项目上时遇到了困难。我对使用哪种学习算法没有特别的要求。这样做是不是很简单?如果是的话,应该怎么做呢?
X, y = email.data, email.target
from sklearn.svm import LinearSVC
clf = LinearSVC()
clf = clf.fit(X, y)
X_new = [Testing Email Data]
clf.predict(X_new)
3 个回答
你能给我演示一下你是怎么写代码,从电子邮件中提取数据并处理这些数据,以找出最重要的信息的吗?
比如:发件人的地址出现的频率、对话的活跃程度、收到邮件的日期(回复之间的时间)、邮件正文或主题中常见的词汇。
你可能还想看看另一个库:http://pypi.python.org/pypi/textmining/1.0 (我以前用过这个库)
最简单(虽然可能不是最快)的解决方案是使用 scikit-learn 的 DictVectorizer
。首先,使用 Python 的 csv
模块读取每个样本,然后构建一个包含 (特征, 值)
对的 dict
,同时将优先级单独保存:
# UNTESTED CODE, may contain a bug or two; also, you need to decide how to
# implement split_words
datareader = csv.reader(csvfile)
dicts = []
y = []
for row in datareader:
y.append(row[-1])
d = {"From": row[0]}
for word in split_words(row[1]):
d["Subject_" + word] = 1
for word in split_words(row[2]):
d["Body_" + word] = 1
# etc.
dicts.append(d)
# vectorize!
vectorizer = DictVectorizer()
X_train = vectorizer.fit_transform(dicts)
现在你有了一个稀疏矩阵 X_train
,可以和 y
一起输入到 scikit-learn 的分类器中。
需要注意的是:
当你想对未见过的数据进行预测时,必须使用相同的步骤和完全相同的
vectorizer
对象。也就是说,你需要使用上面的循环构建一个test_dicts
对象,然后执行X_test = vectorizer.transform(test_dicts)
。我假设你想直接预测优先级。如果你想预测“排名”,那就变成了回归问题,而不是分类问题。一些 scikit-learn 的分类器有一个
predict_proba
方法,可以给出邮件重要性的概率,但你不能用排名来训练这些分类器。
(*) 我是 scikit-learn 的 DictVectorizer
的作者,所以这不是完全客观的建议。不过这是来自第一手的信息,哈哈 :)