1 sklearn的TfidfVectorizer() 方法的参数解释
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)]