【问题标题】:Machine Learning Email Prioritization - Python机器学习电子邮件优先级 - Python
【发布时间】:2013-01-18 23:20:27
【问题描述】:

我一直在研究一个 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)

【问题讨论】:

  • 我以前从未使用过 scikit.learn,但在清理数据并获取特征向量后,使用分类器确实可能很“简单”。您示例中的算法似乎是 SVM 分类器。您可能想要检查 scikit.learn SVM 期望的特征向量格式。请注意:您可能不想在特征中包含“排名”,因为有关它的信息已经编码在您分配的“优先级”标签中(即,这是您的目标变量)。
  • 例如,我的特征可能是:发件人地址频率线程活动接收日期(回复之间的时间)正文/主题中的常用词以及要预测的目标类:优先级
  • 是的,没错。还要确保它们都是数字的,即由数字(浮点数,整数)组成。
  • 如果您当前的代码可以根据电子邮件的特征对电子邮件进行排名,那么它已经是一个分类器了。为什么你需要训练另一个人?
  • 是的,很好。但是,您的目标值(或标签,重要/不重要)是通过您使用的当前分类器获得的。所以每个标签都是有偏见的(不是基本事实)。那么你应该如何评估分类错误呢?我的意思是您可能想要手动标记您的电子邮件重要性。

标签: python machine-learning classification ranking scikit-learn


【解决方案1】:

最简单(虽然可能不是最快)的解决方案 (*) 是使用 scikit-learn 的 DictVectorizer。首先,使用 Python 的 csv 模块读取每个示例,并构建一个包含 (feature, value) 对的 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 分类器。

注意:

  1. 当您想对看不见的数据进行预测时,您必须对其应用相同的过程和完全相同的vectorizer 对象。 IE。您必须使用上面的循环构建一个test_dicts 对象,然后执行X_test = vectorizer.transform(test_dicts)

  2. 我假设您想直接预测优先级。相反,预测“排名”将是一个回归问题,而不是分类问题。一些 scikit-learn 分类器有一个 predict_proba 方法,它会产生电子邮件很重要的概率,但你不能训练那些排名靠前的人。

(*) 我是 scikit-learn 的 DictVectorizer 的作者,所以这不是公正的建议。不过是从马嘴里说的:)

【讨论】:

  • 谢谢。我正在实施,但是如果 CSV 数据已经在 CSV 文件中按单词拆分。我想我不需要'split_words'那么这一行会是'for word in row[1]?
  • @ZeeeeeV 您仍然需要以某种方式拆分该字段,因为它将作为单个字符串出现。
  • 好的,谢谢,我现在已经包含了。我能够成功地将数据输入 scikit-learn 分类器并进行预测。但是,如果我想将 70% 的数据用于训练,30% 用于测试,这可能吗?我想我会得到一个错误,X 在预测 30% 时期望每个样本有更多特征?
  • @ZeeeeeV 如果您使用适合训练集的向量器处理测试集,那么没有问题:训练集中没有出现的特征将被忽略。
【解决方案2】:

您可能想看看的另一个库:http://pypi.python.org/pypi/textmining/1.0 (我以前用过)

【讨论】:

    【解决方案3】:

    您能否演示您如何开发代码来从电子邮件中提取数据并对其进行处理以发现最重要的数据。

    发件人地址频率 线程活动 收到日期(回复之间的时间) 正文/主题中的常用词

    【讨论】:

      猜你喜欢
      • 2010-09-14
      • 2020-12-21
      • 2016-02-13
      • 1970-01-01
      • 2016-05-08
      • 2017-03-03
      • 2019-05-14
      • 2013-01-15
      • 2018-04-07
      相关资源
      最近更新 更多