热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

皮一下之技术流保命法

当女票发来一套送命题,程序员应该怎么做?这个时候,我感觉到后脊梁骨一阵发凉,果不其然。正在喝水的我,差点没被噎
当女票发来一套送命题,程序员应该怎么做?

这个时候,我感觉到后脊梁骨一阵发凉,果不其然。正在喝水的我,差点没被噎死。发来如下题目,就是说,如果我俩越默契,答案就越相似,题目是这样的。

请给以下唇色评分(5分制),评出你对每一个的喜好程度?

额?你给大直男,发这种测试,真的好吗?我这些是啥色都认不全,哪里知道选多少分哦?只能凭感觉蒙吧~

我以为把答案丢给他,然后她比对我的答案,看下我大概哪些题每答对就好了。好吧。我太小看女生心思了。她把这些测试都发了一份给她的闺蜜们,得出了10个人的得分,然后让我选择其中哪一个是她。大兄弟们,也就是说,如果选了她的一位闺蜜,那就危险了。

正好最近看了推荐系统的章节,发现这个和推荐系统的相似度计算很相似,首先咱们理一下数据的情况,咱们选项按照分数级来分1~5表示喜好程度。每一个人呢,我们就用字典的key形式给她做编号,比如第一个闺蜜(或女票)就是per_1唇色就用编号lip_1,那么第一个人的数据类似于这样的

