首页 文章 精选 留言 我的

精选列表

搜索[匹配算法],共10000篇文章
优秀的个人博客,低调大师

贝叶斯分类算法实例 --根据姓名推测男女

一.从贝叶斯公式开始 贝叶斯分类其实是利用用贝叶斯公式,算出每种情况下发生的概率,再取概率较大的一个分类作为结果。我们先来看看贝叶斯公式: P(A|B) = P(B|A) P(A) / P(B) 其中P(A|B)是指在事件B发生的情况下事件A发生的概率。 在贝叶斯定理中,每个名词都有约定俗成的名称: P(A|B)是已知B发生后A的条件概率,也由于得自B的取值而被称作A的后验概率。 P(A)是A的先验概率(或边缘概率)。之所以称为"先验"是因为它不考虑任何B方面的因素。 P(B|A)是已知A发生后B的条件概率,也由于得自A的取值而被称作B的后验概率。 P(B)是B的先验概率或边缘概率。 这里可以用一个例子来说明这个公式。 看一个简单的小例子来展示贝叶斯定理 病人的例子:某个医院早上收了八个门诊病人,如下表。 症状 职业 疾病 打喷嚏 护士 感冒 打喷嚏 农夫 过敏 头痛 建筑工人 脑震荡 头痛 建筑工人 感冒 打喷嚏 建筑工人 过敏 打喷嚏 教师 感冒 头痛 教师 脑震荡 打喷嚏 教师 过敏 现在又来了第九个病人,是一个打喷嚏的建筑工人。请问他患上感冒的概率有多大? 根据贝叶斯定理: P(A|B) = P(B|A) P(A) / P(B) 可得满足“打喷嚏”和“建筑工人”两个条件下,感冒的概率如下: P(感冒|打喷嚏x建筑工人) = P(打喷嚏x建筑工人|感冒) x P(感冒) / P(打喷嚏x建筑工人) 假定"打喷嚏"和"建筑工人"这两个特征是独立的(即这两个条件没有相关性,比如不存在说他是建筑工人他打喷嚏的概率比较大或者比较小这种关系),因此,上面的等式就变成了。 P(感冒|打喷嚏x建筑工人) = P(打喷嚏|感冒) x P(建筑工人|感冒) x P(感冒) / P(打喷嚏) x P(建筑工人) 通过统计可得: P(感冒|打喷嚏x建筑工人) = (2/3) x (1/3) x (3/8) / (5/8) x (3/8) = (16/45) 通过贝叶斯公式算出了满足条件下感冒的概率,那么现在贝叶斯分类器如何实现呢? 接上面的例子,从上面我们得出了 P(感冒|打喷嚏x建筑工人) 的值,那么我们可以再算出P(不感冒|打喷嚏x建筑工人) 的值,计算结果如下: P(不感冒|打喷嚏x建筑工人) = P(打喷嚏|不感冒) x P(建筑工人|不感冒) x P(不感冒) / P(打喷嚏) x P(建筑工人) = (3/5) x (2/5) x (5/8) / (5/8) x (3/8) = (16/25) OK,现在我们知道来一个打喷嚏的建筑工人,他感冒的几率是P(感冒|打喷嚏x建筑工人)= (16/45)。不感冒的几率是P(不感冒|打喷嚏x建筑工人)= (16/45)。 通过对概率的比较,我们就可以将打喷嚏的建筑工人分类到“不感冒”人群中(不感冒的概率比较大)。 这就是朴素贝叶斯分类器的最简单的应用了。当然你也看到了,贝叶斯分类器需要我们应用到统计所得的结果,这需要数据量比较大,大到能满足大数定理(大数定理这里就不多解释啦,自行百度即可),以及样本数据足够客观。 接下来我们看一个实际的例子,是我在 github 上看到的一个项目例子,根据姓名来对性别进行分类。看上去觉得很不可思议吧,其实也是用了上述说的贝叶斯分类的方法。 二.贝叶斯分类器根据姓名判别男女 -python 项目github地址:https://github.com/observerss/ngender 先说一下主要思路,我们日常从一个人的名字中,基本上能大致判断这个名字的主人是男是女。比如李大志,这个名字一听就很男性。为什么呢?因为大字和志字男性名字用得比较多。虽然机器一眼看不出来,但它可以通过统计信息来判断。如果有足够多的数据,我们就可以统计出大字和志字用作男性名字的比例,计算概率信息。然后就可以用这些概率,运用上述的贝叶斯公式来进行计算,判定性别。 代码其实不难,各个字的统计数据已经计算好,在项目中给出。我们只需要读取文件数据,存储到 python 的字典中,计算出概率,然后预测的时候进行计算即可。我们先看核心代码,稍后会有例子说明。 里面核心代码文件为: 这里主要讲一下核心代码的内容:https://github.com/observerss/ngender/blob/master/ngender/ngender.py class Guesser(object): //初始化函数,调用下面的_load_model()函数 def __init__(self): self._load_model() //初始化一些参数 def _load_model(self): self.male_total = 0 self.female_total = 0 self.freq = {} //这里加载charfreq.csv文件,这个文件存放的是一些汉字是男女的统计信息 with open(os.path.join(os.path.dirname(__file__), 'charfreq.csv'), 'rb') as f: # skip first line next(f) //将文件中的信息存储,累加,以便稍后计算概率 for line in f: line = line.decode('utf-8') char, male, female = line.split(',') char = py2compat(char) //计算男性总数 self.male_total += int(male) //计算女性总数 self.female_total += int(female) //一个汉字对应的那女数量 self.freq[char] = (int(female), int(male)) self.total = self.male_total + self.female_total //一个汉字是男女概率 for char in self.freq: female, male = self.freq[char] self.freq[char] = (1. * female / self.female_total, 1. * male / self.male_total) def guess(self, name): name = py2compat(name) //去掉姓氏 firstname = name[1:] //过滤掉不在这个unicode编码范围内的字符 for char in firstname: assert u'\u4e00' <= char <= u'\u9fa0', u'姓名必须为中文' //贝叶斯分类器,分别计算出男的概率和女的概率 pf = self.prob_for_gender(firstname, 0) pm = self.prob_for_gender(firstname, 1) //若名字为男的概率较大,则分类为男,反之则为女 if pm pf: return ('male', 1. * pm / (pm + pf)) elif pm < pf: return ('female', 1. * pf / (pm + pf)) else: return ('unknown', 0) //贝叶斯公式的应用 def prob_for_gender(self, firstname, gender=0): p = 1. * self.female_total / self.total \ if gender == 0 \ else 1. * self.male_total / self.total for char in firstname: p *= self.freq.get(char, (0, 0))[gender] return p guesser = Guesser() 上述代码还是比较简单的,首先在初始化的时候会调用 _load_model() 函数,这个函数完成的是一些概率计算工作,比如先将每个字对应是男是女的概率计算好存储在字典中。 然后在计算的时候,先过滤掉姓氏。然后分别计算出这个名字是男是女的概率,比如计算 P(男|李大志)和P(女|李大志),,对比哪个概率大一些,然后进行男女分类。 这里放上一个例子:判断 P(gender=男|name=本山) = P(name=本山|gender=男) * P(gender=男) / P(name=本山) = P(name has 本|gender=男) * P(name has 山|gender=男) * P(gender=男) / P(name=本山) 公式原理为贝叶斯公式,下面对公式中中各个项进行解答,首先明确我们已经统计得到P(gender=男),P(gender=女)的概率。 怎么算 P(name has 本|gender=男)? “本”在男性名字中出现的次数 / 男性字出现的总次数 怎么算 P(gender=男)? 男性名出现的次数 / 总次数 怎么算 P(name=本山)? 这个概率对男女来说都是一样的,所以没必要算出来,即我们只需要比较P(name=本山|gender=男) P(gender=男)和P(name=本山|gender=女) P(gender=女)两部分谁比较大即可做出判断。 以上就是贝叶斯分类器介绍的全部内容啦。 参考文章:http://www.ruanyifeng.com/blog/2013/12/naive_bayes_classifier.html

