Implementing Slope-One in T-SQL

Slope-One, the simplest form of non-trivial item-based collaborative filtering based on ratings. (Original Paper)
Referencing to Bryan O’Sullivan’s tutorial of implementing Slope One in Python, I write a the implementation in T-SQL. Believe it useful to many people and projects.

Brief process summary

  • Define the fact table as user data.
  • Calculating intermediate matrix(FreqDiff). The information about users is eliminated and frequency/ score differences data between items is produced.
  • Predicting from user input score with the intermediate data.

Data schema

The UserData is fact table of business transactions. I use an view to wrap it for switching between testing data and working data.
The Freq&Diff matrix is square and sparse. Only non-zero values is meaningful and stored. And a half-matrix triangle holds full information about the matrix.
There created two indices to avoid heavily bookmark-lookup.

create table UserData (                  -- fact table
    userid   varchar(50) not null,
    itemid   varchar(50) not null,
    rating   float not null default 0,
    updtime  datetime default getdate(),
    primary key (userid, itemid)
)
GO

create table FreqDiff (                  -- Freqs and Diffs
    itemid1  varchar(50),
    itemid2  varchar(50),
    freq     float not null default 0,
    diff     float not null default 0,
    updtime  datetime default getdate(),
    primary key (itemid1, itemid2)
)
GO
create index idx_freqdiff_itemid1 on FreqDiff(itemid1, freq, diff, itemid2)
create index idx_freqdiff_itemid2 on FreqDiff(itemid2, freq, diff, itemid1)

/*
 * The matrix FreqDiff is *almost* symmetric,
 * so only half of the data need to be stored.
 * There would be huge of space (50%) saved for large dataset.
 */
alter view vw_freqdiff as
select itemid1 as itemid1, itemid2 as itemid2, freq,     diff from FreqDiff fd
union all
select itemid2 as itemid1, itemid1 as itemid2, freq, -1* diff from FreqDiff fd
GO

/*
 * Wrap for userdata,
 * switch from one model to another easily.
 */
alter view vw_userdata as
select * from userdata
GO

Testing data

Same as Bryan’s but names changed for easily debugging print.

-- init userdata, Bryan O'Sullivan's sample data is used
insert into UserData values ( 'u1', 'i1',  1, getdate() )
insert into UserData values ( 'u1', 'i2', .5, getdate() )
insert into UserData values ( 'u1', 'i3', .2, getdate() )
insert into UserData values ( 'u2', 'i1',  1, getdate() )
insert into UserData values ( 'u2', 'i3', .5, getdate() )
insert into UserData values ( 'u2', 'i4', .2, getdate() )
insert into UserData values ( 'u3', 'i1', .2, getdate() )
insert into UserData values ( 'u3', 'i2', .4, getdate() )
insert into UserData values ( 'u3', 'i3',  1, getdate() )
insert into UserData values ( 'u3', 'i4', .4, getdate() )
insert into UserData values ( 'u4', 'i2', .9, getdate() )
insert into UserData values ( 'u4', 'i3', .4, getdate() )
insert into UserData values ( 'u4', 'i4', .5, getdate() )
GO

Processing the intermediate table

-- update process
delete FreqDiff
insert into FreqDiff
select
    ud1.itemid, ud2.itemid, count(*), (sum(ud1.rating - ud2.rating))/count(*), getdate()
from
    vw_userdata ud1
    join vw_userdata ud2 on
            ud1.userid = ud2.userid
        and ud1.itemid > ud2.itemid
group by ud1.itemid, ud2.itemid

Predicting

-- predict process
declare @pref table(itemid varchar(50), rating float)
insert into @pref values('i1', 0.4)

select -- distinct top 10
    itemid1,
    sum(freq)                               as freq,
    sum(freq*(diff + rating))            as pref,
    sum(freq*(diff + rating)) /sum(freq) as rating
from
    vw_freqdiff fd
    join @pref p on fd.itemid2 = p.itemid
where itemid1 not in( select itemid from @pref )
group by itemid1

Further works as intermediate data updating seems easy.
So, writing here, listening for suggestions.

“逆转瓮安”,很有创意,值得一看

Gridview排序和分页的基本机制

排序

  • 客户端PostBack。
  • 在Sorting事件中,取得排序的列及排序方向。
  • 调用DataSource的排序方法。
  • 重新DataBind

