学习笔记--NLP文本相似度之LCS(最长公共子序列)

6 篇文章 0 订阅
3 篇文章 0 订阅

最长公共子序列

一个序列S任意删除若干个字符得到的新序列T,则T叫做S的子序列

两个序列X和Y的公共子序列中,长度最长的那个,定义为X和Y的最长公共子序列

 例如:

     --字符串12455245576的最长公共子序列为2455

     --字符串acdfg与adfc的最长公共子序列为adf

     --字符串ABCBDAB与BDCABA的最长公共子序列为BCAB或BCBA或BDAB

LCS的作用

  • 生物学家常利用该算法进行基因序列比对,以推测序列的结构、功能和演化过程。
  • 描述两段文字之间的“相似度”
  • 辨别抄袭,对一段文字进行修改之后,计算改动前后文字的最长公共子序列,将除此子序列 外的部分提取出来,该方法判断修改的部分(论文查重)

LCS方法

  1. 暴力穷举法(复杂度高,不可用!)
  2. 动态规划法

数据结构(二维数组)

             --- 当i=0或j=0时,空序列是X 和Y 的最长公共子序列,故C[i,j]=0 ij

  • 使用二维数组C[m,n]
  • C[i,j]记录序列X 和Y 的最长公共子序列的长度 

例子:

  • X = <A,B,C,,B,D,A,B>
  • Y = <B,D,C,A,B,A>

 最长公共子序列为:BCAB、BCBA、BDAB (3个最长公共子序列,长度为4)

相似度=4*2/(6+7)=0.61

实践:

利用MR框架来算LCS文本相似度

首先元数据为

run.sh

HADOOP_CMD="/usr/local/src/hadoop-2.6.1/bin/hadoop"
STREAM_JAR_PATH="/usr/local/src/hadoop-2.6.1//share/hadoop/tools/lib/hadoop-streaming-2.6.1.jar"

INPUT_FILE_PATH_1="/lcs_input.data"
OUTPUT_PATH="/lcs_output"

$HADOOP_CMD fs -rmr -skipTrash $OUTPUT_PATH

# Step 1.
$HADOOP_CMD jar $STREAM_JAR_PATH \
    -input $INPUT_FILE_PATH_1 \
    -output $OUTPUT_PATH \
    -mapper "python map.py" \
    -jobconf "mapred.reduce.tasks=0" \
    -jobconf  "mapred.job.name=mr_lcs" \
    -file ./map.py

map.py

# -*- coding: utf-8 -*-
#!/usr/bin/python

import sys 

def cal_lcs_sim(first_str, second_str):
    len_vv = [[0] * 50] * 50

    first_str = unicode(first_str, "utf-8", errors='ignore')
    second_str = unicode(second_str, "utf-8", errors='ignore')

    len_1 = len(first_str.strip())
    len_2 = len(second_str.strip())

    for i in range(1, len_1 + 1): 
        for j in range(1, len_2 + 1): 
            if first_str[i - 1] == second_str[j - 1]: 
                len_vv[i][j] = 1 + len_vv[i - 1][j - 1]
            else:
                len_vv[i][j] = max(len_vv[i - 1][j], len_vv[i][j - 1]) 

    return float(float(len_vv[len_1][len_2] * 2) / float(len_1 + len_2))


for line in sys.stdin:
    ss = line.strip().split('\t')
    if len(ss) != 2:
        continue
    first_str = ss[0].strip()
    second_str = ss[1].strip()

    sim_score = cal_lcs_sim(first_str, second_str)
    print '\t'.join([first_str, second_str, str(sim_score)])

通过MR框架跑出来的数据为

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小崔崔啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值