#coding=utf8#公共方法
classCommonM:#@classmethod
@staticmethoddefpreprocess_title(title):'''字符串特殊字符处理'''title=title.lower()
title= title.replace(',', ' ')
title= title.replace("'", '')
title= title.replace('&', 'and')
title= title.replace('?', '')
title= title.decode('utf-8', 'ignore')returntitle.strip()#############################################################coding=utf8#数据获取
#Importing urlib
importurllibimportosimportgzipclassacquireData:'''该类主要是获取各种类型的文件'''
def __init__(self):pass
defdown_csv_data(self):'''获取csv文件'''
#Creating the data folder
if not os.path.exists('./data'):
os.makedirs('./data')#Obtaining the dataset using the url that hosts it
kaggle_url = 'https://github.com/sundeepblue/movie_rating_prediction/raw/master/movie_metadata.csv'
if not os.path.exists('./data/kaggle_dataset.csv'): #avoid downloading if the file exists
response = urllib.urlretrieve(kaggle_url, './data/kaggle_dataset.csv')
imdb_url= 'https://anaconda.org/BigGorilla/datasets/1/download/imdb_dataset.csv'
if not os.path.exists('./data/imdb_dataset.csv'): #avoid downloading if the file exists
response = urllib.urlretrieve(imdb_url, './data/imdb_dataset.csv')defget_gz_data(self):'''获取gz数据
IMDB Plain Text Data(参见此处)是一系列文件,其中每个文件描述电影的一个或多个属性。我们将重点关注电影属性的子集,它表示我们仅对以下所列文件中的数个文件感兴趣:
genres.list.gz
ratings.list.gz
** 注意: 上述文件的总大小约为30M。 运行以下代码可能需要几分钟时间。'''
#Obtaining IMDB's text files
imdb_url_prefix = 'ftp://ftp.funet.fi/pub/mirrors/ftp.imdb.com/pub/'imdb_files_list= ['genres.list.gz', 'ratings.list.gz']#imdb_files_list = ['genres.list.gz']
for name inimdb_files_list:if not os.path.exists('./data/' +name):
response= urllib.urlretrieve(imdb_url_prefix + name, './data/' +name)
urllib.urlcleanup()#urllib fails to download two files from a ftp source. This fixes the bug!
with gzip.open('./data/' + name) as comp_file, open('./data/' + name[:-3], 'w') as reg_file:
file_content=comp_file.read()
reg_file.write(file_content)#obj = acquireData()#obj.down_csv_data()###################################################################################################
#coding=utf8#数据匹配和合并
importosimportdatetimeimporttimeimportreimportcsvimportpandas as pdfrom os importwalkimporturllibimportpy_stringsimjoin as ssjimportpy_stringmatching as smfrom pandas.core.frame importDataFramefrom extract_clean importextract_clean_dataimportpy_entitymatching as emimportLogFileclassmatch_merge_data:def __init__(self):pass
def WriteToCsv(self, titls, data,filename='./data/finalResult-Magellan.csv'):#csvfile = os.path.join(os.getcwd(), 'csvtest.csv')
with open(filename, 'wb') as f:
writer=csv.writer(f)#标题
writer.writerow(titls)for item indata:#内容
writer.writerow(item)defmatch_merge_list(self):'''数据匹配合并'''obj=extract_clean_data()
genreslist=obj.extract_genreslist()
ratinglist=obj.extract_ratinglist()printratinglist.shape[0]printgenreslist.shape[0]
brief_imdb_data= pd.merge(ratinglist, genreslist, how='inner', on=['norm_movie', 'year'])
brief_imdb_data.head()printbrief_imdb_data.shape[0]defmatch_merge_Kaggle_IMDB(self):'''数据匹配合并'''obj=extract_clean_data()
kaggle_data=obj.extract_kaggle_dataset()
imdb_data=obj.extract_imdb_dataset()#print kaggle_data.shape[0] #4919
#print imdb_data.shape[0] #869178
#方法1
data_attempt1 = pd.merge(imdb_data, kaggle_data, how='inner', left_on=['norm_title', 'norm_year'],
right_on=['norm_movie_title', 'norm_title_year'])#print data_attempt1.shape[0] #4261
data_attempt1.to_csv('./data/finalResult-IMDB.csv')defmatch_merge_Kaggle_IMDB_stringsimjoin(self):'''数据匹配合并'''obj=extract_clean_data()
kaggle_data=obj.extract_kaggle_dataset()
imdb_data=obj.extract_imdb_dataset()#方法2
imdb_data['id'] =range(imdb_data.shape[0])
kaggle_data['id'] =range(kaggle_data.shape[0])#使用编辑距离度量来连接两个表。从左表和右表找到元组,使编辑连接属性之间的距离满足输入条件阈
#。 例如,如果比较运算符是'<=',则找到元组对,其编码距离是字符串之间的值连接属性小于或等于输入阈值,as在“阈值”中指定。
similar_titles = ssj.edit_distance_join(imdb_data, kaggle_data, 'id', 'id', 'norm_title','norm_movie_title', l_out_attrs=['title','norm_title', 'norm_year'],
r_out_attrs=['movie_title','norm_movie_title', 'norm_title_year'], threshold=1)#selecting the entries that have the same production year
data_attempt2 = similar_titles[similar_titles.r_norm_title_year ==similar_titles.l_norm_year]
data_attempt2.to_csv('./data/finalResult-stringsimjoin.csv')#data_attempt2.to_csv('./data/finalResult-stringsimjoin.csv', encoding='utf-8')
#print data_attempt2.shape[0]#4696
#print data_attempt3.shape[0] # 10525
defmatch_merge_Kaggle_IMDB_Magellan(self):#print str(datetime.datetime.now())[0:19]
'''数据匹配合并'''obj=extract_clean_data()
kaggle_data=obj.extract_kaggle_dataset()
imdb_data=obj.extract_imdb_dataset()
imdb_data['id'] =range(imdb_data.shape[0])
kaggle_data['id'] =range(kaggle_data.shape[0])#方法3
#子步骤A: 寻找一个候选集(拦截)
#repeating the same thing for the Kaggle dataset
ssj.dataframe_column_to_str(kaggle_data, 'budget', inplace=True)
kaggle_data['mixture'] = kaggle_data['norm_movie_title'] + ' ' + kaggle_data['norm_title_year'] + kaggle_data['budget']#transforming the "budget" column into string and creating a new **mixture** column
ssj.dataframe_column_to_str(imdb_data, 'budget', inplace=True)
imdb_data['mixture'] = imdb_data['norm_title'] + ' ' + imdb_data['norm_year'] + ' ' + imdb_data['budget']#使用重叠系数连接两个表。
C = ssj.overlap_coefficient_join(kaggle_data, imdb_data, 'id', 'id', 'mixture', 'mixture',
sm.WhitespaceTokenizer(),
l_out_attrs=['movie_title','norm_movie_title', 'norm_title_year', 'duration','budget', 'content_rating'],
r_out_attrs=['title','norm_title', 'norm_year', 'length', 'budget', 'mpaa'],
threshold=0.65)#C.shape()
rowCount = C.shape[0] #34
#print C.shape[0]
#子步骤B: 指定要素
em.set_key(kaggle_data, 'id') #specifying the key column in the kaggle dataset
em.set_key(imdb_data, 'id') #specifying the key column in the imdb dataset
em.set_key(C, '_id') #specifying the key in the candidate set
em.set_ltable(C, kaggle_data) #specifying the left table
em.set_rtable(C, imdb_data) #specifying the right table
em.set_fk_rtable(C, 'r_id') #specifying the column that matches the key in the right table
em.set_fk_ltable(C, 'l_id')#子步骤C: 拦截工具故障排除
C[['l_norm_movie_title', 'r_norm_title', 'l_norm_title_year', 'r_norm_year','l_budget', 'r_budget', 'l_content_rating', 'r_mpaa']].head()#子步骤D: 从候选集采样,label列
#samplelen = rowCount
sampled = C.sample(rowCount, random_state=0)#增加label列
#为了标记抽样的数据,我们可以在.csv文件中创建一个新的列(我们称之为label);
#如果配对是正确的匹配,则在此栏中填入数值1,否则,填入数值0。为避免文件重叠,让我们将新文件重命名为labeled.csv。
list =[]for index inxrange(len(sampled.values)):
tem=float(sampled.values[index][13])if tem>0.6:
list.append(1)else:
list.append(0)
sampled['label'] =list#把采样数据保存到sampled.csv文件里面
#sampled.to_csv('./data/sampled.csv', encoding='utf-8')
sampled.to_csv('./data/sampled.csv')#If you would like to avoid labeling the pairs for now, you can download the labled.csv file from
#BigGorilla using the following command (if you prefer to do it yourself, command the next line)
#response = urllib.urlretrieve('https://anaconda.org/BigGorilla/datasets/1/download/labeled.csv',
#'./data/labeled.csv')
labeled = em.read_csv_metadata('data/labeled.csv', ltable=kaggle_data, rtable=imdb_data,
fk_ltable='l_id', fk_rtable='r_id', key='_id')#tt = labeled.head()
#子步骤E: 机器学习算法训练
#现在我们可以使用抽样的数据集,针对我们的预测任务进行各种机器学习算法训练。
#为此,我们需要将我们的数据集分割为训练和测试集,然后为我们的预测任务选择所需的机器学习方法。
split = em.split_train_test(labeled, train_proportion=0.5, random_state=0)
train_data= split['train']
test_data= split['test']
dt= em.DTMatcher(name='DecisionTree', random_state=0)
svm= em.SVMMatcher(name='SVM', random_state=0)
rf= em.RFMatcher(name='RF', random_state=0)
lg= em.LogRegMatcher(name='LogReg', random_state=0)
ln= em.LinRegMatcher(name='LinReg')
nb= em.NBMatcher(name='NaiveBayes')#在应用任何机器学习方法之前,我们需要抽取一组功能。幸运地是,一旦我们指定两个数据集中的哪些列相互对应,
#py_entitymatching程序包就可以自动抽取一组功能。指定两个数据集的列之间的对应性,
#将启动以下代码片段。然后,它使用py_entitymatching程序包确定各列的类型。
#通过考虑(变量l_attr_types和r_attr_types中存储的)各个数据集中列的类型,
#并使用软件包推荐的编译器和类似功能,我们可以抽取一组用于抽取功能的说明。
#请注意,变量F并非所抽取功能的集合,相反,它会对说明编码以处理功能。
attr_corres =em.get_attr_corres(kaggle_data, imdb_data)
attr_corres['corres'] = [('norm_movie_title', 'norm_title'),
('norm_title_year', 'norm_year'),
('content_rating', 'mpaa'),
('budget', 'budget'),
]
l_attr_types=em.get_attr_types(kaggle_data)
r_attr_types=em.get_attr_types(imdb_data)
tok=em.get_tokenizers_for_matching()
sim=em.get_sim_funs_for_matching()
F=em.get_features(kaggle_data, imdb_data, l_attr_types, r_attr_types, attr_corres, tok, sim)#考虑所需功能的集合F,现在我们可以计算训练数据的功能值,并找出我们数据中丢失数值的原因。
#在这种情况下,我们选择将丢失值替换为列的平均值。
train_features= em.extract_feature_vecs(train_data, feature_table=F, attrs_after='label', show_progress=False)
train_features= em.impute_table(train_features, exclude_attrs=['_id', 'l_id', 'r_id', 'label'],
strategy='mean')#使用计算的功能,我们可以评估不同机器学习算法的性能,并为我们的匹配任务选择最佳的算法
result= em.select_matcher([ ln, lg,svm,nb,rf, dt], table=train_features,
exclude_attrs=['_id', 'l_id', 'r_id', 'label'], k=5,
target_attr='label', metric='f1', random_state=0)print result['cv_stats']#子步骤F: 评估我们的匹配质量
best_model= result['selected_matcher']
best_model.fit(table=train_features, exclude_attrs=['_id', 'l_id', 'r_id', 'label'], target_attr='label')
test_features= em.extract_feature_vecs(test_data, feature_table=F, attrs_after='label', show_progress=False)
test_features= em.impute_table(test_features, exclude_attrs=['_id', 'l_id', 'r_id', 'label'], strategy='mean')#Predict on the test data
predictions = best_model.predict(table=test_features, exclude_attrs=['_id', 'l_id', 'r_id', 'label'],
append=True, target_attr='predicted', inplace=False)#Evaluate the predictions
eval_result = em.eval_matches(predictions, 'label', 'predicted')
em.print_eval_summary(eval_result)#子步骤G: 使用训练的模型匹配数据集
#现在,我们可以使用训练的模型对两个标记进行如下匹配:
candset_features= em.extract_feature_vecs(C, feature_table=F, show_progress=True)
candset_features= em.impute_table(candset_features, exclude_attrs=['_id', 'l_id', 'r_id'], strategy='mean')
predictions= best_model.predict(table=candset_features, exclude_attrs=['_id', 'l_id', 'r_id'],
append=True, target_attr='predicted', inplace=False)
matches= predictions[predictions.predicted == 1]#请注意,匹配数据帧包含了很多存储数据集抽取功能的列。以下代码片段移除了所有非必要的列,并创建一个格式良好的拥有最终形成的整合数据集的数据帧。
from py_entitymatching.catalog importcatalog_manager as cm
matches= matches[['_id', 'l_id', 'r_id', 'predicted']]
matches.reset_index(drop=True, inplace=True)
cm.set_candset_properties(matches,'_id', 'l_id', 'r_id', kaggle_data, imdb_data)
matches= em.add_output_attributes(matches, l_output_attrs=['movie_title','norm_movie_title', 'norm_title_year', 'budget','content_rating'],
r_output_attrs=['title','norm_title', 'norm_year', 'budget', 'mpaa'],
l_output_prefix='l_', r_output_prefix='r_',
delete_from_catalog=False)
matches.drop('predicted', axis=1, inplace=True)
matches.head()#matches.to_csv('./data/finalResult-Magellan.csv', encoding='utf-8')
#matches.to_csv('./data/finalResult-Magellan.csv')
titls=[]for col inmatches.columns:
titls.append(col)
self.WriteToCsv(titls,matches.values)#print str(datetime.datetime.now())[0:19]
defmatch_merge_softad(self):'''数据匹配合并'''left_Candidate_set= ['channel_name1', 'programe_name1', 'brand_name1']
right_Candidate_set= ['channel_name2', 'programe_name2', 'brand_name2']
obj=extract_clean_data()
leftcsvfile= './data/20170708.csv'soft_data=obj.get_date_fromCSV(leftcsvfile)
dir= os.path.join(os.getcwd(), 'data\softAD-1701-1706')
flist=[]
dir= unicode(dir, 'utf8')for (dirpath, dirnames, filenames) inwalk(dir):
flist.extend(filenames)break
for fileName inflist:if fileName.find('finalResult') == -1:
rightcsvfile= str('./data/softAD-1701-1706/') + fileName.encode('utf8')
monitor_soft_data=obj.get_date_fromCSV(rightcsvfile)
monitor_soft_data= monitor_soft_data.drop_duplicates(subset=right_Candidate_set, keep='first').copy()
monitor_soft_data.head()
data_attempt1= pd.merge(soft_data, monitor_soft_data, how='inner', left_on=left_Candidate_set,
right_on=right_Candidate_set)
fp=os.path.basename(rightcsvfile)
filename= './data/softAD-1701-1706/fmerge_softad-' + fp[0:fp.rindex('.')] + '.csv'filename= unicode(filename, 'utf8')
data_attempt1.to_csv(filename)defmatch_softad_Magellan(self):
obj=extract_clean_data()
logfile= os.path.join(os.getcwd(), 'log\\' + time.strftime('%Y-%m-%d') + '.txt')
log=LogFile.LogFile(logfile)#加载串播单数据
leftcsvfile = './data/softAD-1701-1706/20170706.csv'soft_data=obj.get_date_fromCSV(leftcsvfile)
log.WriteLog('\r\n')
log.WriteLog('加载串播单数据:%s' %os.path.basename(leftcsvfile))print ('加载串播单数据:%s' %os.path.basename(leftcsvfile))
dir= os.path.join(os.getcwd(), 'data\softAD-1701-1706')
flist=[]
dir= unicode(dir, 'utf8')for (dirpath, dirnames, filenames) inwalk(dir):
flist.extend(filenames)break
for fileName inflist:if fileName.find('finalResult')==-1:
fn= str('./data/softAD-1701-1706/') + fileName.encode('utf8')
self.match_softad_data(soft_data,log,leftcsvfile='./data/20170708.csv',rightcsvfile=fn)defmatch_softad_data(self,soft_data,log,leftcsvfile,rightcsvfile,
left_Candidate_set=['channel_name1', 'programe_name1', 'brand_name1'],
right_Candidate_set=['channel_name2', 'programe_name2', 'brand_name2'],
attr_corres_columns=[('channel_name1', 'channel_name2'),('programe_name1', 'programe_name2'),('brand_name1', 'brand_name2'),],
csvtitls=['_id', 'l_id', 'r_id', '频道名称', '整理节目全称-广告项目', '整理品牌', '频道', '节目名称', '品牌']):'''leftcsvfile='./data/20170708.csv'
rightcsvfile='./data/串播单-T-中央台D006-中央1套(综合)170101-170630-更新1.csv'
left_Candidate_set=['channel_name1', 'programe_name1', 'brand_name1']
right_Candidate_set=['channel_name2', 'programe_name2', 'brand_name2']
attr_corres_columns=[('channel_name1', 'channel_name2'),('programe_name1', 'programe_name2'),('brand_name1', 'brand_name2'),]
:param log: log日志
:param leftcsvfile:
:param rightcsvfile:
:param left_Candidate_set:
:param right_Candidate_set:
:param attr_corres_columns:
:return:'''obj=extract_clean_data()## logfile = os.path.join(os.getcwd(), 'log\\' + time.strftime('%Y-%m-%d') + '.txt')
## log = LogFile.LogFile(logfile)
## 1、获取数据
## 软广数据
#soft_data = obj.get_date_fromCSV(leftcsvfile)
#log.WriteLog('\r\n')
#log.WriteLog('加载串播单数据:%s'%os.path.basename(leftcsvfile))
log.WriteLog('\r\n')#软广告监测报告数据
monitor_soft_data=obj.get_date_fromCSV(rightcsvfile)
log.WriteLog('加载软广告监测报告数据:%s' %os.path.basename(rightcsvfile))print ('加载软广告监测报告数据:%s' %os.path.basename(rightcsvfile))#去重复数据
#soft_data = soft_data.drop_duplicates(subset=left_Candidate_set, keep='first').copy()
#soft_data.head()
#去重复数据
monitor_soft_data = monitor_soft_data.drop_duplicates(subset=right_Candidate_set, keep='first').copy()
monitor_soft_data.head()
soft_data['id'] =range(soft_data.shape[0])
monitor_soft_data['id'] =range(monitor_soft_data.shape[0])#2、寻找一个候选集(拦截)
lstlen =len(left_Candidate_set)
temp= ''
for i in xrange(lstlen-1):
temp+= soft_data[left_Candidate_set[i]] + ' 'soft_data['mixture'] = temp+soft_data[left_Candidate_set[lstlen - 1]]
lstlen=len(right_Candidate_set)
temp= ''
for i in xrange(lstlen-1):
temp+= monitor_soft_data[right_Candidate_set[i]] + ' 'monitor_soft_data['mixture'] = temp + monitor_soft_data[right_Candidate_set[lstlen - 1]]#使用重叠系数连接两个表。
C = ssj.overlap_coefficient_join(soft_data, monitor_soft_data, 'id', 'id', 'mixture', 'mixture',
sm.WhitespaceTokenizer(),
l_out_attrs=left_Candidate_set,
r_out_attrs=right_Candidate_set,
threshold=0.65)
log.WriteLog('正在寻找一个候选集')print ('正在寻找一个候选集')
rowCount=C.shape[0]if rowCount <= 5:
log.WriteLog('文件%s没有匹配项' %os.path.basename(rightcsvfile))print ('文件%s没有匹配项' %os.path.basename(rightcsvfile))return
#3、 指定要素
em.set_key(soft_data, 'id') #specifying the key column in the kaggle dataset
em.set_key(monitor_soft_data, 'id') #specifying the key column in the imdb dataset
em.set_key(C, '_id') #specifying the key in the candidate set
em.set_ltable(C, soft_data) #specifying the left table
em.set_rtable(C, monitor_soft_data) #specifying the right table
em.set_fk_rtable(C, 'r_id') #specifying the column that matches the key in the right table
em.set_fk_ltable(C, 'l_id')
log.WriteLog('正在指定要素')print ('正在指定要素')#4: 拦截工具故障排除
l_list = ['l_'+ item for item inleft_Candidate_set]
r_list= ['r_' + item for item inright_Candidate_set]
l_list.extend(r_list)
C[l_list].head()#C[['l_channel_name1', 'r_channel_name2', 'l_programe_name1', 'r_programe_name2',
#'l_brand_name1', 'r_brand_name2']].head()
log.WriteLog('正在拦截工具故障排除')print ('正在拦截工具故障排除')#5: 从候选集采样
#rowCount = 500
colmunCount = C.shape[1]
sampled= C.sample(rowCount, random_state=0)#增加label列
#为了标记抽样的数据,我们可以在.csv文件中创建一个新的列(我们称之为label);
#如果配对是正确的匹配,则在此栏中填入数值1,否则,填入数值0。为避免文件重叠,让我们将新文件重命名为labeled.csv。
list =[]for item insampled.values:
tem= float(item[colmunCount-1])if tem > 0.6:
list.append(1)else:
list.append(0)
sampled['label'] =list#把采样数据保存到sampled.csv文件里面
#sampled.to_csv('./data/sampled.csv', encoding='utf-8')
sampled.to_csv('./data/labeled.csv')
labeled= em.read_csv_metadata('data/labeled.csv', ltable=soft_data, rtable=monitor_soft_data,
fk_ltable='l_id', fk_rtable='r_id', key='_id')
log.WriteLog('正在从候选集采样')print ('正在从候选集采样')#6: 机器学习算法训练
#现在我们可以使用抽样的数据集,针对我们的预测任务进行各种机器学习算法训练。
#为此,我们需要将我们的数据集分割为训练和测试集,然后为我们的预测任务选择所需的机器学习方法。
log.WriteLog('正在进行机器学习算法训练')print ('正在进行机器学习算法训练')
split= em.split_train_test(labeled, train_proportion=0.5, random_state=0)
train_data= split['train']
test_data= split['test']
dt= em.DTMatcher(name='DecisionTree', random_state=0)
svm= em.SVMMatcher(name='SVM', random_state=0)
rf= em.RFMatcher(name='RF', random_state=0)
lg= em.LogRegMatcher(name='LogReg', random_state=0)
ln= em.LinRegMatcher(name='LinReg')
nb= em.NBMatcher(name='NaiveBayes')#在应用任何机器学习方法之前,我们需要抽取一组功能。幸运地是,一旦我们指定两个数据集中的哪些列相互对应,
#py_entitymatching程序包就可以自动抽取一组功能。指定两个数据集的列之间的对应性,
#将启动以下代码片段。然后,它使用py_entitymatching程序包确定各列的类型。
#通过考虑(变量l_attr_types和r_attr_types中存储的)各个数据集中列的类型,
#并使用软件包推荐的编译器和类似功能,我们可以抽取一组用于抽取功能的说明。
#请注意,变量F并非所抽取功能的集合,相反,它会对说明编码以处理功能。
attr_corres =em.get_attr_corres(soft_data, monitor_soft_data)
attr_corres['corres'] =attr_corres_columns
l_attr_types=em.get_attr_types(soft_data)
r_attr_types=em.get_attr_types(monitor_soft_data)
tok=em.get_tokenizers_for_matching()
sim=em.get_sim_funs_for_matching()
F=em.get_features(soft_data, monitor_soft_data, l_attr_types, r_attr_types, attr_corres, tok, sim)#考虑所需功能的集合F,现在我们可以计算训练数据的功能值,并找出我们数据中丢失数值的原因。
#在这种情况下,我们选择将丢失值替换为列的平均值。
train_features= em.extract_feature_vecs(train_data, feature_table=F, attrs_after='label', show_progress=False)
train_features= em.impute_table(train_features, exclude_attrs=['_id', 'l_id', 'r_id', 'label'],
strategy='mean')#使用计算的功能,我们可以评估不同机器学习算法的性能,并为我们的匹配任务选择最佳的算法
#result = em.select_matcher([ln, lg, svm, nb, rf, dt], table=train_features,
#exclude_attrs=['_id', 'l_id', 'r_id', 'label'], k=5,
#target_attr='label', metric='f1', random_state=0)
result = em.select_matcher([ln, nb, rf, dt], table=train_features,
exclude_attrs=['_id', 'l_id', 'r_id', 'label'], k=5,
target_attr='label', metric='f1', random_state=0)print result['cv_stats']#7: 评估我们的匹配质量
log.WriteLog('正在进行评估匹配质量')print ('正在进行评估匹配质量')
best_model= result['selected_matcher']
best_model.fit(table=train_features, exclude_attrs=['_id', 'l_id', 'r_id', 'label'], target_attr='label')
test_features= em.extract_feature_vecs(test_data, feature_table=F, attrs_after='label', show_progress=False)
test_features= em.impute_table(test_features, exclude_attrs=['_id', 'l_id', 'r_id', 'label'], strategy='mean')#Predict on the test data
predictions = best_model.predict(table=test_features, exclude_attrs=['_id', 'l_id', 'r_id', 'label'],
append=True, target_attr='predicted', inplace=False)#Evaluate the predictions
eval_result = em.eval_matches(predictions, 'label', 'predicted')
em.print_eval_summary(eval_result)#8: 使用训练的模型匹配数据集
#现在,我们可以使用训练的模型对两个标记进行如下匹配:
log.WriteLog('正在进行用训练的模型匹配数据集')print ('正在进行用训练的模型匹配数据集')
candset_features= em.extract_feature_vecs(C, feature_table=F, show_progress=True)
candset_features= em.impute_table(candset_features, exclude_attrs=['_id', 'l_id', 'r_id'], strategy='mean')
predictions= best_model.predict(table=candset_features, exclude_attrs=['_id', 'l_id', 'r_id'],
append=True, target_attr='predicted', inplace=False)
matches= predictions[predictions.predicted == 1]#请注意,匹配数据帧包含了很多存储数据集抽取功能的列。以下代码片段移除了所有非必要的列,并创建一个格式良好的拥有最终形成的整合数据集的数据帧。
from py_entitymatching.catalog importcatalog_manager as cm
matches= matches[['_id', 'l_id', 'r_id', 'predicted']]
matches.reset_index(drop=True, inplace=True)
cm.set_candset_properties(matches,'_id', 'l_id', 'r_id', soft_data, monitor_soft_data)
matches=em.add_output_attributes(matches,
l_output_attrs=left_Candidate_set,
r_output_attrs=right_Candidate_set,
l_output_prefix='l_', r_output_prefix='r_',
delete_from_catalog=False)
matches.drop('predicted', axis=1, inplace=True)
matches.head()#matches.to_csv('./data/finalResult-Magellan.csv', encoding='utf-8')
#matches.to_csv('./data/finalResult-Magellan.csv')
#titls = []
#for col in matches.columns:
#titls.append(col)
csvtitls=['_id','l_id','r_id','频道名称','整理节目全称-广告项目','整理品牌','频道','节目名称','品牌']
log.WriteLog('把匹配的最终数据导出到csv文件')print ('把匹配的最终数据导出到csv文件')
fp=os.path.basename(rightcsvfile)
filename= './data/softAD-1701-1706/finalResult-'+fp[0:fp.rindex('.')] + '.csv'filename= unicode(filename,'utf8')
self.WriteToCsv(csvtitls, matches.values,filename)return
#obj = match_merge_data()#obj.match_merge_Kaggle_IMDB()#obj.match_merge_Kaggle_IMDB_stringsimjoin()#obj.match_merge_Kaggle_IMDB_Magellan()#obj.match_softad_Magellan()#obj.match_merge_softad()
##########################################################################################
#coding=utf8#数据匹配和合并
importosimportdatetimeimporttimeimportreimportcsvimportpandas as pdfrom os importwalkimporturllibimportpy_stringsimjoin as ssjimportpy_stringmatching as smfrom pandas.core.frame importDataFramefrom extract_clean importextract_clean_dataimportpy_entitymatching as emimportLogFileclassmatch_merge_data:def __init__(self):pass
def WriteToCsv(self, titls, data,filename='./data/finalResult-Magellan.csv'):#csvfile = os.path.join(os.getcwd(), 'csvtest.csv')
with open(filename, 'wb') as f:
writer=csv.writer(f)#标题
writer.writerow(titls)for item indata:#内容
writer.writerow(item)defmatch_merge_list(self):'''数据匹配合并'''obj=extract_clean_data()
genreslist=obj.extract_genreslist()
ratinglist=obj.extract_ratinglist()printratinglist.shape[0]printgenreslist.shape[0]
brief_imdb_data= pd.merge(ratinglist, genreslist, how='inner', on=['norm_movie', 'year'])
brief_imdb_data.head()printbrief_imdb_data.shape[0]defmatch_merge_Kaggle_IMDB(self):'''数据匹配合并'''obj=extract_clean_data()
kaggle_data=obj.extract_kaggle_dataset()
imdb_data=obj.extract_imdb_dataset()#print kaggle_data.shape[0] #4919
#print imdb_data.shape[0] #869178
#方法1
data_attempt1 = pd.merge(imdb_data, kaggle_data, how='inner', left_on=['norm_title', 'norm_year'],
right_on=['norm_movie_title', 'norm_title_year'])#print data_attempt1.shape[0] #4261
data_attempt1.to_csv('./data/finalResult-IMDB.csv')defmatch_merge_Kaggle_IMDB_stringsimjoin(self):'''数据匹配合并'''obj=extract_clean_data()
kaggle_data=obj.extract_kaggle_dataset()
imdb_data=obj.extract_imdb_dataset()#方法2
imdb_data['id'] =range(imdb_data.shape[0])
kaggle_data['id'] =range(kaggle_data.shape[0])#使用编辑距离度量来连接两个表。从左表和右表找到元组,使编辑连接属性之间的距离满足输入条件阈
#。 例如,如果比较运算符是'<=',则找到元组对,其编码距离是字符串之间的值连接属性小于或等于输入阈值,as在“阈值”中指定。
similar_titles = ssj.edit_distance_join(imdb_data, kaggle_data, 'id', 'id', 'norm_title','norm_movie_title', l_out_attrs=['title','norm_title', 'norm_year'],
r_out_attrs=['movie_title','norm_movie_title', 'norm_title_year'], threshold=1)#selecting the entries that have the same production year
data_attempt2 = similar_titles[similar_titles.r_norm_title_year ==similar_titles.l_norm_year]
data_attempt2.to_csv('./data/finalResult-stringsimjoin.csv')#data_attempt2.to_csv('./data/finalResult-stringsimjoin.csv', encoding='utf-8')
#print data_attempt2.shape[0]#4696
#print data_attempt3.shape[0] # 10525
defmatch_merge_Kaggle_IMDB_Magellan(self):#print str(datetime.datetime.now())[0:19]
'''数据匹配合并'''obj=extract_clean_data()
kaggle_data=obj.extract_kaggle_dataset()
imdb_data=obj.extract_imdb_dataset()
imdb_data['id'] =range(imdb_data.shape[0])
kaggle_data['id'] =range(kaggle_data.shape[0])#方法3
#子步骤A: 寻找一个候选集(拦截)
#repeating the same thing for the Kaggle dataset
ssj.dataframe_column_to_str(kaggle_data, 'budget', inplace=True)
kaggle_data['mixture'] = kaggle_data['norm_movie_title'] + ' ' + kaggle_data['norm_title_year'] + kaggle_data['budget']#transforming the "budget" column into string and creating a new **mixture** column
ssj.dataframe_column_to_str(imdb_data, 'budget', inplace=True)
imdb_data['mixture'] = imdb_data['norm_title'] + ' ' + imdb_data['norm_year'] + ' ' + imdb_data['budget']#使用重叠系数连接两个表。
C = ssj.overlap_coefficient_join(kaggle_data, imdb_data, 'id', 'id', 'mixture', 'mixture',
sm.WhitespaceTokenizer(),
l_out_attrs=['movie_title','norm_movie_title', 'norm_title_year', 'duration','budget', 'content_rating'],
r_out_attrs=['title','norm_title', 'norm_year', 'length', 'budget', 'mpaa'],
threshold=0.65)#C.shape()
rowCount = C.shape[0] #34
#print C.shape[0]
#子步骤B: 指定要素
em.set_key(kaggle_data, 'id') #specifying the key column in the kaggle dataset
em.set_key(imdb_data, 'id') #specifying the key column in the imdb dataset
em.set_key(C, '_id') #specifying the key in the candidate set
em.set_ltable(C, kaggle_data) #specifying the left table
em.set_rtable(C, imdb_data) #specifying the right table
em.set_fk_rtable(C, 'r_id') #specifying the column that matches the key in the right table
em.set_fk_ltable(C, 'l_id')#子步骤C: 拦截工具故障排除
C[['l_norm_movie_title', 'r_norm_title', 'l_norm_title_year', 'r_norm_year','l_budget', 'r_budget', 'l_content_rating', 'r_mpaa']].head()#子步骤D: 从候选集采样,label列
#samplelen = rowCount
sampled = C.sample(rowCount, random_state=0)#增加label列
#为了标记抽样的数据,我们可以在.csv文件中创建一个新的列(我们称之为label);
#如果配对是正确的匹配,则在此栏中填入数值1,否则,填入数值0。为避免文件重叠,让我们将新文件重命名为labeled.csv。
list =[]for index inxrange(len(sampled.values)):
tem=float(sampled.values[index][13])if tem>0.6:
list.append(1)else:
list.append(0)
sampled['label'] =list#把采样数据保存到sampled.csv文件里面
#sampled.to_csv('./data/sampled.csv', encoding='utf-8')
sampled.to_csv('./data/sampled.csv')#If you would like to avoid labeling the pairs for now, you can download the labled.csv file from
#BigGorilla using the following command (if you prefer to do it yourself, command the next line)
#response = urllib.urlretrieve('https://anaconda.org/BigGorilla/datasets/1/download/labeled.csv',
#'./data/labeled.csv')
labeled = em.read_csv_metadata('data/labeled.csv', ltable=kaggle_data, rtable=imdb_data,
fk_ltable='l_id', fk_rtable='r_id', key='_id')#tt = labeled.head()
#子步骤E: 机器学习算法训练
#现在我们可以使用抽样的数据集,针对我们的预测任务进行各种机器学习算法训练。
#为此,我们需要将我们的数据集分割为训练和测试集,然后为我们的预测任务选择所需的机器学习方法。
split = em.split_train_test(labeled, train_proportion=0.5, random_state=0)
train_data= split['train']
test_data= split['test']
dt= em.DTMatcher(name='DecisionTree', random_state=0)
svm= em.SVMMatcher(name='SVM', random_state=0)
rf= em.RFMatcher(name='RF', random_state=0)
lg= em.LogRegMatcher(name='LogReg', random_state=0)
ln= em.LinRegMatcher(name='LinReg')
nb= em.NBMatcher(name='NaiveBayes')#在应用任何机器学习方法之前,我们需要抽取一组功能。幸运地是,一旦我们指定两个数据集中的哪些列相互对应,
#py_entitymatching程序包就可以自动抽取一组功能。指定两个数据集的列之间的对应性,
#将启动以下代码片段。然后,它使用py_entitymatching程序包确定各列的类型。
#通过考虑(变量l_attr_types和r_attr_types中存储的)各个数据集中列的类型,
#并使用软件包推荐的编译器和类似功能,我们可以抽取一组用于抽取功能的说明。
#请注意,变量F并非所抽取功能的集合,相反,它会对说明编码以处理功能。
attr_corres =em.get_attr_corres(kaggle_data, imdb_data)
attr_corres['corres'] = [('norm_movie_title', 'norm_title'),
('norm_title_year', 'norm_year'),
('content_rating', 'mpaa'),
('budget', 'budget'),
]
l_attr_types=em.get_attr_types(kaggle_data)
r_attr_types=em.get_attr_types(imdb_data)
tok=em.get_tokenizers_for_matching()
sim=em.get_sim_funs_for_matching()
F=em.get_features(kaggle_data, imdb_data, l_attr_types, r_attr_types, attr_corres, tok, sim)#考虑所需功能的集合F,现在我们可以计算训练数据的功能值,并找出我们数据中丢失数值的原因。
#在这种情况下,我们选择将丢失值替换为列的平均值。
train_features= em.extract_feature_vecs(train_data, feature_table=F, attrs_after='label', show_progress=False)
train_features= em.impute_table(train_features, exclude_attrs=['_id', 'l_id', 'r_id', 'label'],
strategy='mean')#使用计算的功能,我们可以评估不同机器学习算法的性能,并为我们的匹配任务选择最佳的算法
result= em.select_matcher([ ln, lg,svm,nb,rf, dt], table=train_features,
exclude_attrs=['_id', 'l_id', 'r_id', 'label'], k=5,
target_attr='label', metric='f1', random_state=0)print result['cv_stats']#子步骤F: 评估我们的匹配质量
best_model= result['selected_matcher']
best_model.fit(table=train_features, exclude_attrs=['_id', 'l_id', 'r_id', 'label'], target_attr='label')
test_features= em.extract_feature_vecs(test_data, feature_table=F, attrs_after='label', show_progress=False)
test_features= em.impute_table(test_features, exclude_attrs=['_id', 'l_id', 'r_id', 'label'], strategy='mean')#Predict on the test data
predictions = best_model.predict(table=test_features, exclude_attrs=['_id', 'l_id', 'r_id', 'label'],
append=True, target_attr='predicted', inplace=False)#Evaluate the predictions
eval_result = em.eval_matches(predictions, 'label', 'predicted')
em.print_eval_summary(eval_result)#子步骤G: 使用训练的模型匹配数据集
#现在,我们可以使用训练的模型对两个标记进行如下匹配:
candset_features= em.extract_feature_vecs(C, feature_table=F, show_progress=True)
candset_features= em.impute_table(candset_features, exclude_attrs=['_id', 'l_id', 'r_id'], strategy='mean')
predictions= best_model.predict(table=candset_features, exclude_attrs=['_id', 'l_id', 'r_id'],
append=True, target_attr='predicted', inplace=False)
matches= predictions[predictions.predicted == 1]#请注意,匹配数据帧包含了很多存储数据集抽取功能的列。以下代码片段移除了所有非必要的列,并创建一个格式良好的拥有最终形成的整合数据集的数据帧。
from py_entitymatching.catalog importcatalog_manager as cm
matches= matches[['_id', 'l_id', 'r_id', 'predicted']]
matches.reset_index(drop=True, inplace=True)
cm.set_candset_properties(matches,'_id', 'l_id', 'r_id', kaggle_data, imdb_data)
matches= em.add_output_attributes(matches, l_output_attrs=['movie_title','norm_movie_title', 'norm_title_year', 'budget','content_rating'],
r_output_attrs=['title','norm_title', 'norm_year', 'budget', 'mpaa'],
l_output_prefix='l_', r_output_prefix='r_',
delete_from_catalog=False)
matches.drop('predicted', axis=1, inplace=True)
matches.head()#matches.to_csv('./data/finalResult-Magellan.csv', encoding='utf-8')
#matches.to_csv('./data/finalResult-Magellan.csv')
titls=[]for col inmatches.columns:
titls.append(col)
self.WriteToCsv(titls,matches.values)