基于Pandas+余弦相似度+大数据智能护肤品推荐系统——机器学习算法应用(含Python工程源码)+数据集

本文主要是介绍基于Pandas+余弦相似度+大数据智能护肤品推荐系统——机器学习算法应用(含Python工程源码)+数据集,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 前言
  • 总体设计
    • 系统整体结构图
    • 系统流程图
  • 运行环境
    • Python环境
    • Pycharm 环境
  • 模块实现
    • 1. 文件读入
    • 2. 推荐算法
      • 1)数据预处理
      • 2)计算相似度
      • 3)排序并提取产品
      • 4)组合推荐算法
    • 3. 应用模块
      • 1)得到最终产品
      • 2)筛选过敏物质
      • 3)筛选相互禁忌的产品
      • 4)输出单品推荐与组合推荐
    • 4. 测试调用函数
  • 系统测试
  • 工程源代码下载
  • 其它资料下载


在这里插入图片描述

前言

本项目结合了Pandas数据处理工具和机器学习技术,旨在构建一个智能的护肤品推荐系统。该系统不仅会考虑用户的肤质特征,还会考虑过敏反应等因素,并筛选出相互禁忌的产品,以便为不确定如何选择护肤品的用户提供个性化的推荐。

首先,项目会收集用户的肤质信息,包括肤质类型(如干性、油性、混合性等)以及特殊过敏或敏感反应(例如对某些成分的过敏)。这些信息将作为推荐系统的输入。

接下来,项目会利用Pandas进行数据处理和分析,以便理解不同护肤产品的成分、特性和功效。这包括产品的成分列表、适用肤质类型、适用场景等信息。

然后,项目会应用机器学习与余弦相似度算法,基于用户的肤质和过敏特征,以及不同护肤产品的属性,来建立一个推荐模型。这个模型将考虑用户的需求和限制条件,例如对某些成分的过敏反应,从而为用户推荐适合他们的护肤产品。

在推荐产品时,系统还会考虑相互禁忌的产品组合。这意味着系统将避免推荐那些在使用时可能引发不良反应或效果相互抵消的产品。

最终,用户将获得一套适合他们肤质和需求的护肤产品建议。这些建议可能包括洁面产品、护肤霜、面膜等,以满足用户的整体护肤需求。

总的来说,项目旨在帮助用户更好地选择护肤产品,考虑了他们的肤质特征、过敏反应和产品相互作用等因素。这种护肤品推荐系统可以提高用户的护肤体验,确保他们选择的产品是安全有效的。

总体设计

本部分包括系统整体结构图和系统流程图。

系统整体结构图

系统整体结构如图所示。

在这里插入图片描述

系统流程图

系统流程如图所示。

在这里插入图片描述

运行环境

本部分包括 Python 环境和Pycharm 环境。

Python环境

需要Python 3.6及以上配置,在Windows环境下推荐下载Anaconda完成Python所需环境的配置,下载地址为https://www.anaconda.com/,也可下载虚拟机在Linux环境下运行代码。

各数据包环境如下:

import pandas
import numpy
import math
import itertools

Pycharm 环境

PyCharm下载地址为http://www.jetbrains.com/pycharm/download/#section=windows,进入网站后单击Comminity版本下的DOWNLOAD下载安装包,下载完成后安装。单击Create New Project创建新的项目文件,Location为存放工程的路径,单击project附近的三角符号,可以看到PyCharm已经自动获取Python 3.6,单击create完成。

模块实现

本项目包括4个模块:文件读入、推荐算法、应用模块和测试调用函数,下面分别给出各模块的功能介绍及相关代码。

1. 文件读入

本部分主要是读取用户的肤质特征、诉求以及过敏成分,同时导入5个数据集文件,分别是用户数据集、产品主要成分表、功能表、禁忌搭配成分表、护肤公式。

相关代码如下:

#文件读入部分
user = pd.Series({'wxid':'o_2phwQNVY9WYG1p0B1z0E_d-lHM','T区油': 1,'U区油': 1,'敏感肌': 1,'诉求': '祛痘','过敏成分': '烟酰胺'})
pro = pd.read_csv(r'df_product1046.csv', encoding='ANSI')
df_component = pd.read_csv("df_component.csv",encoding='gb18030')
df_fake = pd.read_csv("df_fake.csv",encoding="gb18030")
fformula = pd.read_csv("Formula_formatting.csv",encoding="gb18030") 
ingredient_banned = pd.read_excel('ingredient_banned_to_number.xlsx', encoding="gb18030")

2. 推荐算法

导入数据后,进行推荐算法计算相似度。

1)数据预处理

提取有用的数据加工成合适的格式方便调用。

相关代码如下:

def __init__(self, df_fake, sub2_product):self.frame = df_fake #调用文件self.product = sub2_product  #产品表#self.screened_product_path = r'D:\work\dataclinic\fake\df_product1046.csv'  #读取预筛选后的产品集#self._init_data()#def _init_data(self):#self.frame = pd.read_csv(self.frame_path)#self.product = pd.read_csv(self.product_path,encoding='GB18030')#self.screened_product_path = pd.read_csv(self.product_path,encoding='GB18030')def screen(self, need):   #数据预处理self.frame = self.frame[(self.frame['诉求'].isin([need]))]def vec_purchase(self):#提取购买记录并拉直g = self.frame['购买记录']g2 = self.frame['购买记录2']g3 = self.frame['购买记录3']wxid = list(self.frame['wechatid'])s = pd.Series(wxid, index=g)s2 = pd.Series(wxid, index=g2)s3 = pd.Series(wxid, index=g3)pin = pd.concat([s, s2, s3], axis=0) #数据合并dict_pin = {'wechatid': pin.values, '购买记录': pin.index, }df2 = pd.DataFrame(dict_pin)#拉直后的dataframe(wechat id :购买记录)self.frame_p = df2[~(df2['购买记录'].isin([-1]))]

2)计算相似度

处理数据格式后计算相似度。相似度由用户购买记录和肤质相似度组成,最后加权求和。

相关代码如下:

#计算肤质向量(T区油、U区油、敏感肌、痘痘肌)的余弦相似度def cosine_skin(self, target_user_id, other_user_id):#数据预处理target_skin = []other_skin = []cols = ['T区油', 'U区油', '敏感肌', '痘痘肌']for col in cols:target_skin.append((self.frame[self.frame['wechatid'] == target_user_id][col].values[0]) * 2 - 1)  #标准化可能for col in cols:other_skin.append((self.frame[self.frame['wechatid'] == other_user_id][col].values[0]) * 2 - 1)#计算余弦相似度nume=sum(np.multiply(np.array(target_skin),np.array(other_skin)))#分子deno=sum(np.array(target_skin)** 2)*sum(np.array(other_skin)** 2)#分母cosine = nume / math.sqrt(deno)   #值为1return cosine#计算购买记录余弦相似度def cosine_purchase(self, target_user_id, other_user_id):target_items = self.frame_p[self.frame_p['wechatid'] == target_user_id]['购买记录']items = self.frame_p[self.frame_p['wechatid'] == other_user_id]['购买记录']union_len = len(set(target_items) & set(items))if union_len == 0:return 0.0product = len(target_items) * len(items)cosine = union_len / math.sqrt(product)return cosine#计算加权平均相似度并排序def get_top_n_users(self, target_user_id, top_n):#提取其他所有用户other_users_id = [i for i in set(self.frame_p['wechatid']) if i != target_user_id]#计算与其他用户的购买相似度sim_purchase_list = [self.cosine_purchase(target_user_id, other_user_id) for other_user_id in other_users_id]#计算与其他用户的肤质相似度sim_skin_list = [self.cosine_skin(target_user_id, other_user_id) for other_user_id in other_users_id]#加权平均(各占50%)sim_list = list((np.array(sim_purchase_list) + np.array(sim_skin_list)) / 2)sim_list = sorted(zip(other_users_id, sim_list), key=lambda x: x[1], reverse=True)return sim_list[:top_n]

