基于gensim电商标题相似度

gensim

gensim是在做自然语言处理时较为经常用到的一个python工具库,主要用来以无监督的方式从原始的非结构化文本当中,学习文本隐藏的主题向量表达。包括TF-IDF、word2vec、doc2vec等多种模型

实现逻辑

  1. 利用HanLP对标题进行分词,形成一个二维的列表
  2. 将二维列表生成预料词典,通过doc2bow稀疏向量,形成语料库
  3. 词袋模型 + TF-IDF模型,计算出tfidf值
  4. 获取预料词典的特征数, 计算稀疏矩阵相似度,建立一个索引
  5. 将测试语料同样进行HanLP分词,用doc2bow计算测试语料的稀疏向量
  6. 测试语料与训练预料进行匹配,计算相似度,返回相似度最大的标题行数

训练预料

title.txt 文件中是扳手的电商标题数据
示例:

MAXPOWER 可调式扭力扳手,1/4"方头,5-25N.m,M18150
东日扭力扳手10-50NM,QL50N-MH
东日手动式扭力扳手,QL100N4-MH
史丹利 数显角度扭矩扳手,1/2"方头,17-340N.m,SDA-340-22,带棘轮头
东日 扭力扳手,0.4-2N.m,6.35mm驱动头,QL2N-MH
史丹利 数显角度扭矩扳手,1/2"方头,10-200N.m,SDA-200-22,带棘轮头
东日 数字式扭力扳手,4-20N.M,CEM20N3×10D-G
世达扭力扳手,G系列可换头预置式10-50Nm,棘轮头需另配,96443
史丹利 数显角度扭矩扳手,3/8"方头,6.8-135N.m,SDA-135-22,带棘轮头
世达电子扭力扳手,3/8"系列 27-135Nm,96525
准达 表盘式扭矩扳手,5-25N.m,3/8"方驱,ZNB-25A

代码

import pickle
import numpy as np
from pyhanlp import *
from gensim import corpora, models, similarities


def hanlp_process(text):
    """
    hanlp分词
    :param text: 待分词的文本
    :return:仅返回词不返回词性
    """
    return [value.word for value in text]


def split_text(path):
    """
    对标题进行分词, 并去停用词
    :return: 返回分词列表
    """
    # 将title追加到列表中
    title_list = []
    if path.find('.txt') != -1:
        with open(path, 'r', encoding='utf-8-sig') as f:
            for line in f.readlines():
                title_list.append(line.strip())
    else:
        title_list = [path]

    # 去停用词
    stop_path = r'stop_words.txt'
    stopwords = [line.strip() for line in open(stop_path, 'r', encoding='utf-8').readlines()]
    word_list = []
    for corpu in title_list:
        # hanlp分词
        seg_list = hanlp_process(HanLP.segment(corpu))
        # 去停用词
        seg_list = [i for i in seg_list if i not in stopwords and i != ' ']
        word_list.append(seg_list)
    return word_list


def get_dict(word_list):
    """
    根据分词结果,得到语料库的词典,保存语料文件
    :param word_list: 分词列表
    :return: 预料字典
    """
    # 赋予每个词索引
    dictionary = corpora.Dictionary(word_list)
    # 保存索引
    with open('./model/index.txt', 'w', encoding='utf-8-sig') as f:
        for a, b in zip(dictionary.token2id.keys(), dictionary.token2id.values()):
            f.write(str({a: b}))
            f.write('\n')
    return dictionary


def bag_words(dictionary, word_list):
    """
    获取词袋模型
    :param dictionary: 预料字典
    :param word_list: 分词列表
    :return: 词袋模型
    """
    # 统计每个词出现的次数
    dictionary_vec = [dictionary.doc2bow(word) for word in word_list]
    return dictionary_vec


def words_TF_IDF(dictionary_vec, dictionary):
    """
    构建词袋模型+TF-IDF模型
    :param dictionary_vec: 词袋模型
    :return: 词袋模型+TF-IDF模型
    """
    # 计算TF-IDF
    tfidf = models.TfidfModel(dictionary_vec, dictionary)
    c_tfidf = tfidf[dictionary_vec]
    f_num = len(dictionary.token2id.keys())
    index_f = similarities.SparseMatrixSimilarity(c_tfidf, num_features=f_num)
    # 保存TF-IDF模型
    tfidf.save("./model/my_model.tfidf")
    return index_f, tfidf


def main(text):
    # 分词 去停用词
    word_list = split_text('./title.txt')
    # 语料词典
    dictionary = get_dict(word_list)
    # 获取词袋模型
    dictionary_vec = bag_words(dictionary, word_list)
    feature_index, tfidf_model = words_TF_IDF(dictionary_vec, dictionary)
    # 对待测文本进行分词
    text_list = split_text(text)
    text_vec = dictionary.doc2bow(text_list[0])
    feature_list = list(feature_index[tfidf_model[text_vec]])
    max_index = feature_list.index(max(feature_list))
    return max_index, max(feature_list)


if __name__ == '__main__':

    result, max_similar = main('史丹利(STANLEY )1/2英寸数显角度扭矩扳手公斤扭力棘轮快速力矩板手 SDA-340-22 (17-340N.m)现货')
    print(f"与第{result}行的数据最相似, 相似度为{max_similar}")
    # 第29161行的数据: 史丹利 数显角度扭矩扳手,1/2"方头,17-340N.m,SDA-340-22,带棘轮头
    # 相似度:0.6777337789535522

你可能感兴趣的:(python,人工智能,深度学习)