当前位置: 首页 > 知识库问答 >
问题:

NLP对句子内容进行分类/标记(Ruby绑定必要)

轩辕弘雅
2023-03-14

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

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

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

  • "[他们|公司|公司|网站|商家]"
  • "[没有|没有|没有]"
  • "[回应|回应|回答|回复]"
  • "[在第二天之前|足够快|根本]"
  • 等等

然后,组合中的几个示例组应与以下句子匹配:

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

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

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

  • 斯坦福大学CoreNLP

还可以查看这些建议的NLP。

共有2个答案

任繁
2023-03-14

不完全确定,但我能想到两种方法来解决你的问题:

>

  • 标准机器学习

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

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

    语法

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

    例如,直觉上,语法中的某些结果可以定义为:

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

    其中组织=[他们|公司|公司|网站|商家],等等。

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

  • 岑元徽
    2023-03-14

    使用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换行符结尾

    使用此appoach,您可以添加任何您想要的表示“客户服务问题”的内容,也可以添加任何其他类别,因此您不必过于确定哪些数据属于哪些类别

    这是构建模型的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中,你有你建模的每个类别和一个分数,你可以使用分数来决定输入文本属于哪个类别。

     类似资料:
    • 问题内容: 我一直在阅读有关文本分类的文章,并找到了几种可用于分类的Java工具,但我仍然想知道:文本分类与句子分类一样! 有没有专门针对句子分类的工具? 问题答案: “文本分类”和“句子分类”之间没有形式上的区别。毕竟,句子是一种文本。但是总的来说,当人们谈论文本分类时,恕我直言,他们指的是更大的文本单元,例如文章,评论或演讲。将政治人物的讲话归类为民主人士或共和党人比对推文进行分类要容易得多。

    • 我是thymeleaf的新手,我正试图创建一个web组件。我想要的是这样的东西: 向路易斯问好

    • 文件范围的元数据 reST 有字段列表”field lists” 的概念; 字段序列如下: :fieldname: Field content 文件开端的字段列表会被文档工具解释为文档源信息,通常记录了作者,出版日期等元数据. 在Sphinx中, 在所有标记前面的字段列表将作为文档元数据放在Sphinx 环境中,不显示在输出文档中; 在文档标题后的字段列表仍然是文档源信息的一部分显示在输出文档中.

    • 我试图仅从粗体标记中获取文本,但每当我解析它时,它都会显示完整。我也试图删除a类,但下面遗漏了文本 - “一些随机的副标题”。 我尝试通过: 然后通过检索。

    • 在我的随机测试中,我看到了一个行为,我把一个锚标签放在另一个锚标签里。我做了一个jsfiddle。 但在开发人员工具中,它似乎有所不同: 我相信我们不能将锚定标记放在另一个锚定标记内,因为单击内部锚定将使单击事件冒泡到父锚定标记,这是不允许的。 我的假设正确吗?

    • 如果不存在则创建表(int(11)不为空AUTO_INCREMENT,char(50)不为空,主键())engine=innoDB DEFAULT charset=latin1 AUTO_INCREMENT=11; 表tblcontent 如果不存在(int(11)不为NULL AUTO_INCREMENT,char(100)不为NULL,text不为NULL,date不为NULL,char(50