参考文档:http://www.biggorilla.org/walkt/

  一、BigGorilla应用主要步骤

    如下图:

    

  二、实例应用

    1、数据获取

      urllib是非常受欢迎的用于在网络上读取数据的Python软件包。在本部分中,我们使用urllib下载本教程所需的数据集。

      “Kaggle 5000 Movie Dataset”下载 所需的数据集是一个.csv文件,拥有以下代码片段中指定的url。

    

  

    2、数据抽取

      “Kaggle 5000 Movie Dataset”存储在.csv文件中,该文件已经完成结构化并且可供使用。另一方面,“IMDB Plain Text Data”是一系列需要进行处理以抽取数据的半结构化文本文件。快速查看每个文件的前几行可以发现,每个文件都有不同的格式,

    并且必须单独加以处理。

    3、数据归档和清理

      在此数据准备阶段中的高级目标就是审视我们目前已经获取和抽取的数据。这样可以帮助我们熟悉数据,了解数据需要以什么方式进行清理或转换,最终让我们为数据整合任务的以下步骤准备数据。

      a、处理重复(清理)

        # 使用简单的重复处理方法,即仅保留第一次出现的重复条目并移除剩余的重复条目

        
      
     b、
文本标准化(清理)
        
        我们将用来整合电影数据集的关键属性是电影片名。因此,对这些片名进行标准化非常重要。以下代码片段使所有电影片名变为小写,然后移除某些字符,例如“’”和“?”,并替换一些其他特殊字符(例如“&”被替换为“and”)。
        
        

        

    4、数据匹配和合并

      使用Magellan进行数据匹配

      a、寻找一个候选集(拦截)

      本步骤的目标是使用简单的启发式规则限制我们认为是潜在匹配的配对数量。对于此任务,我们可以在各个数据集中新建一列,将重要属性的值合并到单个字符串(我们称之为混合)。然后,我们可以像之前一样使用字符串类似项合并,

    寻找重要列的数值有一些重叠的条目组合。在此之前,我们需要将作为混合的一部分的列转换为字符串。使用py_stringsimjoin程序包,我们可以轻松完成这些工作。

      

      现在,我们可以使用混合列创建所需的候选集(我们称之为C)。

      b、指定要素

      下一步就是指定在py_entitymatching程序包中哪些列对应于各个数据帧中的要素。此外,我们需要指定哪些列对应于候选集中两个数据帧中的外部要素。

      

      c、拦截工具故障排除

      

      d、从候选集采样,label列

      

      e、机器学习算法训练

      

       

      

      f、评估匹配质量

      

      g、使用训练的模型匹配数据集

      

          

    三、完整代码

    