3)排序并提取产品

相关代码如下:

#提取候选产品表def get_candidates_items(self, target_user_id):target_user_item = set(self.frame_p[self.frame_p['wechatid'] == target_user_id]['购买记录'])other_user_item = set(self.frame_p[self.frame_p['wechatid'] != target_user_id]['购买记录'])candidates_item = other_user_item - target_user_item  
#寻找候选推荐品标准:目标用户没有使用过的(必要性存疑)candidates_item = list(candidates_item & set(self.product['ind'].values))#候选推荐品必须属于上一步筛选出的项目(目前使用全产品表代替筛选后产品表)return candidates_item#计算用户兴趣程度def get_top_n_items(self, top_n_users, candidates_items, top_n):top_n_user_data = [self.frame_p[self.frame_p['wechatid'] == k] for k, _ in top_n_users]interest_list = []for ind in candidates_items:tmp = []for user_data in top_n_user_data:if ind in user_data['购买记录'].values:tmp.append(1)else:tmp.append(0)interest = sum([top_n_users[i][1] * tmp[i] for i in range(len(top_n_users))])interest_list.append((ind, interest))interest_list = sorted(interest_list, key=lambda x: x[1], reverse=True)return interest_list[:top_n]#输入wxid,需求默认推荐产品数为10 输出有序推荐产品def calculate(self, target_user):top_n = self.product.shape[0]target_user_id = target_user.wxidneed = target_user.诉求self.screen(need)self.vec_purchase()top_n_users=self.get_top_n_users(target_user_id, top_n) candidates_items = self.get_candidates_items(target_user_id)top_n_items = self.get_top_n_items(top_n_users, candidates_items, top_n)#重构数据格式返回完整推荐产品信息productlist = [top_n_items[i][0] for i in range(len(top_n_items))]product_rec = self.product[(self.product['ind'].isin(productlist))]product_rec['InterestRate'] = [top_n_items[i][1] for i in range(len(top_n_items))]return product_rec

4)组合推荐算法

相关代码如下:

  #组合推荐算法
class CombRating():def __init__(self,user, pro_withrate, fformula):self.user = userself.product = pro_withrateself.fformula=fformula#第一个for 找到用户的诉求是哪一种,要求四个属性全部对上#第二个for 找到组合中应当有的产品类型,水、乳、霜、祛痘凝胶、洁面def find_kind(self):#print(self.fformula)n_formula = self.fformula.shape[0]for i in range(n_formula):if (self.user.诉求 == self.fformula.诉求[i]) \and (self.user.T区油 == self.fformula.T区油[i]) \and (self.user.U区油 == self.fformula.U区油[i]) \and (self.user.敏感肌 == self.fformula.敏感肌[i]):i_formula = ibreak#此处使用总共的产品种类解决数字问题#寻找第一个是产品类型的列并记录此前经过的列数form_list = []total_pro_type = ['水', '乳', '霜', '祛痘凝胶', '洁面']type_number = 0for j in range(len(self.fformula.columns)):if self.fformula.columns[j] in total_pro_type:breakelse:type_number = type_number + 1#再找到所有需要的产品种类for j in range(type_number, len(self.fformula.columns)):if (self.fformula.loc[i_formula][j] == 1):form_list.append(self.fformula.columns[j])return form_listdef outer_multiple(self, form_list):ddict={}for i in range(len(form_list)):ddict[form_list[i]] = list(self.product[self.product.剂型 == form_list[i]].ind)#print(ddict)dd = []for i in itertools.product(*ddict.values()):dd.append(i)comb_pd = pd.DataFrame(dd)#为DF的每一列添加名称column_name = []for i in range(len(comb_pd.columns)):column_name.append('产品'+str(i+1))comb_pd.columns = column_name#返回的是产品编号ind一列的值return comb_pd

3. 应用模块

根据已经计算并排序的用户,找到产品并加工好合适的数据格式,按照护肤公式中的种类进行排列组合,同时考虑单品过敏和组合推荐的相互禁忌情况。若有相互禁忌和过敏情况在最后输出让用户知情。

