任务1 相关节目识别
1.在mysql中对t_movie_douban的title进行排序,注意去掉NULL
setwd('F:/M 2013/chs/work') con<-file('movie_title_sorted.txt', 'r') txt<-readLines(con) series_OVA_index<-grep('OVA', txt) series_OVA<-txt[series_OVA_index] writeLines(series_OVA, 'seriesOVA.txt')
共有261个结果,注意到有例外的情况(用红框圈出)
例外情况:
(OVA实际是标题的一部分)
NOVA珠穆朗玛死亡地带
兽装机攻断空我NOVA
(OVA在前面)
OVA 东京喰种トーキョーグール JACK
OVA 东京喰种トーキョーグール【PINTO】
(OVA包含数字)
名侦探柯南OVA9:十年后的陌生人
解决办法是用正则表达式进行匹配,注意到NOVA珠穆朗玛死亡地带,兽装机攻断空我NOVA这两个例外OVA前面都包含了其他英文字母,那么可以用正则表达式:
'[A-Za-z]OVA|OVA[A-Za-z]|[A-Za-z]OVA[A-Za-z]'
来进行匹配, 先把例外情况去掉。匹配后再判断OVA出现的位置,如果出现在开头,则把后面的返回;如果出现在系列名后,则把前面的返回。此外还要注意大小写的问题。
例子:
> temp
[1] "OVAZ" "OVA2" "NOVA" "NOVAN"
index<-grep('[A-Za-z]OVA|OVA[A-Za-z]|[A-Za-z]OVA[A-Za-z]',temp) temp[index]
结果:
> temp[index]
[1] "OVAZ" "NOVA" "NOVAN"
从结果看到正则表达式成功把所有例外情况识别出来了。
2)再判断OAD:
series_OAD_index<-grep('OAD', txt) series_OAD<-txt[series_OAD_index] writeLines(series_OAD, 'seriesOAD.txt')
共107条结果,如下:
例外情况:
热风海陆BUSHIROAD 通往希望的道路
用正则表达式
index<-grep('[A-Za-z]OAD|OAD[A-Za-z]|[A-Za-z]OAD[A-Za-z]',series_OAD) series_OAD[index]
将例外情况识别出来:
> series_OAD[index]
[1] "热风海陆BUSHIROAD 通往希望的道路"
[2] "最游记 RELOAD"
[3] "最游记 RELOAD GUNLOCK"
[4] "最游记 RELOAD 埋葬篇"
3)判断含有“第x季”的title
series_Season_index<-grep('第[一二三四五六七八九十|0-9]季|第[一二三四五六七八九十|0-9][一二三四五六七八九十|0-9]季|花漾季',txt) series_Season<-txt[series_Season_index] writeLines(series_Season, 'seriesSeasonRefine.txt')
共3941个结果:
4)含有 最终章、序章的title
如 真?假面骑士 序章,"宇宙战舰大和号2199 第七章 “战舰继续前进”" ,勇者义彦第2章:勇者义彦与恶灵之钥
例外:
终章:杀死一个国家英雄的不同方法
夜的第三章
寻:最终章
骷髅人 暗之序章 スカルマン 闇の序章
口袋妖怪:原初之章
恐怖童谣 里之章
交响情人梦 最终乐章 后篇
爱情第二章,爱情外一章 (不同系列)
第27章
5)第x集
series_episode_index<-grep('第[一二三四五六七八九十|0-9]集|第[一二三四五六七八九十|0-9][一二三四五六七八九十|0-9]集|第[一二三四五六七八九十|0-9][一二三四五六七八九十|0-9][一二三四五六七八九十|0-9]集',txt) series_episode<-txt[series_episode_index] writeLines(series_episode, 'seriesEpisode.txt')
6)第x部分
如
铁西区第二部分:艳粉街
铁西区第三部分:铁路
铁西区第一部分:工厂
眼睛/机器:第一部分
series_part_index<-grep('第[一二三四五六七八九十|0-9]部分|第[一二三四五六七八九十|0-9][一二三四五六七八九十|0-9]部分',txt) series_part<-txt[series_part_index] writeLines(series_part, 'seriesPart.txt')
7)其他
其他的系列词也按照前面相似的方法处理,不一一列举
对于冒号,先保留着 ,到时候再处理
6. 去掉系列词后,关键在于title相似度的匹配
第一个想法是 求两个title的最长公子串, 但有一些例外, 比如 荒野求生与荒野求爱, 罪爱与罪爱你 等
最长公子串的问题是会把关键词打散,破坏词义信息
因此,我想先对中文title进行分词(分词工具暂定为lucene), 分好的词 计算他们的TF-IDF, 然后用VSM或者simhash计算他们之间的相似度
7.设计分类器
光是计算相似度还不够,比如
海贼王15周年纪念特别篇——幻之篇章「3D2Y 跨越艾斯之死!与路飞伙伴的誓言」与 海贼王 他们的关键词差很大, 造成相似度降低
对于这种情况,我想训练一个分类器来辅助判断,类别为同系列1,不同系列-1(注意没有重名),利用导演、演员信息作为特征,判断两部电影是否属于同一系列,如果分类器认为属于同一系列,则对两个title取交集(最长公子串) 得到公共部分,并认为公共部分是系列名。
比较过程如下:
1.直接比较名字,如果相同就认为是重名,否则转到2
2. 根据正则表达式去掉系列词, 再用分类器进行判断,如果返回1则认为是同系列,如果返回-1则是不同系列。
分类器的设计有以下难点:
1.标号的产生。 这个问题没有给我们标号,因此需要人工进行标定,这一部分工作量比较大
2.特征的设计。 目前想用相似度、 导演是否相同、 演员匹配数 作为特征, 但感觉这些特征略显粗糙。
3.正负样本比例的确定。
此外,我还想了一个基于自训练的半监督学习算法来辅助人工标定数据,其过程如下:
输入: 人工产生的训练集T
1)用T训练一个分类器
2)再对剩余的样本进行预测,选出其中confidence最高的一部分样本,加入训练集T得到新训练集T',并令T=T'
3)是否将所有样本加入训练集,如果是则输出结果;如果不是则返回1)
这里可以进行一个加速, 前面已经对所有的title按照字典顺序排好序了,那么只要比较前后的title就可以了。这样省掉了大量没用的pair,加快了训练速度。