数学建模预测模型实例(四)---食堂菜品推荐系统

数学建模预测模型实例(四)—食堂菜品推荐系统

数学建模预测模型实例(一)—大学生体测数据模型
数学建模预测模型实例(二)—表白墙影响力量化模型
python预测算法—线性回归
数学建模预测模型实例(三)—双色球概率预测模型
数学建模预测模型实例(四)—食堂菜品推荐系统

前言

在这里插入图片描述
看到这张海报大家有没有觉得很熟悉?为了解决佩奇每天下课吃什么这一世纪难题,佩奇和奇趣多多的各位团结一心开发出了一种全新的推荐算法!在发布的这一周里大家的积极参与给了我们很多新的思路,也让我们能够不断debug,推荐功能在今天将会正式关闭,我们会放出所有核心源码以及思路,期待与大家的思维碰撞!

特征提取

在冒出这个想法之后,有着丰富数学建模经验的佩奇首先就想到了美团,大众点评,乃至于淘宝的猜你喜欢模块。

秉持着专业的精神,奇趣多多还原了这些推荐机制的运作过程:
在这里插入图片描述
其实总结起来就是:将大量的用户数据聚集在一起,随后提取特征并进行相似度分析,找出爱好相似的两个人进行相互推荐。

针对这个推荐思路,奇趣多多首先就想到了提取特征,对于入口的饭菜而言,特征也不外乎就是菜系,油腻程度,荤素搭配,食材,调味,制作过程,以及价格这七个特征。针对这七个特征,奇趣多多以五分制给每一道菜都打了分。部分打分结果见下图。
在这里插入图片描述

相似度分析

根据刚刚的推荐思路,在特征提取之后就是相似度分析了,而相似度分析说白了就是分类,而一提到分类,奇趣多多就想到了数学建模中常见的决策树算法

决策树算法,就像下面这张图一样是一个根据条件进行选择的过程,而这一个个的节点都是基于我们现有的特征进行自动选取的
在这里插入图片描述
在明白决策树算法之后大家可能会感到疑惑,既然这是个分类算法,那么分类的标准又在哪里呢?

问到点儿上了,为了弥补没有以往用户数据这一问题,奇趣多多选取了十道具有代表性的菜品作为分类标准。对!就是你们参与推荐时五分制打分的那十道菜。criteria一列所传入的就是每个人独一无二的打分数据。

在这里插入图片描述

算法实践

预处理

在算法训练前我们首先需要剔除七个特征中对此次分类较小贡献的特征。

#### 剔除与对分类结果贡献较小的特征
target  =pre_data['criteria']
data = pre_data.drop(['criteria','name'],axis=1)
data_train,data_test,target_train,target_test=train_test_split(data,target,test_size=0.2,random_state=42)
predictors = ["classify", "youni", "hunsu", "shicai", "tiaowei", "criteria","price"]
selector = SelectKBest(f_classif, k=5)
selector.fit(data_train, target_train)
scores = -np.log10(selector.pvalues_)
for i in range(len(scores)):
    if scores[i]<0.1 and predictors[i]!='criteria':
        exclude.append(predictors[i])
    elif scores[i]==float(scores.max()):
        k_y.append(predictors[i])
data_ = pos_data.drop(exclude,axis=1)
data_p =  data_.drop(['name'],axis=1)
predictors_best = data_p.columns

算法模拟

在这个阶段奇趣多多先后应用了两种分类算法进行调试:决策树,随机森林。决策树顾名思义就是一颗带有决策条件的树,而随机森林同样的就是很多棵决策树随机排列在一起。

一棵树可能会造成数据结果过拟合,也就是对真实数据解释度较低的问题,而整片森林则不同,对于我们这次推荐器的十个分类数据来说不会因为训练数据的规模小而造成结果的不稳定。

因此最终我们选定利用随机森林进行模拟。

### 随机森林模型训练
data_train = data_train[predictors_best]
data_test = data_test[predictors_best]
kf = model_selection.KFold(n_splits=3)
tree_param_grid = { 'min_samples_split': list((2,3,4)),'n_estimators':list((3,5,10,15,20,25,30,35,40,45,50))}
grid = GridSearchCV(RandomForestClassifier(),param_grid=tree_param_grid, cv=kf)
grid.fit(data_train, target_train)
rf = RandomForestClassifier(random_state=1, n_estimators=35, min_samples_split=2, min_samples_leaf=2)
#### 随机森林模型预测
array = grid.predict(data_p)
pos_data['predict_cri']=pd.DataFrame(array)
like = pos_data.loc[pos_data['predict_cri']==5]
if like.empty:
    like = pos_data.loc[pos_data['predict_cri']==4]
    print(like['name'].head(10))
    if like.empty:
        like = pos_data.loc[pos_data['predict_cri']==3]
        print(like['name'].head(10))
elif 0<len(like)<=10:
    print(like['name'])
elif len(like)>10:
    like = like.head(10)
    print(like['name'])

关键词提取

通过算法模拟之后,我们得出了预测评分为5的前十道菜品作为我们的推荐内容。但是光是这样还不够,我们还想找到大家的喜好关键词,而这时奇趣多多就想到了之前PubMed搜索软件中尝试过的LDA主题词提取模型,没有看过这篇推送的朋友们可以去看看,这里面详细提到了有关LDA主题模型的建立过程。

还在为PubMed查找文献而烦恼吗

LDA主题模型的关键词个数是需要我们自己定义的,所以奇趣多多在这里应用了聚类算法根据推荐结果的特征进行二次分类,将分类个数应用于LDA主题模型

#### 根据特征找出最好聚类个数k
like_ = like.drop(['name','predict_cri'],axis=1)
featureList = like_.columns
mdl = pd.DataFrame.from_records(data, columns=featureList)
for k in range(1, 9):
    estimator = KMeans(n_clusters=k)
    estimator.fit(np.array(mdl[featureList]))
    SSE.append(estimator.inertia_)
for i in range(len(SSE)):
    if i+1<len(SSE):
        if SSE[i]-SSE[i+1]<=20:
            k_.append(i+1)
#### 对于最喜欢的菜名进行分词预处理
file_userDict = ['石锅拌饭','焗饭','意面','猪排饭','牙签肉','蔬菜卷','鸡饭','照烧','烤肉拌饭','鸡排饭']
jieba.load_userdict(file_userDict)
name = like['name']
name = list(name)
for na in name:
    text_split =jieba.cut(na)
    FullMode =  ' '.join(text_split)
    doc_clean.append(FullMode)
for doc in doc_clean:
    doc_=doc.split()
    d_c.append(doc_)
dictionary = corpora.Dictionary(d_c)
doc_term_matrix = [dictionary.doc2bow(doc) for doc in d_c]
### 应用LDA主题模型提取k个主题关键词
Lda = gensim.models.ldamodel.LdaModel
ldamodel = Lda(doc_term_matrix, num_topics=k_[0], id2word = dictionary, passes=50)
result=ldamodel.print_topics(num_topics=k_[0], num_words=1)
for i in range(len(result)):
    print('第{}类{}'.format(i+1,result[i]))

系统思路

在这里插入图片描述
关注公众号奇趣多多,回复关键词“食堂”获取源码及数据!
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

佩瑞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值