使用Python构建基于视觉相似度的推荐系统的动手指南
在当今竞争激烈的技术世界中,对于不断发展的电子商务平台吸引客户并保持一致的品牌体验至关重要。代替允许用户在搜索之后执行搜索以获得他们想要的物品,推荐这样的相关物品更加令人印象深刻并且提供更好的满足感。
产品推荐可以通过分析客户以前的浏览模式和当前平台使用情况,非常有效地应对此类挑战。
视觉相似度推荐
产品推荐可以帮助:
将购物者转化为客户
吸引客户
促进销售和收入
提供最相关的内容
维持品牌体验
广义上讲,有两种推荐方法:
基于内容的建议
协同过滤
顾名思义,基于内容的方法基于有关客户或产品的其他内容(元数据)进行推荐。对于产品,此内容可以是产品标题,描述,图像,类别/子类别,规格等。
因此,这种方法推荐产品通过找到最相似的产品基础上,一个给定的产品内容。
在本文中,我们将通过使用产品图像来实现基于内容的推荐系统。基本上,目标是推荐与最近购买/检查过的产品图像非常相似的产品图像。
因此,基于图像的推荐将有助于根据客户最近的购物行为/平台使用情况向他们推荐最相似的产品。
视觉相似度推荐
让我们开始使用Fashion Product Images Dataset来实现这一点。数据集包含2906个产品图片,涵盖了四个不同的性别类别(男人,女人,男孩和女孩)。它还包含各种产品功能,例如标题,类别,子类别,颜色,性别,类型,用法等。
目录
基本
数据分析
1.1导入必要的库并加载数据
1.2基本统计数据–产品数量,子类别和性别
1.3每个性别的频率
1.4按性别分列的产品分布
资料准备
使用ResNet提取特征
计算欧几里得距离并推荐类似产品
4.1。加载提取的特征
4.2。距离计算与建议
部署解决方案
基本数据分析
1.1导入必要的库并加载数据
将numpy导入为np
将熊猫作为pd导入
导入matplotlib.pyplot作为plt
将seaborn导入为sns
从keras.preprocessing.image导入ImageDataGenerator
从keras.models导入顺序
从keras.layers导入Dropout,Flatten,Dense
从keras导入应用程序
从sklearn.metrics导入pairwise_distances
汇入要求
从PIL导入图片
进口泡菜
从datetime导入datetime
从PIL导入ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES =真
导入plotly.figure_factory为ff
随地导入plotly.graph_objects
导入plotly.express为px
导入streamlit为st
#在jupyter笔记本中显示图像时使用以下库
从IPython.display导入显示,图像
fashion_df = pd.read_csv(“ ./ fashion.csv”)
1.2基本统计数据–产品数量,子类别和性别
打印(“产品总数:”,fashion_df.shape [0])
print(“唯一子类别总数:”,fashion_df [“ SubCategory”]。nunique())
print(“唯一性别类型总数:”,fashion_df [“ Gender”]。nunique())
如前所述,数据集包含4906种不同性别类型的9906种不同子类别的2906种产品。
1.3每个性别的频率
在此数据集中,大多数产品属于男性,然后是女性,依此类推。
1.4按性别分列的产品分布
情节= sns.countplot(fashion_df [“性别”])
plt.title(“按性别分配文章”)
plt.xlabel(“性别类型”)
plt.ylabel(“产品数量”)
plot.set_xticklabels(plot.get_xticklabels())
视觉相似度推荐
从条形图中,我们还可以看到男士的产品数量最多。同样,数据集几乎是平衡的。
2.数据准备
由于不推荐跨类别推荐,例如,向单身汉推荐女孩的产品,因此让我们将数据按性别划分为4个不同的数据框。
apparel_boys = fashion_df [fashion_df [“ Gender”] ==“男孩”]
apparel_girls = fashion_df [fashion_df [“ Gender”] ==“ Girls”]
Shoes_men = fashion_df [fashion_df [“ Gender”] ==“ Men”]
Shoes_women = fashion_df [fashion_df [“ Gender”] ==“ Women”]
3.使用ResNet提取特征
通常,产品图像包含其颜色,形状和边缘的独特图案。
具有此类特征的图像应该是相似的。因此,从图像中提取此类特征对于推荐最相似的产品将非常有帮助。
如何从图像中提取特征?
可以使用计算机视觉技术从图像中提取特征。在这里,由于我们在数据大小,计算资源和时间上都有限制,所以让我们使用标准的预训练模型(例如ResNet)来提取功能。这样的预训练模型已经过微调,并在庞大的数据集(如ImageNet)上进行了训练。此过程也称为转移学习。
ResNet
ResNet是Residual Networks的缩写形式,由Kaiming He于2015年首次提出。目前,ResNet被视为许多计算机视觉任务的经典
神经网络。在2015年的ImageNet挑战赛中,该模型的表现优于GoogleNet,VGGNet和AlexNet等以前的模型。
视觉相似度推荐
该架构使我们能够成功地训练一个具有152层的极深和广泛的网络。在我们的实现,我们将使用ResNet50(较小的版本ResNet152)中提取的特征。
img_width,img_height = 224,224
#top_model_weights_path ='resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5'
train_data_dir =“ / home / vikas / fl / av /鞋/男装/图片/”
nb_train_samples = 811
时代= 50
batch_size = 1def extract_features():
产品编号= []
datagen = ImageDataGenerator(重新缩放= 1/255)
模型=应用程序.ResNet50(include_top = False,weights ='imagenet')
生成器= datagen.flow_from_directory(
train_data_dir,
target_size =(img_width,img_height),
batch_size =批量大小,
class_mode =无,
shuffle = False)
对于我在generator.filenames中:
Productids.append(i [(i.find(“ /”)+ 1):i.find(“。”)]))
extract_features = model.predict_generator(generator,nb_train_samples // batch_size)
extract_features = extracted_features.reshape((811,100352))
np.save(open('./ Men_ResNet_features.npy','wb'),extract_features)
np.save(open('./ Men_ResNet_feature_product_ids.npy','wb'),np.array(Productids))
一个= datetime.now()
extract_features()
print(“特征提取所花费的时间”,datetime.now()-a)
extract_features()函数从给定图像中提取特征。由于每RESNET标准第一,我们调整图像大小224 X 224,并使用它们正常化ImageDataGenerator可用Keras。最后,每个图像都表示为100352维特征向量。
为避免部署后提取运行时功能,提取的功能将保留在NumPy数组中。我们在此维护两个数组,分别用于产品ID和提取的特征。
类似地,针对其他产品图像按性别重复相同的特征提取过程。
4.计算欧几里得距离并推荐类似产品
距离是评估项目/记录之间相似性的最佳方法。距离越短,相似度越高,而距离越大,相似度越低。
根据几何形状,距离有多种类型,例如欧几里得距离,余弦距离,曼哈顿距离等。我们将在此处使用欧几里得距离来计算相似度。
由于我们已经提取了图像特征,因此可以使用sklearn.metrics中的pairwise_distances ()函数轻松地计算出欧几里得距离。
一旦计算出该距离,我们就可以按照距离的升序轻松推荐产品。我们开工吧!
4.1加载提取的特征
extract_features = np.load('./ Men_ResNet_features.npy')
产品编号= np.load('./ Men_ResNet_feature_product_ids.npy')men = pd.read_csv('./ footwear_men.csv')
df_Productids = list(men ['ProductId'])
产品编号=清单(产品编号)
4.2距离计算与建议
def get_similar_products_cnn(product_id,num_results):
doc_id = Productids.index(product_id)
pairwise_dist = pairwise_distances(extracted_features,extract_features [doc_id] .reshape(1,-1))
索引= np.argsort(pairwise_dist.flatten())[0:num_results]
pdists = np.sort(pairwise_dist.flatten())[0:num_results]
打印(“ =” * 20,“输入产品图片”,“ =” * 20)
ip_row = men [['ImageURL','ProductTitle']]。loc [men ['ProductId'] == int(Productids [indices [0]])]
#print(ip_row.head())
对于indx,在ip_??row.iterrows()中行:
display(Image(url = row ['ImageURL'],width = 224,height = 224,embed = True))
print('Product Title:',row ['ProductTitle'])
打印(“ \ n”,“ =” * 20,“推荐产品”,“ =” * 20)
对于范围内的我(1,len(indices)):
行=男子[['ImageURL','ProductTitle']]。loc [men ['ProductId'] == int(Productids [indices [i]])]
对于indx,为row.iterrows()中的行:
display(Image(url = row ['ImageURL'],width = 224,height = 224,embed = True))
print('Product Title:',row ['ProductTitle'])
print('距输入图像的欧几里得距离:',pdists [i])get_similar_products_cnn('13683',5)
上面的get_similar_products_cnn()函数根据提取的功能向查询的产品推荐5种最相似的产品。该函数接受两个参数-最近购买/检查的商品的商品ID和要推荐的商品数。
推荐产品编号为13683的前5名推荐产品如下所示。
提示:可以从此处下载完整的代码。
同样,我们也可以针对其他性别类型的产品推荐产品。让我们看看使用Streamlit的最终部署。
5.部署解决方案
Streamlit是一个交互式库/框架,用于构建数据应用程序和Web应用程序以及部署
机器学习工作负载。最重要的是,它不需要任何Web设计和开发方面的知识。Python知识足以与之交互,因为它与Python兼容。
st.set_option('deprecation.showfileUploaderEncoding',False)
fashion_df = pd.read_csv(“ ./ fashion.csv”)
boys_extracted_features = np.load('./ Boys_ResNet_features.npy')
boys_Productids = np.load('./ Boys_ResNet_feature_product_ids.npy')
girls_extracted_features = np.load('./ Girls_ResNet_features.npy')
girls_Productids = np.load('./ Girls_ResNet_feature_product_ids.npy')
men_extracted_features = np.load('./ Men_ResNet_features.npy')
men_Productids = np.load('./ Men_ResNet_feature_product_ids.npy')
women_extracted_features = np.load('./ Women_ResNet_features.npy')
women_Productids = np.load('./ Women_ResNet_feature_product_ids.npy')
fashion_df [“ ProductId”] = fashion_df [“ ProductId”]。astype(str)
def get_similar_products_cnn(product_id,num_results):
if(fashion_df [fashion_df ['ProductId'] == product_id] ['Gender']。values [0] ==“ Boys”):
extract_features = boys_extracted_features
产品编号=男孩_产品编号
elif(fashion_df [fashion_df ['ProductId'] == product_id] ['Gender']。values [0] ==“ Girls”):
extract_features = girls_extracted_features
产品ID = girls_Productid
elif(fashion_df [fashion_df ['ProductId'] == product_id] ['Gender']。values [0] ==“ Men”):
extract_features = men_extracted_features
产品编号=男人_产品编号
elif(fashion_df [fashion_df ['ProductId'] == product_id] ['Gender']。values [0] ==“ Women”):
extract_features = women_extracted_features
产品编号=女性_产品编号
产品编号=清单(产品编号)
doc_id = Productids.index(product_id)
pairwise_dist = pairwise_distances(extracted_features,extract_features [doc_id] .reshape(1,-1))
索引= np.argsort(pairwise_dist.flatten())[0:num_results]
pdists = np.sort(pairwise_dist.flatten())[0:num_results]
st.write(“”“
####输入项目的详细信息
“”“)
ip_row = fashion_df [['ImageURL','ProductTitle']]。loc [fashion_df ['ProductId'] == Productids [indices [0]]]
对于indx,在ip_??row.iterrows()中行:
图片= Image.open(urllib.request.urlopen(row ['ImageURL']))
图片= image.resize((224
st.image(图片)
st.write(f“产品标题:{row ['ProductTitle']}”)
st.write(f“”“
####顶部{num_results}推荐项目
“”“)
对于范围内的我(1,len(indices)):
行= fashion_df [['ImageURL','ProductTitle']]。loc [fashion_df ['ProductId'] == Productids [indices [i]]]
对于indx,为row.iterrows()中的行:
图片= Image.open(urllib.request.urlopen(row ['ImageURL']))
图片= image.resize((224
st.image(图片)
st.write(f“产品标题:{row ['ProductTitle']}”)
st.write(f“距输入图像的欧几里得距离:{pdists [i]}”)
st.write(“”“
##基于视觉相似度的推荐
“”
)
user_input1 = st.text_input(“输入商品ID”)
user_input2 = st.text_input(“输入要推荐的产品数量”)
button = st.button('产生建议')
如果按钮:
get_similar_products_cnn(str(user_input1),int(user_input2))
在此,以下内置函数用于进行交互式部署:
st.text_input()–从用户获取动态输入
st.write()–将消息/参数写入应用程序
st.title()–显示图像或图像列表。
像之前一样,这里的get_similar_products_cnn()函数根据指定的参数推荐大多数相似的产品。
要在终端类型中执行此部署脚本:
流式运行recom_deployment.py
题库