优秀的个人博客,低调大师

leetcode算法题解(Java版)-13-经典反转链表

一、简单二分搜索 题目描述 Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. You may assume no duplicates in the array. Here are few examples.[1,3,5,6], 5 → 2[1,3,5,6], 2 → 1[1,3,5,6], 7 → 4[1,3,5,6], 0 → 0 思路 题目很简单,二分就能通过 代码 public class Solution { public int searchInsert(int[] A, int target) { //二分查找 int left = 0; int right = A.length-1; while(left<=right){ int mid = (left+right)/2; if(A[mid]==target){ return mid; } else if(A[mid]<target){ left = mid+1; } else{ right = mid-1; } } return left; } } 二、反转链表 题目描述 Reverse a linked list from position m to n. Do it in-place and in one-pass. For example:Given1->2->3->4->5->NULL, m = 2 and n = 4, return1->4->3->2->5->NULL. Note: Given m, n satisfy the following condition:1 ≤ m ≤ n ≤ length of list. 思路 经典的题目,值得反复推敲。设置两个指针,一个指向m的位置,一个指向m之前的那个位置,不断刷新这两个指针的next,达到反转的效果。 注意,这两个指针本身不变化,变化的是他们的next. 这样做,满足了题意中的:do it in-place and in one-place 代码 /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode reverseBetween(ListNode head, int m, int n) { ListNode dummy = new ListNode(0); dummy.next = head; ListNode start = head; ListNode prestart = dummy; for(int i=1;i<m;i++){ prestart = start; start = start.next; } ListNode tem; for(int i=0;i<n-m;i++){ tem = start.next; start.next = tem.next; tem.next = prestart.next; prestart.next = tem; } return dummy.next; } } 三、深搜 题目描述 Given a collection of integers that might contain duplicates, S, return all possible subsets. Note: Elements in a subset must be in non-descending order. The solution set must not contain duplicate subsets. For example,If S =[1,2,2], a solution is: [ [2], [1], [1,2,2], [2,2], [1,2], [] ] 思路 题目要列出所有不重复的,用所给数组中数字组成的非递减数列。 深搜解决问题:注意到不能有重复的数字,之前好像做过类似的题目,今天又碰到了,也就是要让拿的数字不能和已经拿过的一样。if(start>i&&num[i]==num[i-1] 代码 import java.util.ArrayList; import java.util.Arrays; public class Solution { ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>(); public ArrayList<ArrayList<Integer>> subsetsWithDup(int[] num) { if(num==null||num.length==0){ return res; } Arrays.sort(num); findAll(num,0,new ArrayList<>()); return res; } public void findAll(int [] num,int start,ArrayList<Integer> list){ res.add(new ArrayList<Integer>(list)); for(int i=start;i<num.length;i++){ if(i>start&&num[i]==num[i-1]){ continue; } list.add(num[i]); findAll(num,i+1,list); list.remove(list.size()-1); } } }

优秀的个人博客,低调大师

leetcode算法题解(Java版)-12-中序遍历

日子又恢复正常了,浪了半个月。。。还是学习的时候感觉好~~ 一、动态规划 题目描述 Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For example,Given n = 3, there are a total of 5 unique BST's. 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3 思路 题目看上去像是二叉搜索树的题,实际上是动态规划。给到1~n的数,要找出多少种二叉查找树,对于取值为k的数来说,在它左边的又1~k-1,右边的有k+1~n.所以可以把左子树排列的种数乘右子树的种数得到以这个为根的二叉查找树的个数。 用一个状态数组记录下值。 代码 public class Solution { public int numTrees(int n) { if(n==0){ return 0; } int [] f = new int[n+1]; f[0]=1; for(int i=1;i<=n;i++){//外循环,刷新1,2,3,4.。。n的结果 for(int j=1;j<=i;j++){//小循环,计算各个的值 f[i]+=f[j-1]*f[i-j]; } } return f[n]; } } 二、中序遍历 题目描述 Given a binary tree, return the inorder traversal of its nodes' values. For example:Given binary tree{1,#,2,3}, 1 \ 2 / 3 return[1,3,2]. 思路 二叉树的中序遍历,就是所谓的左-中-右。 递归和非递归方法,直接看代码! 代码 //递归 /** * Definition for binary tree * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ import java.util.ArrayList; public class Solution { public ArrayList<Integer> inorderTraversal(TreeNode root) { ArrayList<Integer> res=new ArrayList<Integer>(); if(root==null)return res; inorder(root,res); return res; } public static void inorder(TreeNode root, ArrayList<Integer> list){ if(root != null){ inorder(root.left,list); list.add(root.val); inorder(root.right,list); } } } //非递归 /** * Definition for binary tree * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ import java.util.ArrayList; import java.util.Stack; public class Solution { public ArrayList<Integer> inorderTraversal(TreeNode root) { ArrayList<Integer> res = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); TreeNode node = root; if(root==null){ return res; } while(!stack.isEmpty()||node!=null){ while(node!=null){ stack.add(node); node = node.left; } node = stack.pop(); res.add(node.val); node = node.right; } return res; } } 三、深搜 题目描述 Given a string containing only digits, restore it by returning all possible valid IP address combinations. For example:Given"25525511135", return["255.255.11.135", "255.255.111.35"]. (Order does not matter) 思路 深度搜索+回溯的时候剪枝 代码 import java.util.ArrayList; public class Solution { public ArrayList<String> restoreIpAddresses(String s) { ArrayList<String> res =new ArrayList<String>(); ArrayList<String> ip =new ArrayList<String>(); int start = 0 ; dfs(s,res,ip,start); return res; } public void dfs(String s,ArrayList<String> res,ArrayList<String> ip,int start){ if(ip.size()==4&&start==s.length()){ res.add(ip.get(0)+'.'+ip.get(1)+'.'+ip.get(2)+'.'+ip.get(3)); } if(s.length()-start > 3*(4-ip.size())){//剪枝 return ; } if(s.length()-start+1 < 4-ip.size()){//剪枝 return ; } int num = 0 ; for(int i=start;i<start+3&&i<s.length();i++){ num = num*10+(s.charAt(i)-'0'); if(num<0||num>255){ return ; } ip.add(s.substring(start,i+1)); dfs(s,res,ip,i+1); ip.remove(ip.size()-1); if(num==0){//可以添加0,但不允许有前缀为0的 break; } } } }

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册