给定一个用户需求(query),如果搜索系统展示的搜索结果是根据文档和query的相关性由高向低排序的,那么这个搜索引擎是最优的。在文档集合的基础上计算其相关性估计是其核心~

概率排序原理

以往的向量空间模型是将query和文档使用向量表示然后计算其内容相似性来进行相关性估计的,而概率检索模型是一种直接对用户需求进行相关性的建模方法,一个query进来,将所有的文档分为两类—-相关文档不相关文档,这样就转为了一个相关性的分类问题,赞!

对于某个文档$D$来说,$P(R|D)$表示该文档数据相关文档的概率,则$P(NR|D)$表示该文档属于不相关文档的概率,如果query属于相关文档的概率大于不相关文档$P(R|D)>P(RN|D)$,则认为这个文档是与用户查询相关相关的.

Read More

Shell强大灵活,但是今天在使用Shell处理按行读取文件时发现 读取到的行设定的tab分割符不见了

先看一下演示的待处理文件:

需要做的需求就是将里面的数据使用shell将第一列读取出来做一些其他处理(当然如果仅仅是完成读取首列这个功能,使用awk是最快的,这里只是演示)

Read More

与其说awk是一个强大的文本处理工具,我更加喜欢称之为轻量级的C语言版脚本,有了它,你就能非常自由,轻松的操作文本文件了。ps:比Excel更加方便哦,一句话:awk可以带你装b带你飞~

初体验:九九乘法表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#! /bin/awk -f

BEGIN{
print "lets begins"
}

{
for(i=1;i<=NR;i++)
printf("%sx%s=%s\t",NR,i,NR*i)
printf("\n")
}

END{
print "ends"
}

在先看awk程序之前,咱先来看一下由他实现的一个九九乘法表

yans-MacBook-Pro:Downloads yanyl$ seq 9 | awk -f chengfa.awk
lets begins
1x1=1
2x1=2    2x2=4
3x1=3    3x2=6    3x3=9
4x1=4    4x2=8    4x3=12    4x4=16
5x1=5    5x2=10    5x3=15    5x4=20    5x5=25
6x1=6    6x2=12    6x3=18    6x4=24    6x5=30    6x6=36
7x1=7    7x2=14    7x3=21    7x4=28    7x5=35    7x6=42    7x7=49
8x1=8    8x2=16    8x3=24    8x4=32    8x5=40    8x6=48    8x7=56    8x8=64
9x1=9    9x2=18    9x3=27    9x4=36    9x5=45    9x6=54    9x7=63    9x8=72    9x9=81
ends
yans-MacBook-Pro:Downloads yanyl$

Read More

Hadoop Streaming是一个便于变成Map Reduce程序的工具包,这个工具包可以支持各种可执行/脚本语言来创建Mapper和Reducer,利用Hadoop的优势进行大数据的处理,这些语言仅仅只需要支持*unix的表示输出输入即可(python,c,c++,perl,akw etc.)

Streaming实践

先直接来看一个由python写的Streaming程序,还有那个经典的word count,我们的数据集是一篇英语作文,
看来看他的mapper文件

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python
#-*- coding=utf8 -*-

import sys,re

re_english = re.compile(u'[^a-zA-Z0-9\-]+')

for line in sys.stdin: #这里你可以看做是map类中的line输入
words = re_english.sub(' ',line.strip()) #这里只提取英文数字
for word in words.split():
print '%s\t%s' % (word, 1) #这儿就是标准的输出,用tab隔开 默认第一个值为key

Read More

Shell脚本是非常强的大一个脚本语言,但是不用会手生,所以在此记录Shell脚本的相应关键点,也做查字典用^_^

变量

变量定义

先来简单的看一下变量定义的规则

  1. Shell中,使用变量之前不需要事先声明,只是通过使用它们来创建它们;
  2. 在默认情况下,所有变量都被看做是字符串,并以字符串来存储;
  3. Shell变量是区分大小写的;
  4. 在赋值变量的时候等号两端不能有空格-_-

Read More

KNN算法

给一个训练数据集和一个新的实例,在训练数据集中找出与这个新实例最近的k个训练实例,然后统计最近的k个训练实例中所属类别计数最多的那个类,就是新实例的类。

点我查看详情

但是该算法每次在查询k个最近邻的时候都需要遍历全集 才能计算出来,可想而且如果训练样本很大的话,代价还是很大的,那有没有啥方法可以优化呢?本文就针对KNN算法实现一个简单的KD

KD树

KD树是一个二叉树,表示对K维空间的一个划分,可以进行快速检索(那KNN计算的时候不需要对全样本进行距离的计算了)

比如针对6个二维数据点{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)},可以形成以下树形结构以及空间划分

Read More

