Système intelligent de recommandation de produits de soins de la peau basé sur Pandas + similarité cosinus + big data - application d'algorithme d'apprentissage automatique (y compris le code source d'ingénierie Python) + ensemble de données


Insérer la description de l'image ici

Préface

Ce projet combine les outils de traitement de données Pandas et la technologie d'apprentissage automatique pour créer un système intelligent de recommandation de produits de soins de la peau. Le système prend en compte non seulement les caractéristiques de la peau de l'utilisateur, mais également des facteurs tels que les réactions allergiques, et filtre les produits mutuellement contre-indiqués pour fournir des recommandations personnalisées aux utilisateurs qui ne savent pas comment choisir leurs produits de soins de la peau.

Premièrement, le projet collectera des informations sur la peau des utilisateurs, notamment le type de peau (comme sèche, grasse, mixte, etc.) et les allergies particulières ou les réactions sensibles (telles que les allergies à certains ingrédients). Ces informations serviront d’entrée au système de recommandation.

Ensuite, le projet utilisera Pandas pour le traitement et l’analyse des données afin de comprendre les ingrédients, les propriétés et l’efficacité de différents produits de soins de la peau. Cela comprend la liste des ingrédients du produit, les types de peau applicables, les scénarios applicables et d’autres informations.

Le projet appliquera ensuite des algorithmes d'apprentissage automatique et de similarité cosinus pour créer un modèle de recommandation basé sur le type de peau et les caractéristiques d'allergie de l'utilisateur, ainsi que sur les attributs de différents produits de soins de la peau. Ce modèle prendra en compte les besoins et les contraintes de l'utilisateur, comme les réactions allergiques à certains ingrédients, pour lui recommander des produits de soin qui lui conviennent.

Lors de la recommandation de produits, le système prend également en compte les combinaisons de produits mutuellement taboues. Cela signifie que le système évitera de recommander des produits susceptibles de provoquer des effets indésirables ou d’avoir des effets contraires lorsqu’ils sont utilisés.

En fin de compte, les utilisateurs recevront un ensemble de recommandations de produits de soins de la peau adaptés à leur type de peau et à leurs besoins. Ces recommandations peuvent inclure des produits nettoyants, des crèmes pour la peau, des masques et bien plus encore pour répondre aux besoins globaux de soins de la peau de l'utilisateur.

Dans l'ensemble, le projet vise à aider les utilisateurs à faire de meilleurs choix en matière de produits de soins de la peau, en tenant compte de facteurs tels que les caractéristiques de leur peau, leurs réactions allergiques et les interactions entre les produits. Ce système de recommandation de produits de soins de la peau peut améliorer l’expérience des utilisateurs en matière de soins de la peau et garantir que les produits qu’ils choisissent sont sûrs et efficaces.

conception générale

Cette partie comprend le diagramme de structure globale du système et l’organigramme du système.

Schéma de la structure globale du système

La structure globale du système est représentée sur la figure.

Insérer la description de l'image ici

Organigramme du système

Le flux du système est illustré dans la figure.

Insérer la description de l'image ici

Environnement d'exploitation

Cette section comprend l'environnement Python et l'environnement Pycharm.

Environnement Python

La configuration de Python 3.6 et supérieur est requise. Dans l'environnement Windows, il est recommandé de télécharger Anaconda pour terminer la configuration de l'environnement requis pour Python. L'adresse de téléchargement est https://www.anaconda.com/ . Vous pouvez également télécharger un fichier virtuel machine pour exécuter le code dans un environnement Linux.

L'environnement de chaque package de données est le suivant :

import pandas
import numpy
import math
import itertools

Environnement Pycharm

L'adresse de téléchargement de PyCharm est http://www.jetbrains.com/pycharm/download/#section=windows . Après avoir accédé au site Web, cliquez sur TÉLÉCHARGER sous la version Comminity pour télécharger le package d'installation. Une fois le téléchargement terminé, installez-le . Cliquez sur Créer un nouveau projet pour créer un nouveau fichier de projet. L'emplacement est le chemin de stockage du projet. Cliquez sur le symbole triangulaire à côté du projet. Vous pouvez voir que PyCharm a automatiquement obtenu Python 3.6. Cliquez sur Créer pour terminer.

Implémentation des modules

Ce projet comprend 4 modules : lecture de fichiers, algorithme de recommandation, module d'application et fonction d'appel de test. L'introduction de la fonction et le code associé de chaque module sont donnés ci-dessous.

1. Lecture de fichiers

Cette partie lit principalement les caractéristiques de la peau, les attraits et les ingrédients allergiques de l'utilisateur, et importe 5 fichiers d'ensemble de données en même temps, à savoir l'ensemble de données utilisateur, la liste des ingrédients principaux du produit, le tableau des fonctions, la liste des ingrédients de contre-indication et la formule de soin de la peau.

Le code correspondant est le suivant :

#文件读入部分
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. Algorithme de recommandation

Après avoir importé les données, l'algorithme de recommandation est utilisé pour calculer la similarité.

1) Prétraitement des données

Extrayez les données utiles et traitez-les dans un format approprié pour faciliter les appels.

