Coggle 30 Days of ML(23年1月)打卡

目录

任务1:数据集读取

1.1 简介

1.2代码部分

任务2:文本数据分析

2.1任务介绍

2.2代码部分

任务3:文本相似度(统计特征)

3.1任务描述

3.2代码实现

任务1:数据集读取

  • 1.1 简介

  • 自然语言处理(Natural Language Processing, NLP)是计算机科学、人工智能和语言学的交叉领域,其目标是使计算机能够理解、生成和处理人类语言。常见的 NLP 技术包括语音识别、文本分析、机器翻译等。这些技术都是基于人工智能和机器学习的算法来实现的。

    文本匹配是自然语言处理中的一种常见任务。它可以用来判断两个文本之间的相似度或相关性。常见的文本匹配任务包括:文本相似性匹配、问答匹配、查询-文档匹配等。这些任务的具体实现可以使用机器学习技术,例如使用神经网络模型进行文本嵌入,然后使用余弦相似度或其他相似度度量来计算文本之间的相似度。

    LCQMC(Large-scale Chinese Question Matching Corpus)是一个大规模的中文文本匹配数据集。它包含超过 400,000 个标记为重复或非重复的问题对。该数据集由中国科学院自动化研究所(CASIA)深度学习技术与应用国家工程实验室(NEL-DLT)创建。

    LCQMC 数据集中的问题涵盖广泛的主题,并以口语化的中文编写,使其成为文本匹配模型具有挑战性的数据集。该数据集通常用于训练和评估各种中文文本匹配模型的性能,例如基于神经网络的模型。它还用于中文自然语言处理的研究,例如文本匹配、文本分类和其他 NLP 任务。该数据集为研究人员提供了一个基准,用于评估其模型的性能并将其与最先进的方法进行比较。

  • 1.2代码部分

  • #读取LCQMC数据集,为方便运行,将数据集保存在本地文件夹
    data = pd.read_csv('LCQMC.test.data/LCQMC.test.data',
            sep='\t', names=['query1', 'query2', 'label'])
    
    #按照80%、10%、10%划分训练集、验证集和测试集
    train = data[:10000]
    valid = data[10000:11250]
    test = data[11250:12500]
    #查看数据集
    print("-------------------------数据集为-------------------------")
    print(data)
    
    #查看他们的形状
    print('数据集',data.shape)
    print('测试集',train.shape)
    print('验证集',valid.shape)
    print('测试集',test.shape)
    #查看数据类型
    print(type(data))
    print(train)

     

     

  • 任务1结束

任务2:文本数据分析

2.1任务介绍

  • 步骤1:分析赛题文本长度,相似文本对与不相似文本对的文本长度是否存在差异?
  • 步骤2:分析赛题单词和字符个数,在所有文本中包含多少个单词(用jieba进行分析)和字符?

在LCQMC数据集中数据采用三列进行存储,其中label为是否含义相同的标签。在任务2中我们希望各位同学,能对中文文本进出初步的分析,找到相似文本对和不相似文本对的差异。

query1query2label
0喜欢打篮球的男生喜欢什么样的女生爱打篮球的男生喜欢什么样的女生1
1我手机丢了,我想换个手机我想买个新手机,求推荐1
2大家觉得她好看吗大家觉得跑男好看吗?0

jieba是一个中文分词库,用于将中文句子分解为词组。它使用了基于前缀词典的最大匹配算法,并支持用户自定义词典。要使用Jieba库,首先需要安装它。使用 pip 可以轻松安装:

pip install jieba

安装完成后,可以使用下面的代码对句子进行分词:

import jieba
sentence = "我在学习使用jieba分词"
seg_list = jieba.cut(sentence)
print(" ".join(seg_list))

输出结果是:我 在 学习 使用 jieba 分词。还可以使用jieba.lcut() or jieba.lcut_for_search() 获取词组列表。

2.2代码部分

将字符串长度和长度差写入data

