基于sklearn TFIDF模型 的文章推荐算法

1   sklearn的TfidfVectorizer() 方法的参数解释

2    手写tfidf模型

3   大数据情况下,如何计算测试集文本和训练集文本的余弦相似度

一  训练阶段     输入数据格式:一个列表,列表中的每个元素代表一个文本。每个文本分词后的词语组成的一个字符串 代表该文本。 生成的模型、tfidf矩阵、文章item_id列表分别保存。

import pandas as pd
from sklearn.externals import joblib
from scipy import sparse
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
df = pd.read_csv("new_doc/traindata.csv",delimiter='\t',encoding='utf-8')
train = []
train_item_id = []
for i in range(len(df["content"])):
    line = str((df["content"][i]))
    print(line)
    #line = line.split()
    # for word in line:
    #     words +=word
    train.append(line)
    train_item_id.append(df["item_id"][i])
print(len(train))

# 文档频率的高于0.9的词语忽视,低于在2个文档中出现的忽视。
vec = TfidfVectorizer(max_df=0.8,min_df=5,dtype=np.float32)
# 生成训练数据的tfidf矩阵,矩阵每行代表一个样本的tfidf向量。
train_tfidf = vec.fit_transform(train)
print(train_tfidf)
print(train_tfidf.shape[0])
print(len(vec.vocabulary_))
#保存tfidf矩阵
sparse.save_npz('./new_doc/train_tfidf.npz', train_tfidf)  #保存
#保存tfidf模型
joblib.dump(vec,'./new_doc/model_tfidf.pkl')
#保存item_id列表
joblib.dump(train_item_id,'./new_doc/train_item_id.pkl')
print('ok')

 

二  在测试阶段,直接加载tfidf矩阵、item_id、vec模型。

   模型对测试集进行transform;求余弦相似度。对相似度top5的文章进行推荐。

对相关函数的说明:

cosine_similarity(test_tfidf,self.tfidf) :输入参数为一个向量,一个矩阵。 可以对稀疏矩阵和非稀疏矩阵进行处理
flatten()   a是个矩阵或者数组,a.flatten()就是把a降到一维,默认是按横的方向降。  
argsort()  argsort函数返回的是数组值从小到大的索引值
from sklearn.externals import joblib
from scipy import sparse
import jieba
import os
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
class Processing:

    #初始化
    def __init__(self):
        self.new_path = './new_doc'
        self.index = joblib.load('new_doc/train_item_id.pkl')
        self.vec = joblib.load('new_doc/model_tfidf.pkl')
        self.tfidf = sparse.load_npz('new_doc/train_tfidf.npz')
        self.testcorpus= []
        self.stopwords = [line.strip() for line in open('./doc/stopword.txt', 'r', encoding='utf-8').readlines()]
        self.test = []
        self.result = []
    # 读取文章
    def readfile(self,path):
        fp = open(path, "r", encoding="utf-8")
        content = fp.read()
        fp.close()
        return content

    # 分词、去停用词
    def chinese_word_cut(self,mytext):
        seg_list = ''
        seg_text = jieba.cut(mytext)
        for word in seg_text:
            if word not in self.stopwords:
                seg_list += word
                seg_list += ' '
        return ''.join(seg_list)

    # 计算余弦相似度函数
    def cos_like(self,array1, array2):
        num = float(np.matmul(array1, array2))
        s = np.linalg.norm(array1) * np.linalg.norm(array2)
        if s ==0:
            result = 0.0
        else:
            result = num/s
        return result
        # result = 1-distance.cosine(array1,array2)
        # return result


    def read_and_cut(self,new_path):
        catelist = os.listdir(new_path)  # 获取new_doc下所有文件
        result = []
        if catelist is not None:
            for file_path in catelist:
                # 读取要比较的文章进行分词、去停用词处理
                data = self.readfile(new_path + '/' + file_path)
                doc = self.chinese_word_cut(data)
                if doc is not None:
                    # 新文章
                    self.test.append(doc)   #预处理好的新文章放到列表里面
    def get_sim(self):
        # 对新文章构建tdidf向量
        test_tfidf = self.vec.transform(self.test)
        # print(test_tfidf)
        # print(self.tfidf.shape)
        result = cosine_similarity(test_tfidf,self.tfidf).flatten()
        related_doc_indices =  result.argsort()[:-6:-1]
        print(related_doc_indices)
        result_rec = result[related_doc_indices]
        print(result_rec)
        idlist = [] # 保存item_id
        #遍历train_tfidf 和新文章计算相似度,结果保存到result列表。
        # for k in range(int(self.tfidf.shape[0]/5000)+1):
        #     train_tfidf = self.tfidf[k*5000:(k+1)*5000,:].toarray()
        #     for i in range(train_tfidf.shape[0]):
        #         y = np.array(train_tfidf[i, :])
        #         # print(y)
        #         result.append(self.cos_like(x, y))
        #     #print(result)
        #     del train_tfidf
        #     gc.collect()
        # # # 对列表从大到小排序,并获得top6 的索引。
        # max_num_index_list = map(result.index, heapq.nlargest(6, result))
        # index_list = list(max_num_index_list)
        #根据索引找到训练集对应的item_id
        for i in related_doc_indices:
            idlist.append(self.index[i])
        return idlist

实验过程中遇到的问题:

把mysql数据库中的数据存为DataFrame格式的时候,用index=False清除索引列。

清除df 中的指定某列 del df['列名']

定位df 中的某一行

# 选取等于某些值的行记录 用==
df.loc[df['column_name'] == some_value]
# 选取某列是否是某一类型的数值 用 isin
isin df.loc[df['column_name'].isin(some_values)]
# 多种条件的选取 用 &
df.loc[(df['column'] == some_value) & df['other_column'].isin(some_values)]
#  选取不等于某些值的行记录 用 != 
df.loc[df['column_name'] != some_value] 
# isin返回一系列的数值,如果要选择不符合这个条件的数值使用~ 
df.loc[~df['column_name'].isin(some_values)]

                                  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值