#coding=utf8
#公共方法 class CommonM: # @classmethod
@staticmethod
def preprocess_title(title):
'''字符串特殊字符处理'''
title = title.lower()
title = title.replace(',', ' ')
title = title.replace("'", '')
title = title.replace('&', 'and')
title = title.replace('?', '')
title = title.decode('utf-8', 'ignore')
return title.strip() ############################################################
#coding=utf8
#数据获取 # Importing urlib
import urllib
import os
import gzip class acquireData:
'''该类主要是获取各种类型的文件''' def __init__(self):
pass def down_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') def get_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 in imdb_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
#数据匹配和合并 import os
import datetime
import time
import re
import csv
import pandas as pd
from os import walk
import urllib
import py_stringsimjoin as ssj
import py_stringmatching as sm from pandas.core.frame import DataFrame
from extract_clean import extract_clean_data
import py_entitymatching as em
import LogFile class match_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 in data:
# 内容
writer.writerow(item) def match_merge_list(self):
'''数据匹配合并'''
obj = extract_clean_data()
genreslist = obj.extract_genreslist()
ratinglist = obj.extract_ratinglist()
print ratinglist.shape[0]
print genreslist.shape[0]
brief_imdb_data = pd.merge(ratinglist, genreslist, how='inner', on=['norm_movie', 'year'])
brief_imdb_data.head()
print brief_imdb_data.shape[0] def match_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') def match_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 def match_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] #
# 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 in xrange(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 import catalog_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 in matches.columns:
titls.append(col)
self.WriteToCsv(titls,matches.values)
# print str(datetime.datetime.now())[0:19] def match_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) in walk(dir):
flist.extend(filenames)
break
for fileName in flist:
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) def match_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) in walk(dir):
flist.extend(filenames)
break
for fileName in flist:
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) def match_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 in left_Candidate_set]
r_list = ['r_' + item for item in right_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 in sampled.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 import catalog_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
#数据匹配和合并 import os
import datetime
import time
import re
import csv
import pandas as pd
from os import walk
import urllib
import py_stringsimjoin as ssj
import py_stringmatching as sm from pandas.core.frame import DataFrame
from extract_clean import extract_clean_data
import py_entitymatching as em
import LogFile class match_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 in data:
# 内容
writer.writerow(item) def match_merge_list(self):
'''数据匹配合并'''
obj = extract_clean_data()
genreslist = obj.extract_genreslist()
ratinglist = obj.extract_ratinglist()
print ratinglist.shape[0]
print genreslist.shape[0]
brief_imdb_data = pd.merge(ratinglist, genreslist, how='inner', on=['norm_movie', 'year'])
brief_imdb_data.head()
print brief_imdb_data.shape[0] def match_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') def match_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 def match_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] #
# 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 in xrange(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 import catalog_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 in matches.columns:
titls.append(col)
self.WriteToCsv(titls,matches.values)

Python数据整合与数据准备-BigGorilla实例应用的更多相关文章

  1. Python数据整合与数据准备-BigGorilla介绍

    参考文档:http://www.biggorilla.org/zh-hans/walkt/ 一.前言 “根据访谈记录和专家估计,数据科学家将50%至80%的时间花在搜集和准备难以梳理的数字数据的琐碎工 ...

  2. Python数据整合与数据准备-BigGorilla应用

    一.前言 要应用BigGorilla框架对应数据进行数据的处理与匹配,那么首先要下载Anaconda安装,下载地址:https://www.continuum.io/downloads Anacond ...

  3. 用python实现简单EXCEL数据统计的实例

    用python实现简单EXCEL数据统计的实例 下面小编就为大家带来一篇用python实现简单EXCEL数据统计的实例.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧 任 ...

  4. PYTHON爬虫实战_垃圾佬闲鱼爬虫转转爬虫数据整合自用二手急速响应捡垃圾平台_3(附源码持续更新)

    说明 文章首发于HURUWO的博客小站,本平台做同步备份发布. 如有浏览或访问异常图片加载失败或者相关疑问可前往原博客下评论浏览. 原文链接 PYTHON爬虫实战_垃圾佬闲鱼爬虫转转爬虫数据整合自用二 ...

  5. Python数学建模-02.数据导入

    数据导入是所有数模编程的第一步,比你想象的更重要. 先要学会一种未必最佳,但是通用.安全.简单.好学的方法. 『Python 数学建模 @ Youcans』带你从数模小白成为国赛达人. 1. 数据导入 ...

  6. JavaScript 解析 Django Python 生成的 datetime 数据 时区问题解决

    JavaScript 解析 Django/Python 生成的 datetime 数据 当Web后台使用Django时,后台生成的时间数据类型就是Python类型的. 项目需要将几个时间存储到数据库中 ...

  7. 用IBM WebSphere DataStage进行数据整合: 第 1 部分

    转自:http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0602zhoudp/ 引言 传统的数据整合方式需要大量的手工 ...

  8. Python 进程之间共享数据

    最近遇到多进程共享数据的问题,到网上查了有几篇博客写的蛮好的,记录下来方便以后查看. 一.Python multiprocessing 跨进程对象共享  在mp库当中,跨进程对象共享有三种方式,第一种 ...

  9. python 数据可视化 -- 读取数据

    从 CSV 文件中读取数据(CSV) import sys import csv # python 内置该模块 支持各种CSV文件 file_name = r"..\ch02_data\ch ...

随机推荐

  1. JVM垃圾收集规则和算法

    1.垃圾收集 Garbage Collection 程序计数器.虚拟机栈.本地方法栈这三部分内存随着线程生而生,随着线程灭而自然的回收,他们的大小在编译期间就大致确定了下来,所以对这部分的回收是具备确 ...

  2. 在一个ros包下怎么使用另外一个自定义ros包里的message

    假设自定义消息包my_message_package https://answers.ros.org/question/206257/catkin-use-ros-message-from-anoth ...

  3. [转]CreateDIBitmap与CreateDIBSection

    首先明确最主要区别:CreateDIBitmap创建的是设备相关位图句柄 - HBITMAP.                               CreateDIBSection创建的是设备 ...

  4. IIS7.0添加IP地址和域名限制

    IIS7.0默认安装是没有“IP地址和域名限制”功能的,需要我们自己选择安装 1.windows系统的添加方式 控制面板--程序与功能--启用或关闭windows功能--internat inform ...

  5. HDU 2562 奇偶位互换(字符串,水)

      奇偶位互换 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  6. MongoDB走过的坑(4.0.3版本)

    数据存储一般使用本地或者存储在数据库,MongoDB是一个非关系型数据库,今天小结下走过的一些坑. 1.网上的很多教程对自己无效 解决方法:这种情况一般都是和版本有关系,数据库在不断的更新发展,很多东 ...

  7. 洛谷——P1722 矩阵 II

    P1722 矩阵 II 题目背景 usqwedf 改编系列题. 题目描述 如果你在百忙之中抽空看题,请自动跳到第六行. 众所周知,在中国古代算筹中,红为正,黑为负…… 给定一个1*(2n)的矩阵(us ...

  8. 超级素数(sprime) (BFS)

    问题 G: 超级素数(sprime) 时间限制: 1 Sec  内存限制: 64 MB提交: 47  解决: 11[提交][状态][讨论版] 题目描述 超级素数是指一个素数,每去掉后面一个数字,总能保 ...

  9. String和StringBuffer的机制差别

    String是不可变的,StringBuffer是可变的:StringBuffer是线程安全的,StringBuilder是非线程安全的. 因而在大部分情况下字符串的拼接速度为:StringBuild ...

  10. [BZOJ 3571] 画框

    Link: BZOJ 3571 传送门 Solution: 和 BZOJ2395 的建模完全相同,(BZOJ2395 题解传送门) 仅仅是将其中的基础问题由最小生成树改成了二分图最大完美匹配 只要将原 ...