TF-IDF的使用及实现问答

实现的包 from sklearn.feature_extraction.text import TfidfVectorizer

               或

                from sklearn.feature_extraction.text import CountVectorizer

                from sklearn.feature_extraction.text import TfidfTransformer

                先用CountVectorizer做词袋法统计,再用tf-df transformer转化

sklearn的TfidfVectorizer默认输入文本矩阵每行表示一篇文本,不同文本中相同词项的tf值不同,因此tf值与词项所在文本有关。而idf值与输入矩阵的行数(也就是训练集文本数)和包含词项的文本数有关,因此idf值与训练集的大小才有关系。

tf(t,d)是tf值,表示某文本d中词t的频度,tf 值由词项和文本共同决定;

idf(t)是词 t 的idf值,nd:训练集文本数,df(d,t):含词 t 的文档总数,

idf值与训练集总数和包含词 t 文本数有关。

TfidfVectorizer中默认的 token_pattern=r"(?u)\b\w\w+\b",只匹配长度>2的词(用(?u)\b\w+\b解决)

 \b:单词边界;\B:非单词边界;

\w 匹配字母或数字或下划线, 等价于'[^A-Za-z0-9_]',还包含了希腊字母,俄文字母

(?u):re.U

(?iLmsux)

一个或多个字母从集合'i','L','m','s','u','x' 的组相匹配的空字符串;

字母设置相应的标志:re.I(忽略大小写), re.L(与当前位置有关), re.M(多线),(re.S点匹配所有) ,re.U(取决于Unicode)和re.X(详细)(对于整个正则表达式)(标志在模块内容中进行了描述。)如果希望将标志包括在正则表达式中,而不是传递标志参数时候有用。

获取对应词的 tf-idf 权重:

问答的数据是有关法律问题的问答,形式是多个相似问题对应对应一个答案

匹配相似问题找到对应的答案

将相似的问题抽取一个放入测试集,将相似的问题组成一个列表,作为一个问题看待

未去除停用词

只取一个答案的准确率为46%

只取三个答案的准确率为62%

只取五个答案的准确率为68%

去除停用词

只取一个答案的准确率为56.76%

只取三个答案的准确率为75.68%

只取五个答案的准确率为80.27%

import jieba
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.feature_extraction.text import TfidfVectorizer

def QA_pair(path):
    '''
    问题和答案在同一行
    :param path:
    :return:
    '''
    data = pd.read_excel(path)
    q_l = []
    a_l = []
    for row in data.iterrows():
        content = row[1]
        q = []
        a = []
        for k, v in content.iterrows():
            if "问" in k:
                q.append(v)
            elif "答" in k:
                a.append(v)
        q_l.append(q)
        a_l.append(a)

    return q_l, a_l

def QA_dict(q_l, a_l):
    '''
    使用相同的编号将问题和答案对应
    :param q_l:
    :param a_l:
    :return:
    '''
    q_dict = {}
    a_dict = {}
    if len(q_l) == len(a_l):
        for num in range(len(q_l)):
            q_dict.update({num: q_l[num]})
            a_dict.update({num: a_l[num]})

    return q_dict, a_dict

def split_train_test_data(q_l: list):
    train_data = []
    test_data = []
    for n in range(len(q_l)):
        q = q_l[n]
        if len(q) > 1:
            test_data.append({n: q[-1]})
            train_data.append({n: q[:-1]})
        else:
            train_data.append({n: q})

    return train_data, test_data

def del_stop_words(stop_words_path: str, samples: list):
    s_l = []
    with open(stop_words_path, "r", encoding="utf-8") as f:
        stop_words = f.readlines()
        for s in samples:
            if s in stop_words:
                continue
            else:
                s_l.append(s)
    return s_l

def gen_samples(data, stop_words_path):
    l = []
    a_l = []
    for d in data:
        s_l = []
        for k, v in d.items():
            p_l = []
            for q in v:
                parse_l = jieba.lcut(q)
                p_l.extend(parse_l)
            s_l = list(set(p_l))
            s_l = del_stop_words(stop_words_path, s_l)
            a_l.append(k)
        l.append(" ".join(s_l))

    return l, a_l

if __name__ == "__main__":
    path = ""
    stop_words_path = ""
    q_l, a_l = QA_pair(path)
    q_dict, a_dict = QA_dict(q_l, a_l)
    train_data, test_data = split_train_test_data(q_l)
    l, _ = gen_samples(train_data)
    vectorizer = TfidfVectorizer()
    Q = vectorizer.fit_transform(l)

    test_l, test_a_l = gen_samples(train_data)
    test_Q = vectorizer.transform(test_l)
    score = cosine_similarity(test_Q, Q)
    test_num = score.shape[0]
    correct_num = 0
    for num in range(test_num):
        s = score[num]
        r_dict = {}
        for n, r in enumerate(s):
            r_dict.update({n: r})
        s_sorted = sorted(r_dict.items(), key=lambda k: k[1], reverse=True)
        for a_n in s_sorted[:3]:
            if a_n[0] == test_a_l[num]:
                correct_num += 1
                break
            else:
                print()
    print(correct_num / test_num)

参考:https://zhuanlan.zhihu.com/p/67883024

        https://blog.csdn.net/m0_37324740/article/details/79411651

        sklearn: TfidfVectorizer 中文处理及一些使用参数 - 胖墩哥 - 博客园l(TfidfVectorizer 参数使用)

        利用sklearn进行tfidf计算 - King_K - 博客园l (获取词 tf-idf 值)

        sklearn:TfidfVectorizer中文处理及一些使用参数 - 百度文库 (baidu.com)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值