4

我正在分析几百万封电子邮件。我的目标是能够将其分类。组可以是例如:

  • 交货问题(交货缓慢、发货前处理缓慢、可用性信息不正确等)
  • 客户服务问题(邮件回复时间慢、回复不礼貌等)
  • 退货问题(退货请求处理缓慢、客户服务缺乏帮助等)
  • 定价投诉(发现隐藏费用等)

为了执行这种分类,我需要一个可以识别词组组合的 NLP,例如:

  • “[他们|公司|公司|网站|商家]”
  • “[没有|没有|没有]”
  • “[回复|回复|回答|回复]”
  • “[在第二天之前|足够快|完全]”
  • 等等

这些示例组中的一些组合应该匹配以下句子:

  • “他们没有回应”
  • “他们根本没有反应”
  • “根本没有回应”
  • “我没有收到网站的回复”

然后将句子归类为客户服务问题

哪个 NLP 能够处理这样的任务?从我读到的这些是最相关的:

  • 斯坦福 CoreNLP
  • 开放式自然语言处理

还要检查这些建议的 NLP 的

4

2 回答 2

3

使用 OpenNLP doccat api,您可以创建训练数据,然后从训练数据中创建模型。与朴素贝叶斯分类器相比,它的优势在于它返回了一组类别的概率分布。

所以如果你用这种格式创建一个文件:

customerserviceproblems They did not respond
customerserviceproblems They didn't respond 
customerserviceproblems They didn't respond at all
customerserviceproblems They did not respond at all
customerserviceproblems I received no response from the website
customerserviceproblems I did not receive response from the website

等等......提供尽可能多的样本,并确保每行以 \n 换行符结尾

使用此方法,您可以添加任何您想要的内容,这意味着“客户服务问题”,您还可以添加任何其他类别,因此您不必过于确定哪些数据属于哪些类别

这是构建模型的java的样子

DoccatModel model = null;
    InputStream dataIn = new FileInputStream(yourFileOfSamplesLikeAbove);
    try {

      ObjectStream<String> lineStream =  
              new PlainTextByLineStream(dataIn, "UTF-8");

      ObjectStream<DocumentSample> sampleStream = new DocumentSampleStream(lineStream);
      model = DocumentCategorizerME.train("en", sampleStream);
      OutputStream modelOut = new BufferedOutputStream(new FileOutputStream(modelOutFile));
      model.serialize(modelOut);
      System.out.println("Model complete!");
    } catch (IOException e) {
      // Failed to read or parse training data, training failed
      e.printStackTrace();
    }

一旦你有了模型,你就可以像这样使用它:

DocumentCategorizerME documentCategorizerME;
  DoccatModel doccatModel; 

doccatModel = new DoccatModel(new File(pathToModelYouJustMade));
   documentCategorizerME = new DocumentCategorizerME(doccatModel);
 /**
 * returns a map of a category to a score
 * @param text
 * @return
 * @throws Exception 
 */
  private Map<String, Double> getScore(String text) throws Exception {
    Map<String, Double> scoreMap = new HashMap<>();
    double[] categorize = documentCategorizerME.categorize(text);
    int catSize = documentCategorizerME.getNumberOfCategories();
    for (int i = 0; i < catSize; i++) {
      String category = documentCategorizerME.getCategory(i);
      scoreMap.put(category, categorize[documentCategorizerME.getIndex(category)]);
    }
    return scoreMap;

  }

然后在返回的 hashmap 中你有你建模的每个类别和一个分数,你可以使用分数来决定输入文本属于哪个类别。

于 2014-01-14T17:42:15.800 回答
2

不完全确定,但我可以想到两种尝试解决问题的方法:

  1. 标准机器学习

    如评论中所述,仅从每封邮件中提取关键字并使用它们训练分类器。预先定义您的相关关键字集,并仅从电子邮件中提取这些关键字(如果存在)。

    这是一种简单但功能强大的技术,不容小觑,因为它在许多情况下会产生非常好的结果。您可能想先尝试这个,因为更复杂的算法可能会过大。

  2. 语法

    如果您真的想深入研究 NLP,根据您的问题描述,您可以尝试定义某种语法并根据该语法解析电子邮件。我在 ruby​​ 方面没有太多经验,但我确信存在某种 lex-yacc 等效工具。快速的网络搜索给出了这个 SO questionthis。通过识别这些短语,您可以通过计算为每个类别找到的短语的比例来判断电子邮件属于哪个类别。

    例如,直观地,语法中的一些产生式可以定义为:

    {organization}{negative}{verb} :- delivery problems
    

    在哪里organization = [they|the company|the firm|the website|the merchant]

这些方法可能是一种开始。

于 2014-01-14T15:07:41.817 回答