我正在寻找一种可以测量两个输入文本之间格式相似性的算法(构建分类器)。简而言之,格式上的Levenshtein距离。
例如,考虑让应用程序收集来自不同来源的日志数据,并按照其格式标记它们。
另一个例子考虑一个应用程序,它接收来自不同编程语言的源代码作为源代码(让我们假设它们不相似,所以C和Haskell)并且能够按照它们的格式对它们进行分类。
编辑:其他示例
考虑df -h
运行
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/fedora-root 50G 12G 35G 26% /
devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs 3.9G 596K 3.9G 1% /dev/shm
tmpfs 3.9G 9.1M 3.9G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
tmpfs 3.9G 580K 3.9G 1% /tmp
/dev/mapper/fedora-home 178G 82G 87G 49% /home
/dev/sda1 477M 147M 301M 33% /boot
这将与ls -l
total 68
drwxrwxr-x. 2 mhitza mhitza 4096 May 31 22:17 bin
drwxr-xr-x. 2 mhitza mhitza 4096 Jun 1 23:00 Desktop
drwxr-xr-x. 5 mhitza mhitza 4096 May 16 15:43 Documents
drwxr-xr-x. 12 mhitza mhitza 4096 Jun 4 19:08 Downloads
drwx------. 12 mhitza mhitza 4096 Mar 18 23:48 Dropbox
drwxrwxr-x. 12 mhitza mhitza 4096 Apr 30 02:08 Local
该算法应该能够推断这两个是不同类型的文本“结构”,并能够为这些组分类其他类型的传入文本。
问题在于,对于一组固定的格式,这很容易做到,但我想在任何类型的输入上都这样做。
答案 0 :(得分:1)
根据我对该问题的理解,您希望找到一种表示任意文本的方法,以便可以根据数据的格式/结构对其进行分类或聚类,而不是数据的值。
天真的方法是为已知的文档类型收集一组解析器并按顺序应用它们,但是(除了不实用)我收集你不想这样做,因为你希望这个方法适用任意结构(即:新的或不支持的格式)。
我的第一个想法是,当您尝试根据结构而非内容进行分类时,可以尝试将文档简化为符号表示。
例如df -h
输出:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/fedora-root 50G 12G 35G 26% /
...
会变成:
STRING, SEP, STRING, SEP, STRING, SEP, STRING, SEP, STRING, SEP, STRING
FILEPATH, SEP, MEMSIZE, SEP, MEMSIZE, SEP, MEMSIZE, SEP, PERCENTAGE, SEP, FILEPATH
...
这可以通过应用一组不同的预定义正则表达式(不要忘记“我不知道”正则表达式)来实现。
只需执行此步骤就可以很容易地识别df -h
输出,因为它会有一个标题行和一堆表行,尽管它们具有不同的值,但它们都具有相同的符号表示。
要从中将它变成有用的东西,你可以在其上抛出bag of words model,并将每个符号线作为单个“单词”。
按照这种方法,您可以找到一组可区分的常用“单词”(也就是符号行),您可以使用它们来创建每个文档的数字表示。这可以使用类似term frequency–inverse document frequency之类的东西来完成,但可能会受益于使用监督学习方法(可能类似于递归特征消除)。从那里可以很简单地将它扔进你最喜欢的分类或聚类算法中。
只有问题中给出的示例可能看起来像这样:
ls -l
输出:
total 68
drwxrwxr-x. 2 mhitza mhitza 4096 May 31 22:17 bin
...
将成为ls -l
符号:
STRING, SEP, NUMBERS
STRING, SEP, NUMBER, SEP, STRING, SEP, STRING, SEP, NUMBERS, SEP, STRING, SEP, NUMBER, SEP, TIME, SEP, FILEPATH
...
为简洁起见,我们将这些符号行称为L1
和L2
,并将df -h
符号行D1
和D2
简洁地引用。这意味着我们可以将两个示例文档表示如下:
ls -l: D1:0, D2:0, L1:1, L2:6
df -h: D1:1, D2:8, L1:0, L2:0