分页

  • Gridview读取全部的数据源数据。
  • 在PageIndexChanging事件中,取得要前往的页编号(e.NewPageIndex)
  • 数据绑定前,设置PageIndex属性,实现分页。

也就是说,分页完全是在ASP.NET中进行的,对于大量数据集就会有性能问题。
解:

Config VirtualBox with Host Interface Networking (HIF)

Diagram as the note.

Config VirtualBox with Host Interface Networking (HIF)

党委、政府PK不过黑恶社会?(转载自人民网)

人民网是老胡最爱上的网,能登这种文章不容易。早晚要删,留个底子。
http://leaders.people.com.cn/GB/7468985.html
党委、政府PK不过黑恶社会?

2008年07月04日09:28 来源:人民网
【字号 大 中 小】 打印 留言 论坛 网摘 手机点评 纠错
E-mail推荐:

  6月28日下午,贵州省瓮安县城发生一起严重的围攻政府部门和打砸烧突发事件。一些人因对瓮安县公安局对该县一名女学生死因鉴定结果不满,聚集到县政府和县公安局,并点火焚烧多间办公室和一些车辆。贵州省委书记、省人大常委会主任石宗源给“6.28”事件定性为“是黑恶势力人员直接插手参与的,公然向我党委、政府挑衅的群体性事件。”但他也说“6.28”事件何以由一起单纯的民事案件酿成一起严重的打、砸、抢、烧群体性事件,也是由于诸如当地一些社会矛盾长期积累,而没有得到及时有效的解决而造成的。他也列举了这些深层次的矛盾。

  由“6.28”事件我们可以这样的看:每次发生大规模的群体事件,不管是什么原因引起,官方的结论都是千篇一律——都不是政府的错!就石宗源给“6.28”事件下的定性结论来看也是逻辑混乱:黑恶社会凭什么挑衅政府、挑衅党委?老百姓凭什么或为什么跟着黑恶社会走而不跟着政府走?什么是黑恶社会?和党委政府作对的那是什么样的黑恶社会?有直接与政府作对的黑恶社会吗?哪一个黑恶社会不是积极主动的与政府官员勾结,拉政府官员做靠山、做保护伞而能黑、能恶的?!难道堂堂伟光大的执政党的半个多世纪的国民教化,还抵不住区区几个黑恶社会的混混的煽动有力度?唯一可解释的就是那瓮安县党委、政府黑了、恶了!否则的话就是瓮安县的老百姓黑白不分。

  当然,黑恶社会组织的本质一定是反党、反政府、反法律的。然而,政府和党委也是由官员的个体组成的,在某种意上说与党委或和政府的一把手勾结起来和与党委、政府勾结起来的区别不是很本质。有地方党委、政府其实就是党委和政府的化身。有了党委和政府的一把手做保护伞,其实与有党委、政府撑腰而护黑、护恶没什么区别。有的时候一个地方的党政一把手黑了恶了与那里的政府黑了、恶了也没什么大区别。

  就“6.28”的性质来讲,我不怎么同意石宗源的说法。与其说这个说法有假借黑恶社会公然挑衅政府的大帽子而为政府党委执政的无能遮羞之嫌,还不如说就是老百姓不信任政府的心态已经发展到了很严重的程度了更贴切。话又说回来,难道党委、政府不容挑衅吗?挑衅党委又犯了那条国法?黑恶社会也好,老百姓也罢,这些人又不是中共党员,挑衅党委又何罪之有?难道西方国家的反对党都是黑恶社会不成?

  政府或执政者在面对针对政府的大规模群体事件时,不能总是说与政府作对就怎么样的恶劣或十恶不赦。中国由于封建文化的作祟,在执政者的心目中凡是反对官府的或反对政府的都是刁民。

  现在——为什么一些黑恶社会分子就能煽动或挑动上万群众包围县政府?过去——老百姓为什么拼死也要保护中共的干部?这——才是值得执政者深思的。

  如果执政者只是一味的要严打那些打砸烧的人,或以严厉的打击这些打砸烧的行为而吓唬或恫吓、镇压民众而达到使得民众对政府或官员敬畏有加的目的,也就是采用杀鸡吓猴的惯用做法,我想只能是越来越不灵光。反右、文革、天安门事件以及最近的周老虎这些群体事件又哪一件不是政府对不住老百姓的?哪一个不是时隔很长时间执政者才期期艾艾的认错?社会或老百姓付出的代价又是何等的大?可以说在中国社会古往今来没有哪次群体事件是错在老百姓的。屈死不告官的老话就是真实的写照。

  不要动不动就拿与政府作对说事。与政府作对在某种意义上说也是公民社会的正当权利的一种表现形式。处处迎合政府那不是公民社会,那是封建专制社会才会有的顺民规范。当然以打砸烧的方式与政府作对那是任何社会都不允许的违法犯罪行为。但是,官员们的胡作非为,也是老百姓们冲动或不理智的根源。官员平日里又是怎样粗暴的不理性的对待老百姓的?这才是值得执政者在群体事件发生时发生后要深思不已的。否则的话,不论执政者怎样的以手中的话语权或法律来镇压群体事件,只能是扬汤止沸或抱薪救火。

  当公民与政府发生矛盾冲突时,首先是要政府深刻反思自己的执政行为,而不是抓住群体事件中的某些违法的东东抹黑整个群体事件与老百姓的正当诉求,为自己的错误开拓,甚至倒打一耙。就像美国炸了中国驻前南大使馆后,学生们围住美国驻中国使领馆,这样的游行又何尝事先报公安机关批准过?公安机关又何尝镇压过?

  法律不能搞机会主义、实用主义。政府不能看见与自己一致的群体事件就以胡萝卜相待,看见与自己不一致的群体事件就大棒子伺候。法律不是捏糖人儿。

  在中国每一个群体事件的发生都不是容易的事情。中国人对待政府有天生的惧怕心理。如果不到万不得已,不到死活一个价的时候,断不会揭竿而起。正所谓官逼民反、逼上梁山。

  至于“6.28”事件是不是逼上梁山,是不是真的逼上梁山,还是伪的逼上梁山,不管是真的、还是伪的逼上梁山,群体老百姓只要采取了或有了上梁山的做法或心态,都是执政者的失败!(东北大虫)

  本文仅代表作者个人意见,不代表人民网观点。如需转载,请与作者本人联系。