numpy这个科学计算工具大法好,但是里面的东西不用老是会忘,所以在此记录常用的一些语法,以备之后查询之用(也叫懒人模式)^_^,不过详细的使用方法还是得看scipy api

使用之前首先得引入包

1
import numpy as np

array

np.array实现了真正的数组,在numpy中其实就是矩阵啦,同时提供了丰富的矩阵计算方法

Read More

Scala语言是出了名的语法诡异,功能强大-_-,他的Iterator也是如此,还提供了亲民心的size/length方法,但是,但是,但是慎用!!

事情是这样的

今天在做这个:进行采样,在mapPartitions中操作,会传来一个Iterator迭代器,里面存着原始数据,我需要做的大概是先统计迭代器中的数量N(使用size方法来做),然后计算出一个需要采样的量n,然后遍历(直接for来做)这个迭代器,按自己的业务采样n个记录!

清晰明了的一个程序,这尼玛最终采样的变量一直是空,一直是空,一直是空。
起初还以为是概率那块算错了,导致采不出来,但是单独把程序剥离出来debuge发现这个for压根没数据,但是明明这个迭代器的里面的size是有值的啊,奇了怪了。。。

Read More

python相当方便,有问题可以直接查Doc,但是Doc略有繁琐,所以在词记下常用的一些技巧以及bug解决方案^_^

判断字符串的一些东西

当然下面的判断完全可以自己使用正则表达式来些,但是有一句话是杀鸡焉用牛刀,下面的api使用起来就会非常便捷

s为字符串

  1. s.isalnum() 所有字符都是数字或者字母
  2. s.isalpha() 所有字符都是字母
  3. s.isdigit() 所有字符都是数字
  4. s.islower() 所有字符都是小写
  5. s.isupper() 所有字符都是大写
  6. s.istitle() 所有单词都是首字母大写,像标题
  7. s.isspace() 所有字符都是空白字符、\t\n\r

自带的排序函数

python中有两种排序方式:

  1. list.sort(func=None, key=None, reverse=False):这种排序会改变list自身的数据
  2. sorted(list,func=None, key=None, reverse=False):这种会重新生成一个新的list

最简单的栗子:

1
2
3
list=[1,3,4,2,4,7]
list.sort()
print list

会输出

[1, 2, 3, 4, 4, 7]

反向排序

1
2
3
list=[1,3,4,2,4,7]
list.sort(reverse=True)
print list

会输出

[7, 4, 4, 3, 2, 1]

对指定关键字进行排序:

list=[('a',100),('b',10),('c',50),('d',1000),('e',3)]
list.sort(key=lambda x:x[1])
print list

可以看到结果:

[('e', 3), ('b', 10), ('c', 50), ('a', 100), ('d', 1000)]

若不指定,貌似是按第一个关键词排序

还有两种方式均可以完成指定关键词方式:

1
list.sort(lambda x,y:cmp(x[1],y[1]))
1
2
import operator
list.sort(key=operator.itemgetter(1))

按多关键字排序

1
2
3
list=[('a',100),('b',10),('c',100),('d',1000),('e',100)]
list.sort(key=lambda x:(x[1],x[0]))
print list

1
2
3
4
5
import operator

list=[('a',100),('b',10),('c',100),('d',1000),('e',100)]
list.sort(key=operator.itemgetter(1,0))
print list
[('b', 10), ('a', 100), ('c', 100), ('e', 100), ('d', 1000)]

sorted传参一样,只是会返回一个新的实例而已

异常处理

语法结构

1
2
3
4
5
6
try:
block
except [Exception as e]:
do...
finally:
do...

for Example:

1
2
3
4
5
6
7
try:
1/0
except Exception as e:
print 'err'
raise e
finally:
print 'end'

动态载入库

有时候需要载入的库是动态的,类似Java的反射

const_en.py

1
name="xiaoming"

const_ch.py

1
2
3
#! -*- coding=utf-8 -*-

name="小明"

test.py

1
2
3
4
5
6
7
8
#! -*- coding=utf-8 -*-
import sys

const = __import__('const_en')
print const.name

const = __import__('const_ch')
print const.name

可以看到输出结果:

xiaoming
小明

参数中*和**的使用

Python函数的入参列表中经常会看到*和**,他们其实并不是代表指针或者引擎,其中
*表示传递任意个无名字参数,放置在一个元组中,比如

1
2
3
4
5
def array_para_test(a,b,*c):
print a,b
print c

array_para_test(1,2,3,4,5)

它的最终输出将会是

1 2
(3, 4, 5)

**表示任意个有名字的参数,用于存放在字典中进行访问,比如

1
2
3
4
5
def dict_para_test(a,b,**c):
print a,b
print c

dict_para_test(1,2,name="tome",age=23)

他的最终输出是

1 2
{'age': 23, 'name': 'tome'}

下面应该回持续更新