从标记数据集中提取正则表达式的技术



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

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

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

PS:我知道进行分类的正常方法是使用像SVM之类的机器学习技术。但是,我明确地正在寻找一种生成正则表达式的方法。(我会对生成正则表达式的机器学习技术感到满意,而不是用于进行分类本身的机器学习技术!

这个问题通常被框定为如何从字符串集而不是正则表达式生成有限自动机,尽管你显然可以从 FA 生成 RE,因为它们是等价的。

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

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

以下是一些示例:

请参阅幻灯片 40-44

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

另请参阅

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

对GECCO 2012上展示的系统进行更详细的审查。

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

一个简单的 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]).*$"

最新更新