Le code correspondant est le suivant :

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) Calculer la similarité

La similarité est calculée après traitement du format des données. La similarité est composée des enregistrements d'achats des utilisateurs et de la similarité du type de peau, et est finalement pondérée et additionnée.

Le code correspondant est le suivant :

#计算肤质向量(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)   #值为1
        return 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.0
        product = 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) Trier et extraire les produits

Le code correspondant est le suivant :

#提取候选产品表
    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.wxid
        need = 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) Algorithme de recommandation de combinaison

Le code correspondant est le suivant :

  #组合推荐算法
class CombRating():
    def __init__(self,user, pro_withrate, fformula):
        self.user = user
        self.product = pro_withrate
        self.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 = i
                break
        #此处使用总共的产品种类解决数字问题
        #寻找第一个是产品类型的列并记录此前经过的列数
        form_list = []
        total_pro_type = ['水', '乳', '霜', '祛痘凝胶', '洁面']
        type_number = 0
        for j in range(len(self.fformula.columns)):
            if self.fformula.columns[j] in total_pro_type:
                break
            else:
                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_list
    def 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. Module de candidature

Sur la base des utilisateurs calculés et triés, recherchez les produits et traitez le format de données approprié, organisez-les et combinez-les selon les types dans la formule de soin de la peau, tout en tenant compte des tabous mutuels des allergies à un seul produit et des recommandations de combinaison. S'il existe des contre-indications mutuelles ou des allergies, elles seront affichées à la fin pour en informer les utilisateurs.

1) Obtenez le produit final

Le code correspondant est le suivant :

#整合
class Recommendation():
    def __init__(self, user, pro, df_component, df_fake, fformula, ingredient_banned):
        self.user = user
        self.pro = pro
        self.df_component = df_component
        self.df_fake = df_fake
        self.fformula = fformula
        self.ingredient_banned = ingredient_banned
    #诉求筛选得到sub1
    def sub1_product(self):
        #通过用户筛选需求成分,返回筛选后的产品列表sub1
        pro = self.pro
        user = 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 = pro
        return sub1

2) Dépistage des substances allergiques

Après avoir obtenu le produit, examinez les ingrédients du produit auxquels l'utilisateur est allergique.

Le code correspondant est le suivant :

#过敏物质筛选,得到sub2
    def sub2_product(self):
        #通过用户过敏成分筛选产品,得到sub2
        user = self.user
        product = 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_product
        return sub2
    #输入两个产品的ind 返回过敏信息用于后面函数的调用
    def is_pro_component_banned(self, pro1_ind, pro2_ind):
        #输入两个产品的ind 产品成分表、成分禁忌表、总产品表
#根据产品ind判断是否过敏,并且返回禁忌成分的字符串
        df_component = self.df_component
        ingredient_banned = self.ingredient_banned
        pro = self.pro

3) Filtrer les produits mutuellement tabous

Lorsque vous recommandez un ensemble en combinaison, certains ingrédients peuvent être contre-indiqués entre les deux produits. Les utilisateurs doivent donc être informés et autorisés à prendre leurs propres décisions.

Le code correspondant est le suivant :

#对禁忌表进行预处理
        ingredient_name = ingredient_banned.columns
        ingredient_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 + '与' + com2
                    elif 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 + '与' + com2
        return 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_component
        ingredient_banned = self.ingredient_banned
        self.pro = self.pro
        comb_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) Produire des recommandations de produit unique et des recommandations de combinaison

Sur la base des informations sur le produit calculées précédemment, des recommandations de produit unique et des recommandations de combinaison sont émises, et les allergies et les ingrédients tabous sont informés.

Le code correspondant est le suivant :

#单品推荐
    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. Test de la fonction d'appel

Appelez tous les modules précédents et générez des recommandations de produit unique et des recommandations de combinaison.

Le code correspondant est le suivant :

#测试代码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") 

Test du système

Remplacez les données dans le modèle à tester et obtenez les résultats des tests présentés dans les figures 1 et 2.

Insérer la description de l'image ici

Figure 1 : Résultats de la recommandation combinée ! [Insérer la description de l'image ici](https://img-blog.csdnimg.cn/b9e5c80438c244a597d4fe7c1843ca20.png)
Figure 2 : Résultats de la recommandation d'un seul produit

Téléchargement du code source du projet

Pour plus de détails, veuillez consulter la page de téléchargement des ressources de mon blog


Télécharger d'autres informations

Si vous souhaitez continuer à comprendre les parcours d'apprentissage et les systèmes de connaissances liés à l'intelligence artificielle, vous êtes invités à lire mon autre blog " Heavyweight | Complete Artificial Intelligence AI Learning - Basic Knowledge Learning Route, toutes les informations peuvent être téléchargées directement à partir du disque réseau sans suivre aucune routine.
Ce blog fait référence à la célèbre plate-forme open source de Github, à la plate-forme technologique d'IA et aux experts dans des domaines connexes : Datawhale, ApacheCN, AI Youdao et Dr. Huang Haiguang, etc., qui contient près de 100 G d'informations connexes. J'espère que cela pourra aider tous mes amis.

Guess you like

Origin blog.csdn.net/qq_31136513/article/details/132872128