#ql = query len,lc = length 差
data.insert(data.shape[1], 'ql1', 0)
data.insert(data.shape[1], 'ql2', 0)
data.insert(data.shape[1], 'lc', 0)
for i in range(len(data)):
    data['ql1'][i] = len(data.query1[i])
    data['ql2'][i] = len(data.query2[i])
    data['lc'][i] = abs(len(data.query2[i]) - len(data.query1[i]))

将训练集按照标签划分两部分,将长度差计入程序 ,其中label为1的共5012个,label为4988个

label1 = train[train.label == 1]
label0 = train[train.label == 0]

print(label1)
print(label0)

#重新标号
label1.index = range(0,len(label1))
label0.index = range(0,len(label0))

print(label0)
print(label1)

#转化为列表
c1 = label1['lc'].values.tolist()
c0 = label0['lc'].values.tolist()
#print(c1)
#print(c0)

画图查看,开始查看整个训练集,发现数据过大,后筛选前一百个

fig = plt.figure()
ax1 = fig.add_subplot(1,2,1)
plt.plot(c1[:100],'g--')
ax2 = fig.add_subplot(1,2,2)
plt.plot(c0[:100],'k--')
#plt.show()

整体效果如下图所示: 

 

 

 发现看不出来什么区别,进行长度差统计,其中差别超过10的按10计算,差别从0到10,可得

虽然大致相同,但是随着差别越来越大,不相似的概率也越来越大。

对单词进行划分、计数,其代码为

#统计测试集中单词
CoSentence1 = train['query1'].drop_duplicates().values.tolist()
CoSentence2 = train['query2'].drop_duplicates().values.tolist()
CoSentence = CoSentence1 + CoSentence2
#print(CoSentense)

word2index = {}
word2count = {}
index2word = {}
n_words = 0
for pair in CoSentence:
    seg_list = jieba.cut(pair)
    for word in seg_list:
        if word not in word2index:
            word2index[word] = n_words
            word2count[word] = 1
            index2word[n_words] = word
            n_words += 1
        else:
            word2count[word] += 1
print(n_words)
print(word2index)
print('------------------------------------')
print(word2count)

构建字典成果,将9102个词组计入字典中:

 接着是其出现的频率:

  • 任务2结束 

任务3:文本相似度(统计特征)

3.1任务描述

  • 步骤1:对query1和query2计算文本统计特征
    • query1和query2文本长度
    • query1和query2文本单词个数
    • query1和query2文本单词差异
    • query1和query2文本最长公用字符串长度
    • query1和query2文本的TFIDF编码相似度
    • 步骤2:根据相似度标签,上述哪一个特征最有区分性?

文本统计特征是指对文本进行统计并得到的一些数值,可以用来描述文本的特征。基础的文本特征包括:

    文本长度: 文本中的字符数或单词数
    字符频率: 每个字符在文本中出现的次数或频率
    单词频率: 每个单词在文本中出现的次数或频率
    句子长度: 文本中句子的平均长度
    句子数量: 文本中句子的数量

上述文本特征都是无监督的,不局限语言和模型,而且计算快速,在任务3中我们需要大家使用python统计相似的文本和不相似文本的基础统计特征。

3.2代码部分

  • query1和query2文本长度
ql1 = label1['ql1'].values.tolist()
ql2 = label0['ql2'].values.tolist()
#qln1:ql1的字符数统计
qln1 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
j = 0
for j in range(len(ql1)):
    qln1[ql1[j]] = qln1[ql1[j]] + 1
print(qln1)

#qln2:ql2的字符数统计
qln2 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
k = 0
for k in range(len(ql2)):
    qln2[ql2[k]] = qln2[ql2[k]] + 1
print(qln2)

在前文已将每个query的字符数统计出来保存在data中,因此第一步将其转化为列表,第二步对其字符数进行统计:

可以看出,两个query的字符数主要集中在6~15中,其余则随着数字的增加或者减少而减少,没有少于3个或者多于26个字符的。

  •  query1和query2文本单词个数
