【问题标题】:Techniques for extracting regular expressions out of a labeled data set从标记数据集中提取正则表达式的技术
【发布时间】:2012-05-31 05:32:00
【问题描述】:

假设我有一个包含数十万个字符串(如果重要的话,恰好是自然语言句子)的数据集,每个字符串都带有特定的“标签”。每个句子只标记一个标签,大约有 10 个标签,每个标签大约有 10% 的数据集属于它们。标签内的句子结构具有高度相似性。

我知道以上听起来像是机器学习问题的经典示例,但我想问一个稍微不同的问题。 是否有任何已知的技术可以以编程方式为每个标签生成一组正则表达式,这些技术可以成功地对训练数据进行分类,同时仍能推广到未来的测试数据?

我会很高兴参考文献;我意识到这不是一个简单的算法:)

PS:我知道进行分类的常规方法是使用 SVM 等机器学习技术。然而,我正在明确地寻找一种生成正则表达式的方法。 (我会喜欢机器学习技术来生成正则表达式,而不是机器学习技术来进行分类本身!)

【问题讨论】:

  • 您总是可以简单地构建简单的正则表达式:(A|B|C) label 1. (D|E|F) label 2 etc. 其中 A、B、C 等是项目
  • 是的,但这会使“同时仍能推广到未来的测试数据”条件失败:)
  • 我很想建议的另一个解决方案是使用 GA 来构建您的正则表达式 - 适应度函数可以很简单,突变/交叉阶段也可以,但这似乎有点过头了至少可以这么说。
  • 我可能会在稍后写下它作为答案。我可以看到的另一个选项是采用longest common subsequence problem 并解决一个修改后的“最长类特定公共子序列”变体,但解决这个问题看起来很棘手。

标签: regex algorithm nlp machine-learning


【解决方案1】:

这个问题通常被描述为如何从字符串集合而不是正则表达式生成有限自动机,尽管您显然可以从 FA 生成 RE,因为它们是 equivalent

如果您搜索自动机归纳法,您应该能够找到很多关于这个主题的文献,包括 GA 方法。