1)得到最终产品

相关代码如下:

#整合
class Recommendation():def __init__(self, user, pro, df_component, df_fake, fformula, ingredient_banned):self.user = userself.pro = proself.df_component = df_componentself.df_fake = df_fakeself.fformula = fformulaself.ingredient_banned = ingredient_banned#诉求筛选得到sub1def sub1_product(self):#通过用户筛选需求成分,返回筛选后的产品列表sub1pro = self.prouser = self.user#T区条件筛选if user['T区油'] == 1:for index in pro.index:if pro.loc[index, 'typeT区:油'] != 1:pro = pro.drop(index=index)elif user['T区油'] == 0:for index in pro.index:if pro.loc[index, 'typeT区:干'] != 1:pro = pro.drop(index=index)#U区条件筛选if user['U区油'] == 1:for index in pro.index:if pro.loc[index, 'typeU区:油'] != 1:pro = pro.drop(index=index)elif user['U区油'] == 0:for index in pro.index:if pro.loc[index, 'typeU区:干'] != 1:pro = pro.drop(index=index)#敏感肌筛选if user['敏感肌'] == 1:for index in pro.index:if pro.loc[index, '敏感'] != 1:pro = pro.drop(index=index)#诉求筛选美白/祛痘if user['诉求'] == '祛痘':for index in pro.index:if pro.loc[index, '诉求'] != '祛痘':pro = pro.drop(index=index)elif user['诉求'] == '美白':for index in pro.index:if pro.loc[index, '诉求'] != '美白':pro = pro.drop(index=index)pro = pro.reset_index(drop=True)sub1 = proreturn sub1

2)筛选过敏物质

得到产品后筛选产品中与用户过敏的物质成分。

相关代码如下:

#过敏物质筛选,得到sub2def sub2_product(self):#通过用户过敏成分筛选产品,得到sub2user = self.userproduct = self.sub1_product()#1从user信息中提取过敏成分allergic_cpnt = user['过敏成分']#2选出含有过敏成分的产品product_allergic = []for i in range(0, len(df_component.成分)):if df_component.成分[i] == allergic_cpnt:product_allergic.append(df_component.ind[i])#3-1 生成sub2产品表,筛除含有过敏成分的产品,返回sub2产品表sub2_product = pd.DataFrame()sub2_product = product[:]for i in range(0, len(product.ind)):if i in product_allergic:sub2_product.drop(index=[i], inplace=True)sub2 = sub2_productreturn sub2#输入两个产品的ind 返回过敏信息用于后面函数的调用def is_pro_component_banned(self, pro1_ind, pro2_ind):#输入两个产品的ind 产品成分表、成分禁忌表、总产品表
#根据产品ind判断是否过敏,并且返回禁忌成分的字符串df_component = self.df_componentingredient_banned = self.ingredient_bannedpro = self.pro

3)筛选相互禁忌的产品

组合推荐一套可能出现两种产品之间有成分相互禁忌,所以要告知用户,让他们自已决断。

相关代码如下:

#对禁忌表进行预处理ingredient_name = ingredient_banned.columnsingredient_banned= ingredient_banned.drop(ingredient_banned.columns[0], axis=1)  #删除第一列ingredient_banned.index = ingredient_name #重置横标签为产品名#找出两个产品中所有的成分存入两个列表pro1_component = []pro2_component = []for index in range(len(df_component.index)):if df_component.loc[index, 'ind'] == pro1_ind:pro1_component.append(df_component.loc[index, '成分'])elif df_component.loc[index, 'ind'] == pro2_ind:pro2_component.append(df_component.loc[index, '成分'])#print(pro1_component, pro2_component)#寻找是否冲突,并且记录成分、产品这一版先用字符串作为返回值banned_record = ''for com1 in pro1_component:for com2 in pro2_component:if (com1 in ingredient_banned.index) and (com2 in ingredient_banned.index):if ingredient_banned.loc[com1, com2] == 2:li1 = list(pro[pro.ind == pro1_ind].typenickname)li1 = ''.join(li1)li2 = list(pro[pro.ind == pro2_ind].typenickname)li2 = ''.join(li2)banned_record = banned_record + '产品' + li1 + '与产品' + li2 + '相互禁忌' + '禁忌成分为' + com1 + '与' + com2elif ingredient_banned.loc[com1, com2] == 1:li1 = list(pro[pro.ind == pro1_ind].typenickname)li1 = ''.join(li1)li2 = list(pro[pro.ind == pro2_ind].typenickname)li2 = ''.join(li2)banned_record = banned_record + '产品' + li1 + '与产品' + li2 + '相互禁忌' + '禁忌成分为' + com1 + '与' + com2return banned_record#输入推荐组合 调用前方函数返回最后有备注的组合推荐def is_comb_banned(self, comb_pd):#传入信息为 is_pro_component_banned 的参数加上推荐组合的df#增加df一列,用以存贮禁忌信息,数据形式为str#对每个组合进行循环,创建banned_info列表#对每两个产品调用 is_pro_component_banned#若存在禁忌信息加入上述str,将banned_info加入df的新列df_component = self.df_componentingredient_banned = self.ingredient_bannedself.pro = self.procomb_pd['禁忌搭配情况'] = None#对每个组合for index in range(len(comb_pd.index)):total_banned = ''#对每两个产品for pro1 in range(len(comb_pd.columns)):for pro2 in range(pro1, len(comb_pd.columns)):banned = self.is_pro_component_banned(comb_pd.ix[index, pro1], comb_pd.ix[index, pro2])if banned != '':total_banned = total_banned + banned#将得到此列的禁忌信息加入整个pd并返回comb_pd.loc[index, '禁忌搭配情况'] = total_banned#comb_pd.to_csv('result')     return comb_pd

4)输出单品推荐与组合推荐

根据之前计算的产品信息,输出单品推荐和组合推荐,并告知过敏与禁忌成分。

相关代码如下:

#单品推荐def single_rec(self):user = self.user#调用User类进行推荐sub2 = self.sub2_product()U1 = UserCF(self.df_fake, sub2)items = U1.calculate(self.user)return items#复合推荐缺少护肤公式def combine_rec(self):user = self.user#调用User类先进行单品推荐sub2 = self.sub2_product()U1 = UserCF(self.df_fake, sub2)items = U1.calculate(self.user)#再调用Comb类进行复合推荐C1 = CombRating(user, items, self.fformula)ddd = C1.outer_multiple(C1.find_kind())#再调用禁忌类对此进行处理return self.is_comb_banned(ddd)

4. 测试调用函数

调用之前的所有模块,并且输出单品推荐和组合推荐。

相关代码如下:

#测试代码1
R1 = Recommendation(user, pro, df_component, df_fake, fformula, ingredient_banned)
#print(R1.combine_rec(), R1.single_rec())
a = R1.combine_rec()
b = R1.single_rec()
a.to_csv("file1_1")
b.to_csv("file2_1") 

系统测试

将数据代入模型进行测试,得到如图1和图2所示的测试效果。

在这里插入图片描述

图1 组合推荐结果 ![在这里插入图片描述](https://img-blog.csdnimg.cn/b9e5c80438c244a597d4fe7c1843ca20.png)
图2 单品推荐结果

工程源代码下载

详见本人博客资源下载页


其它资料下载

如果大家想继续了解人工智能相关学习路线和知识体系,欢迎大家翻阅我的另外一篇博客《重磅 | 完备的人工智能AI 学习——基础知识学习路线,所有资料免关注免套路直接网盘下载》
这篇博客参考了Github知名开源平台,AI技术平台以及相关领域专家:Datawhale,ApacheCN,AI有道和黄海广博士等约有近100G相关资料,希望能帮助到所有小伙伴们。

这篇关于基于Pandas+余弦相似度+大数据智能护肤品推荐系统——机器学习算法应用(含Python工程源码)+数据集的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/167865

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空