#查看query1和query2的单词个数
query1wordnumber = {}
query1wordcount = {}
query1word = {}
query1_n_words = 0
for pair1 in CoSentence1:
    seg_list1 = jieba.cut(pair1)
    for word1 in seg_list1:
        if word1 not in query1wordnumber:
            query1wordnumber[word1] = query1_n_words
            query1wordcount[word1] = 1
            query1word[n_words] = word1
            query1_n_words += 1
        else:
            query1wordcount[word1] += 1
print('query1的单词数为:',query1_n_words)
query2wordnumber = {}
query2wordcount = {}
query2word = {}
query2_n_words = 0
for pair2 in CoSentence2:
    seg_list2 = jieba.cut(pair2)
    for word2 in seg_list2:
        if word2 not in query2wordnumber:
            query2wordnumber[word2] = query2_n_words
            query2wordcount[word2] = 1
            query2word[n_words] = word2
            query2_n_words += 1
        else:
            query2wordcount[word2] += 1
print('query2的单词数为:',query2_n_words)

最终我们得到query1的单词数量和query2的单词数量,query2的词汇数量略多于query1。

query1_word = list(query1wordcount.keys())
query2_word = list(query2wordcount.keys())

q12gong = [wordgong for wordgong in query1_word if wordgong in query2_word]
q12butong = [wordcha for wordcha in (query1_word + query2_word) if wordcha not in q12gong]
print("相同的词有:")
print(q12gong)
print(len(q12gong))
print()
print()
print("不同的词有:")
print(q12butong)
print(len(q12butong))

相同的词共7130个

不同的词共1972个

  • query1和query2文本最长公用字符串长度
def func(a, b):

    if len(a) < len(b):
        a, b = b, a
    b_list_out = []
    start_sign = 0
    for i in range(1, len(b)+1):
        c = b[start_sign:i]
        if c in a:
            b_list_out.append(len(c))
        else:
            start_sign = i - 1
    b_list_out.sort()
    if b_list_out:
        return (b_list_out[-1])
    else:
        return (0)

strlong = []

print(len(CoSentence2))
print(len(CoSentence1))
for a in range(len(CoSentence2)):
    strlong.append(func(CoSentence1[a],CoSentence2[a]))
print(strlong)
print(max(strlong),strlong.index(max(strlong)))
print(CoSentence2[7196],CoSentence1[7196])
print(len(CoSentence1[7196]))

  

将最长公用字符串长度进行计数,存储到列表之中,接着查看最长的所在的下标,发现最长的有17个字符串相同,而其总长为23/22

  • query1和query2文本的TFIDF编码相似度
def TF_IDF(s1, s2):
    s1_cut = [i for i in jieba.cut(s1, cut_all=True) if i != '']
    s2_cut = [i for i in jieba.cut(s2, cut_all=True) if i != '']
    word_set = set(s1_cut).union(set(s2_cut))


    word_dict = dict()
    i = 0
    for word in word_set:
        word_dict[word] = i
        i += 1


    s1_cut_code = [word_dict[word] for word in s1_cut]
    s1_cut_code = [0] * len(word_dict)

    for word in s1_cut:
        s1_cut_code[word_dict[word]] += 1


    s2_cut_code = [word_dict[word] for word in s2_cut]

    s2_cut_code = [0] * len(word_dict)
    for word in s2_cut:
        s2_cut_code[word_dict[word]] += 1


    # 计算余弦相似度
    sum = 0
    sq1 = 0
    sq2 = 0
    for i in range(len(s1_cut_code)):
        sum += s1_cut_code[i] * s2_cut_code[i]
        sq1 += pow(s1_cut_code[i], 2)
        sq2 += pow(s2_cut_code[i], 2)

    try:
        result = round(float(sum) / (math.sqrt(sq1) * math.sqrt(sq2)), 2)
    except ZeroDivisionError:
        result = 0.0
    return result

shujuTFIDF = []
for b in range(len(CoSentence1)):
    shujuTFIDF.append(TF_IDF(CoSentence1[b],CoSentence2[b]))
len1 = 0
print(shujuTFIDF)

最终得到TF-IDF相似度:

其中数字越接近1则表示越相似,越接近0则表示越不相似。不难看出,TFIDF编码相似度最具有区分性。

  • 任务3结束

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值