【讨论】:

    【解决方案2】:

    据我所知,这是当前进化计算研究的主题。

    这里有一些例子:

    参见幻灯片 40-44

    https://cs.byu.edu/sites/default/files/Ken_De_Jong_slides.pdf (在发布此答案时存在幻灯片)。

    另见

    http://www.citeulike.org/user/bartolialberto/article/10710768

    更详细地回顾 GECCO 2012 上展示的系统。

    【讨论】:

      【解决方案3】:

      注意: 也许这会有所帮助。下面的函数为ab 的给定值生成正则表达式模式。其中ab 都是字母字符串。该函数将生成一个公平的RegEx 模式以匹配ab 之间的范围。该函数只需要前三个字符来生成模式并生成一个result,它可能类似于某种语言中的starts-with() 函数,带有一般RegEx 支持的暗示。

      一个简单的 VB.NET 示例

      Public Function GetRangePattern(ByVal f_surname As String, ByVal l_surname As String) As String
              Dim f_sn, l_sn As String
              Dim mnLength% = 0, mxLength% = 0, pdLength% = 0, charPos% = 0
              Dim fsn_slice$ = "", lsn_slice$ = ""
              Dim rPattern$ = "^"
              Dim alphas As New Collection
              Dim tmpStr1$ = "", tmpStr2$ = "", tmpStr3$ = ""
      
              '///init local variables
              f_sn = f_surname.ToUpper.Trim
              l_sn = l_surname.ToUpper.Trim
      
              '///do null check
              If f_sn.Length = 0 Or l_sn.Length = 0 Then
                  Return "-!ERROR!-"
              End If
      
              '///return if both equal
              If StrComp(f_sn, l_sn, CompareMethod.Text) = 0 Then
                  Return "^" & f_sn & "$"
              End If
      
              '///return if 1st_name present in 2nd_name
              If InStr(1, l_sn, f_sn, CompareMethod.Text) > 0 Then
                  tmpStr1 = f_sn
                  tmpStr2 = l_sn.Replace(f_sn, vbNullString)
                  If Len(tmpStr2) > 1 Then
                      tmpStr3 = "[A-" & tmpStr2.Substring(1) & "]*"
                  Else
                      tmpStr3 = tmpStr2 & "*"
                  End If
                  tmpStr1 = "^" & tmpStr1 & tmpStr3 & ".*$"
                  tmpStr1 = tmpStr1.ToUpper
                  Return tmpStr1
              End If
      
              '///initialize alphabets
              alphas.Add("A", CStr(Asc("A")))
              alphas.Add("B", CStr(Asc("B")))
              alphas.Add("C", CStr(Asc("C")))
              alphas.Add("D", CStr(Asc("D")))
              alphas.Add("E", CStr(Asc("E")))
              alphas.Add("F", CStr(Asc("F")))
              alphas.Add("G", CStr(Asc("G")))
              alphas.Add("H", CStr(Asc("H")))
              alphas.Add("I", CStr(Asc("I")))
              alphas.Add("J", CStr(Asc("J")))
              alphas.Add("K", CStr(Asc("K")))
              alphas.Add("L", CStr(Asc("L")))
              alphas.Add("M", CStr(Asc("M")))
              alphas.Add("N", CStr(Asc("N")))
              alphas.Add("O", CStr(Asc("O")))
              alphas.Add("P", CStr(Asc("P")))
              alphas.Add("Q", CStr(Asc("Q")))
              alphas.Add("R", CStr(Asc("R")))
              alphas.Add("S", CStr(Asc("S")))
              alphas.Add("T", CStr(Asc("T")))
              alphas.Add("U", CStr(Asc("U")))
              alphas.Add("V", CStr(Asc("V")))
              alphas.Add("W", CStr(Asc("W")))
              alphas.Add("X", CStr(Asc("X")))
              alphas.Add("Y", CStr(Asc("Y")))
              alphas.Add("Z", CStr(Asc("Z")))
      
              '///populate max-min length values
              mxLength = f_sn.Length
              If l_sn.Length > mxLength Then
                  mnLength = mxLength
                  mxLength = l_sn.Length
              Else
                  mnLength = l_sn.Length
              End If
              '///padding values
              pdLength = mxLength - mnLength
              f_sn = f_sn.PadRight(mxLength, "A")
              'f_sn = f_sn.PadRight(mxLength, "~")
              l_sn = l_sn.PadRight(mxLength, "Z")
              'l_sn = l_sn.PadRight(mxLength, "~")
      
              '///get a range like A??-B??
              If f_sn.Substring(0, 1).ToUpper <> l_sn.Substring(0, 1).ToUpper Then
                  fsn_slice = f_sn.Substring(0, 3).ToUpper
                  lsn_slice = l_sn.Substring(0, 3).ToUpper
                  tmpStr1 = fsn_slice.Substring(0, 1) & fsn_slice.Substring(1, 1) & "[" & fsn_slice.Substring(2, 1) & "-Z]"
                  tmpStr2 = lsn_slice.Substring(0, 1) & lsn_slice.Substring(1, 1) & "[A-" & lsn_slice.Substring(2, 1) & "]"
                  tmpStr3 = "^(" & tmpStr1 & "|" & tmpStr2 & ").*$"
                  Return tmpStr3
              End If
      
              '///looping charwise
              For charPos = 0 To mxLength
                  fsn_slice = f_sn.Substring(charPos, 1)
                  lsn_slice = l_sn.Substring(charPos, 1)
                  If StrComp(fsn_slice, lsn_slice, CompareMethod.Text) = 0 Then
                      rPattern = rPattern & fsn_slice
                  Else
                      'rPattern = rPattern & "("
                      If charPos < mxLength Then
                          Try
                              If Asc(fsn_slice) < Asc(lsn_slice) Then
                                  tmpStr1 = fsn_slice & "[" & f_sn.Substring(charPos + 1, 1) & "-Z" & "]|"
                                  If CStr(alphas.Item(Key:=CStr(Asc(fsn_slice) + 1))) < CStr(alphas.Item(Key:=CStr(Asc(lsn_slice) - 1))) Then
                                      tmpStr2 = "[" & CStr(alphas.Item(Key:=CStr(Asc(fsn_slice) + 1))) & "-" & CStr(alphas.Item(Key:=CStr(Asc(lsn_slice) - 1))) & "]|"
                                  Else
                                      tmpStr2 = vbNullString
                                  End If
                                  tmpStr3 = lsn_slice & "[A-" & l_sn.Substring(charPos + 1, 1) & "]"
                                  rPattern = rPattern & "(" & tmpStr1 & tmpStr2 & tmpStr3 & ").*$"
                                  'MsgBox("f_sn:= " & f_sn & " -- l_sn:= " & l_sn & vbCr & rPattern)
                                  Exit For
                              Else
                                  Return "-#ERROR#-"
                              End If
                          Catch ex As Exception
                              Return "-|ERROR|-" & ex.Message
                          End Try
                      End If
                  End If
              Next charPos
              Return rPattern
          End Function
      

      它被称为

      ?GetRangePattern("ABC","DEF")
      

      产生这个

      "^(AB[C-Z]|DE[A-F]).*$"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-21
        相关资源
        最近更新 更多