{ # 第一个人"per_1": {# 第10个唇色 : 3分,下同"lip_10": 3,"lip_9": 1,"lip_8": 5,"lip_1": 2,"lip_3": 2,"lip_2": 3,"lip_5": 4,"lip_4": 1,"lip_7": 1,"lip_6": 1}}

这里核心就是,只要我们每一题和女票回答的尽可能相近就能够把最后相近度控制在最小。这里我们采用欧几里得公式来求解,别看这个名字挺唬人的,其实原理很简单。就是两点之间的距离计算。

给定两个点 P=(x,y)和Q=(z,t)  ,定义距离

这样看公式不容易理解,没问题,看我的灵魂画图功底。如下,其实咱们就是要求这个d的距离,并且使它最小。

总共有10个唇色偏爱程度,我们只需要根据公式进行加和,最终使得距离值最小即可。

Don't bb, show me the code

def xzz_sim_distance(perfs, person1, person2):'''    小祖宗相似度计算     :return 一个0~1之间的值,越大表示两人相似度越高    '''# 判断如果两人存在共同爱好,跳出来计算两人之间的差值总和# 判断如果两人不存在相同爱好,则返回0for per_person1_like in perfs[person1]:if per_person1_like in perfs[person2]:breakelse:return 0# 计算每一组差值的平方和sum_squares_sim = sum([pow(perfs[person2][per_saw] - perfs[person1][per_saw], 2) for per_saw in perfs[person1] if per_saw in perfs[person2]])# 避免因为两者完全相等时,分母为0;取导数时,则保证,数值越大,表明两者越相关,方便记忆。return 1/(1 + sqrt(sum_squares_sim))

ok,咱们把自己对每一个唇色的喜好程度进行打分,将自己的打分结果与闺蜜们的数据一起打包,形成最终的数据perfs。然后调用 小祖宗相似度计算函数(xzz_sim_distance)看下结果如何。

for per_p in Lips_data:# 不与自己进行比较if per_p == 'per_0':continueprint xzz_sim_distance(Lips_data, 'per_0', per_p), per_p

输出如下:

0.141187848064 per_10
0.179128784748 per_9
0.2 per_8
0.1336766024 per_5
0.2 per_4
0.205213096158 per_7
0.135078105936 per_6
0.139578756837 per_1
0.309016994375 per_3
0.150221104822 per_2

我们可以很容易的看出来,最大值是第三个人。虽然感觉得分还是很低,但是觉得自己推理是没毛病的,颤抖着的手把答案发了过去。

(╯‵□′)╯︵┻━┻ 还没完没了了。但是没办法,谁让她是小祖宗呢?我先审一下题,这次是她们公司的创意库,采集的作品,让我看下各种广告视频,并根据这些个创意进行喜好程度打分。这其实原理和之前一样嘛,也是计算相似度。

所以这里介绍另外一套算法,皮尔逊相关系数,能够修正我这种比较糙的人。对于皮尔逊相关系数不太理解的,可以看下如下资料

如何理解皮尔逊相关系数(Pearson Correlation Coefficient)

皮尔逊相关系数,如下是公式:

show me the code :

def xzz_sim_person(perfs, p1, p2):'''     小祖宗皮尔逊相关系数计算    :return 一个0~1之间的值,越大表示两人相似度越高    '''# 构建共同数据集common = {}for per_p1 in perfs[p1]:if per_p1 in perfs[p2]:common[per_p1] = 1# 得到数据集总数量n = len(common)# 没有共同兴趣爱好if n == 0:return 0# 对所有偏好求和sum1 = sum([perfs[p1][per_common] for per_common in common])sum2 = sum([perfs[p2][per_common] for per_common in common])# 求平方和sq_sum1 = sum([pow(perfs[p1][per_common], 2) for per_common in common])sq_sum2 = sum([pow(perfs[p2][per_common], 2) for per_common in common])# 求乘积和mul_sum = sum([perfs[p1][per_common] * perfs[p2][per_common] for per_common in common])num = mul_sum - sum1*sum2/nden = sqrt((sq_sum1 - pow(sum1, 2)/n)*(sq_sum2 - pow(sum2, 2)/n))if den == 0:return 0r = num/denreturn r

每写一个相似度匹配算法,咱们就得排序一下结果,看看谁分值较高,挺麻烦的,那就写一个通用的小祖宗最n临近人算法(名字瞎取的)方便复用:

def xzz_top_matches(prefs, person, n=5, similarity=xzz_sim_person):'''    小祖宗最n临近人算法    寻找与自己最相近的n个人,并给出相似度评分    '''scores = [(similarity(prefs, person, per_person), per_person) for per_person in prefs if per_person != person]scores.sort()scores.reverse()return scores[0:n]

咱们来调用一下看看结果如何:

print xzz_top_matches(Videos_data, 'per_0', n=5, similarity=xzz_sim_person)

输出如下

[(0.520765483515341, 'per_32'),
(0.4597024642476977, 'per_29'),
(0.34642796561282824, 'per_21'),
(0.3054957597202306, 'per_33'),
(0.2796316410812393, 'per_10')]

激动地酱不出话,从50个人当中找出评分,一个个比对,我找出来,估计也到后年腊月了吧?颤抖着手把猜测结果发了过去。

好了,又来了,这次倒不是测试,是这样,她在网上找了一堆化妆品品牌的评测,每个牌子都有堆网友的综合评分,她自己对10种牌子有一个自己喜好,并做了评分,但想知道哪个人跟她的喜好相似,因此就可以根据相似人的喜好去买买买。

但是这里面有两个问题有bug

1. 不是每个人都对10个牌子有评价;

2. 有些人有个人好恶,就是说某些品牌可能总体评价不好,但某个人就是钟爱她,这就会造成推荐偏差。

这又要怎么解决呢?easy,咱们可以通过加权计算

我们先计算每个人的相似度,然后看她们对于每一个牌子的评分,与我们的相似度相乘,得到加权后的得分,再和相似度总和相除,便可以得到最后的得分。这就可以避免诸如牌子2有一项没有被该用户评分的情况。

上代码:

def xzz_get_recommendations(perfs, person, similarity&#61;xzz_sim_person):"""    小祖宗物品推荐算法    基于相似度评分,进行加权计算,进行推荐建议    """sim_rew_sum &#61; {}sim_sum &#61; {}for per_person in perfs:# 不与自己比较if per_person &#61;&#61; person:continuesimilar &#61; similarity(perfs, person, per_person)# 忽略总分小于0的情况if similar <&#61; 0:continuefor per_item in perfs[per_person]:# 只对自己没了解过的牌子进行评价if per_item not in perfs[person] or perfs[person][per_item] &#61;&#61; 0:# 相似度*评价值之和sim_rew_sum.setdefault(per_item, 0)sim_rew_sum[per_item] &#43;&#61; perfs[per_person][per_item] * similar# 相似度之和sim_sum.setdefault(per_item, 0)sim_sum[per_item] &#43;&#61; similarranks &#61; [(sim_rew_sum[item]/sim_sum[item], item) for item in sim_rew_sum]ranks.sort()ranks.reverse()return ranks

这里再将品牌数据传到其中即可&#xff0c;再将数据集传入其中即可&#xff0c;结果可喜可贺。可是今晚依然没有约会~至此&#xff0c;我的假女朋友也可以退下了。

anyway&#xff0c;做一个简单总结&#xff1a;

  1. 相似度计算可以通过欧几里得或者皮尔逊相关系数等算法。得分越高越匹配

  2. 皮尔逊相关系数能够修正某一个人出分普遍比另一个人高的情况

  3. 推荐物品时&#xff0c;为了消除个人特殊癖好&#xff0c;或者未打分的情况&#xff0c;可通过加权计算进行修正

特别说明&#xff1a;

本节相关知识点参考书籍《集体智慧编程》

素材来自Internet


推荐阅读
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
  • 使用圣杯布局模式实现网站首页的内容布局
    本文介绍了使用圣杯布局模式实现网站首页的内容布局的方法,包括HTML部分代码和实例。同时还提供了公司新闻、最新产品、关于我们、联系我们等页面的布局示例。商品展示区包括了车里子和农家生态土鸡蛋等产品的价格信息。 ... [详细]
author-avatar
米粒多可爱几_642
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有