Hiroki

大部分笔记已经转移到 https://github.com/hschen0712/machine_learning_notes ,QQ:357033150, 欢迎交流

任务1 相关节目识别

1.在mysql中对t_movie_douban的title进行排序,注意去掉NULL

drop table t_sorted_title;
create table t_sorted_title as select title from t_movie_douban where title is not null order by convert(title using gbk);
注意判断null的方式是is null 或者is not null
 
2. 将排好序的title结果导出到txt文件
select * from t_sorted_title into outfile 'E:/chs/data/movie_title_sorted.txt' ;
 
3. 观察数据分析能够代表系列的词
 
代表系列的词:
xxx之xxx,第x季,最终章,序章,第x章,后章,前章,续章, 剧场版,(美版),冒号(冒号前的首字符串末尾的系列号),第x集,OVA,OAD,花漾季,第x部分,序曲,I,II,III,特别篇,Season,数字 ,第xx话,第x夜,第x部,第x卷,第x幕,第x期,外传 ,别传,新版, 高清版,特别篇等
 
4.判断书写系统
1)中文书写系统(含日文、韩文)
2)拉丁文书写系统(英文,俄文)
3)中英文混合(认为是中文)
 
5. 简单系列词的处理
我们先从比较容易识别的情况开始,先把简单的情况解决了,再解决棘手的。
简单的情况:第x季,xx之xxx,OVA(注意要大写,否则会跟某些英文title匹配,造成误判)
1)先从OVA开始
以下R语言代码查找所有含有OVA的title,并写入seriesOVA.txt文件
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,加快了训练速度。

posted on 2015-10-24 19:51  Hiroki  阅读(197)  评论(0编辑  收藏  举报

导航