在线化学结构式图片生成服务

利用一些网站提供的资源,可以在线生成结构式图片。其中比较突出的是DayLight提供的服务,在另外一篇 结构式图片生成服务, DayLight SMI2GIF 中做过详细介绍。DayLight的服务传入的结构式参数是SMILES,而且有很丰富的参数以调节输出效果。

NIST是美国国家标准与技术局(National Institute of Standards and Technology),NIST WebBook 是老牌的免费化合物信息数据库,提供丰富的化合物物理、化学性质数据。其化合物的编码方式,其实是CAS号码。把CAS号码转换成数字,就可以很容易得到结构式图片的地址了。

http://webbook.nist.gov/cgi/cbook.cgi?Struct=C490119

NIST WebBook的数据量并不是很大,只有几万条记录。不知道是不是因为太老的原因(05年就没再更新过),其中还有错误数据。至少到这篇发布的时候,上面的例子仍就是一个错误结构。我写Email报告了这个问题,不知道啥时候能修正。

NLM是(National Library of Medicine) 它提供的ChemIDPlus数据库 也是用CAS号码进行编码的。数据量要比NIST大很多,结构式输出的质量也更好。

http://chem.sis.nlm.nih.gov/chemidplus/RenderImage?maxscale=30&width=200&height=200&superlistid=000490119

对于化合物的标记,SMILES是公开的标准,直观还原结构式信息,值得应用;CAS不公开不免费,但也成为了既成的行业标准。现在能与CAS相提并论的,我想就是NCBI的PubChem 数据库了。NCBI是美国国立生物技术信息中心(The National Center for Biotechnology Information。在在线数据库的范畴内来说,PubChem的Compound ID(cid)基本上是必被引用的。所以也勉强将它用cid作结构参数的图片生成接口纳入进来。这个接口背后也有很多参数用以调节输出。

http://pubchem.ncbi.nlm.nih.gov/image/imagefly.cgi?cid=10273&width=400&height=400

有一篇很好的文章,Thirty-Two Free Chemstry Databases(32个免费化学数据库) ,仔细读过的话也许还会有更多的发现。

下载Google App Engine站点的代码

GAE到目前为止并没有提供从站点上下载或备份代码的功能,本地的开发代码一旦丢失或损坏,就会有无法恢复的麻烦。所以本地代码用SVN之类的管理工具管理起来是很必要的。
Manatlan编写了一个工具,可以将整个GAE站点的代码打成zip包下载。是一个很简单的过程

      在根目录下根据manatlan的代码建立zipme.py。
      在app.yaml中加入handles: - url: /zipme script: zipme.py。
      访问youapp.appspot.com/zipme即可。

这个程序会通过google的身份认证来判断访问者是不是管理员。而且对于各个版本的代码,也可以分别下载了。
不过不能直接访问代码的确是GAE的明显缺陷。

  • 代码可能损坏或丢失而无法恢复
  • 使得合作开发模式也并不灵光,开发者之间需要其他渠道交换和维护代码。
  • 代码的版本和发布的版本不好对应。

所以相信这个问题很快会解决掉,至少能和Google Code结合在一起,代码管理和发布管理的功能集成起来。

Firefox加载Java Applet后死翘的问题

现象就是加载了带Java Applet的网页后,直接死翘或者在关闭页面的时候死翘,整个Firefox失去响应,只能强制结束进程。
真好吃: JVM卡死firefox提出了正解。

我的firefox有时候不能正常现实applet
反映就是卡死firefox
但是有一个奇怪的现象就是 如果运行本地的网页applet后
在不关闭firefox的前提下 去看含有applet的网页没有任何问题

我百思不得其解 最后分析出了一个大概的原因
jvm大概无法获取firefox的代理服务器设置
所以就卡死掉了

我在java 控制面板中代理服务器设置选择直接连接就解决问题了

如图设置,搞定
JVM connection setting

结构式图片生成服务, DayLight SMI2GIF

SMILES的发明者,DayLight公司提供了一个非常实用的Web Service工具,可以在线通过化合物的SMILES编码,生成它的结构式图片。这个工具就是SMI2GIF 。它是基于DayLight公司的产品”HTTP Toolkit“建立的。我们可以购买这个产品自己建立Web Service,也可以直接在线使用DayLight提供的服务。

下面的图片是一个最简单的在线应用。

图片的HTML代码是

        <img src="http://www.daylight.com/dayhttp/smi2gif?smiles=Oc1ccccc1"></img>
    

DayLight给出了一个参考文档,对这个接口的调用参数和功能,讲述得非常详细。下面就把简单的,我也懂的参数作一点举例介绍。

图片的高度和宽度,线条的粗细,输出的格式(PNG/GIF)

        http://www.daylight.com/dayhttp/smi2gif?width=100&height=100&smiles=O%3DC1CCCCC1&Linewidth=thick&output=PNG

色调搭配

提供了几种基本色调


COB
- color on black

COW
- color on white

COP
- color on paper

BOW
- black on white

BOP
- black on paper

WOB
- white on black

WOP
- white on paper

        http://www.daylight.com/dayhttp/smi2gif?smiles=O%3DC1CCCCC1&colormode=COW
    

对原子单独指定颜色

        http://www.daylight.com/dayhttp/smi2gif?numcolors=10&tdt=%24SMI%3COCCCCCCCCCC%3EALAB%3C0.0%2C.1%2C.2%2C.3%2C.4%2C.5%2C.6%2C.7%2C.8%2C.9%2C1.0%3E%7C
    

是否显示手性结构

        http://www.daylight.com/dayhttp/smi2gif?hide_chi_h=false&smiles=C[C%40%40H](N)C(%3DO)O
    

突出显示子结构

这样的功能一般都用在子结构检索之后的结果输出中。

        http://www.daylight.com/dayhttp/smi2gif?smiles=O%3DC1CCCCC1&highlight=O%3DC
    

URL编码

对查询URL中的SMILES字符串,应该用URL-Encode(RFC1738)进行编码。同时,SMI2GIF也支持省略掉百分号的简洁编码方式,比如 (O=C1CCCCC1)可直接表示成 4f3d4331434343434331

参数缩写

SMI2GIF的各个参数,都可以按照下面的映射进行缩写

Option Abbreviation
colormode c
fromto f
height he
hide_chi_h hi
hlen_pct hl
hydrogens hy
numcolors linew
linewidth n
old_style ol
orient or
output ou
reaction r
scale sca
schematic sch
smiles smil
smirks smir
tdt t
width w
xsmiles x

秃瓢

之前 之后
之前 之后

没哭,非常配合,完全出乎爸爸和姥姥的预料。不过也说明爸爸手艺高超。

嘿嘿,既然给我剃了个少林寺头,那我就练个无影手。

无影手

Next Page »

Random posts

  • 我的1997和2007
  • InChiKey
  • 用Beyond Compare同步网站更新
  • 母亲节,城墙下的笑容
  • XSLT中的DISTINCT和GROUP