<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Stage 4, Report
https
Step1:  Filling in Missing Values
Step2:  Generating Features
Here, we generate all the features we decided upon after our final iteration of cross validation and debugging. We only use the relevant subset of all these features in the reported iterations below.
Step3:  Cross Validation Method
Step4:  Iteration 1
Step5:  Iteration 2
Step6:  Iteration 3
Step7:  Iteration 4
Step8:  Train-Test Set Accuracy
<ASSISTANT_TASK:>
Python Code:
import py_entitymatching as em
import os
import pandas as pd
# specify filepaths for tables A and B. 
path_A = 'newTableA.csv'
path_B = 'tableB.csv'
# read table A; table A has 'ID' as the key attribute
A = em.read_csv_metadata(path_A, key='id')
# read table B; table B has 'ID' as the key attribute
B = em.read_csv_metadata(path_B, key='id')
Explanation: Stage 4, Report
https://github.com/anhaidgroup/py_entitymatching/blob/master/notebooks/vldb_demo/Demo_notebook_v6.ipynb
End of explanation
# Impute missing values
# Manually set metadata properties, as current py_entitymatching.impute_table()
# requires 'fk_ltable', 'fk_rtable', 'ltable', 'rtable' properties
em.set_property(A, 'fk_ltable', 'id')
em.set_property(A, 'fk_rtable', 'id')
em.set_property(A, 'ltable', A)
em.set_property(A, 'rtable', A)
A_all_attrs = list(A.columns.values)
A_impute_attrs = ['year','min_num_players','max_num_players','min_gameplay_time','max_gameplay_time','min_age']
A_exclude_attrs = list(set(A_all_attrs) - set(A_impute_attrs))
A1 = em.impute_table(A, exclude_attrs=A_exclude_attrs, missing_val='NaN', strategy='most_frequent', axis=0, val_all_nans=0, verbose=True)
# Compare number of missing values to check the results
print(sum(A['min_num_players'].isnull()))
print(sum(A1['min_num_players'].isnull()))
# Do the same thing for B
em.set_property(B, 'fk_ltable', 'id')
em.set_property(B, 'fk_rtable', 'id')
em.set_property(B, 'ltable', B)
em.set_property(B, 'rtable', B)
B_all_attrs = list(B.columns.values)
# TODO: add 'min_age'
B_impute_attrs = ['year','min_num_players','max_num_players','min_gameplay_time','max_gameplay_time']
B_exclude_attrs = list(set(B_all_attrs) - set(B_impute_attrs))
B1 = em.impute_table(B, exclude_attrs=B_exclude_attrs, missing_val='NaN', strategy='most_frequent', axis=0, val_all_nans=0, verbose=True)
# Compare number of missing values to check the results
print(sum(B['min_num_players'].isnull()))
print(sum(B1['min_num_players'].isnull()))
# Load the pre-labeled data
S = em.read_csv_metadata('sample_labeled.csv', 
                         key='_id',
                         ltable=A1, rtable=B1, 
                         fk_ltable='ltable_id', fk_rtable='rtable_id')
# Split S into I an J
IJ = em.split_train_test(S, train_proportion=0.75, random_state=35)
I = IJ['train']
J = IJ['test']
corres = em.get_attr_corres(A1, B1)
print(corres)
Explanation: Filling in Missing Values
End of explanation
# Generate a set of features
#import pdb; pdb.set_trace();
import py_entitymatching.feature.attributeutils as au
import py_entitymatching.feature.simfunctions as sim
import py_entitymatching.feature.tokenizers as tok
ltable = A1
rtable = B1
# Get similarity functions for generating the features for matching
sim_funcs = sim.get_sim_funs_for_matching()
# Get tokenizer functions for generating the features for matching
tok_funcs = tok.get_tokenizers_for_matching()
# Get the attribute types of the input tables
attr_types_ltable = au.get_attr_types(ltable)
attr_types_rtable = au.get_attr_types(rtable)
# Get the attribute correspondence between the input tables
attr_corres = au.get_attr_corres(ltable, rtable)
print(attr_types_ltable['name'])
print(attr_types_rtable['name'])
attr_types_ltable['name'] = 'str_bt_5w_10w'
attr_types_rtable['name'] = 'str_bt_5w_10w'
# Get the features
F = em.get_features(ltable, rtable, attr_types_ltable,
                                 attr_types_rtable, attr_corres,
                                 tok_funcs, sim_funcs)
#F = em.get_features_for_matching(A1, B1)
print(F['feature_name'])
#TODO get name feature!
#http://pradap-www.cs.wisc.edu/cs638/py_entitymatching/user-manual/_modules/py_entitymatching/feature/simfunctions.html#get_sim_funs_for_matching
#name_feature = em.get_feature_fn('name', em.get_tokenizers_for_matching(), em.get_sim_funs_for_matching())
#print(name_feature)
#em.add_feature(F, 'name_dist', name_feature)
#print(F['feature_name'])
Explanation: Generating Features
Here, we generate all the features we decided upon after our final iteration of cross validation and debugging. We only use the relevant subset of all these features in the reported iterations below.
End of explanation
def cross_validation_eval(H):
    cv_iter = pd.DataFrame(columns=['Precision', 'Recall', 'F1'])
    # Matchers
    matchers = [em.DTMatcher(name='DecisionTree', random_state=0),
     em.RFMatcher(name='RandomForest', random_state=0),
     em.SVMMatcher(name='SVM', random_state=0),
     em.NBMatcher(name='NaiveBayes'),
     em.LogRegMatcher(name='LogReg', random_state=0),
    ]
    
    for m in matchers:
        prec_result = em.select_matcher([m], table=H, 
                exclude_attrs=['_id', 'ltable_id', 'rtable_id','label'],
                k=5,
                target_attr='label', metric='precision', random_state=0)
        recall_result = em.select_matcher([m], table=H, 
                exclude_attrs=['_id', 'ltable_id', 'rtable_id','label'],
                k=5,
                target_attr='label', metric='recall', random_state=0)
        f1_result = em.select_matcher([m], table=H, 
                exclude_attrs=['_id', 'ltable_id', 'rtable_id','label'],
                k=5,
                target_attr='label', metric='f1', random_state=0)
        cv_iter = cv_iter.append(
            pd.DataFrame([
                [prec_result['cv_stats']['Mean score'][0],
                recall_result['cv_stats']['Mean score'][0],
                f1_result['cv_stats']['Mean score'][0],
                ]],
                index=[m.name],
                columns=['Precision', 'Recall', 'F1']))
    return cv_iter
Explanation: Cross Validation Method
End of explanation
# Subset of features we used on our first iteration
include_features = [
    'min_num_players_min_num_players_lev_dist',
    'max_num_players_max_num_players_lev_dist',
    'min_gameplay_time_min_gameplay_time_lev_dist',
    'max_gameplay_time_max_gameplay_time_lev_dist',
]
F_1 = F.loc[F['feature_name'].isin(include_features)]
# Convert the I into a set of feature vectors using F
H_1 = em.extract_feature_vecs(I, feature_table=F_1, attrs_after='label', show_progress=False)
H_1.head(10)
cross_validation_eval(H_1)
Explanation: Iteration 1: CV
End of explanation
PQ = em.split_train_test(H_1, train_proportion=0.80, random_state=0)
P = PQ['train']
Q = PQ['test']
# Convert the I into a set of feature vectors using F
# Here, we add name edit distance as a feature
include_features_2 = [
    'min_num_players_min_num_players_lev_dist',
    'max_num_players_max_num_players_lev_dist',
    'min_gameplay_time_min_gameplay_time_lev_dist',
    'max_gameplay_time_max_gameplay_time_lev_dist',
    'name_name_lev_dist'
]
F_2 = F.loc[F['feature_name'].isin(include_features_2)]
H_2 = em.extract_feature_vecs(I, feature_table=F_2, attrs_after='label', show_progress=False)
H_2.head(10)
# Split H into P and Q
PQ = em.split_train_test(H_2, train_proportion=0.75, random_state=0)
P = PQ['train']
Q = PQ['test']
Explanation: Iteration 2: Debug
End of explanation
# Convert the I into a set of feature vectors using F
# Here, we add name edit distance as a feature
include_features_3 = [
    'min_num_players_min_num_players_lev_dist',
    'max_num_players_max_num_players_lev_dist',
    'min_gameplay_time_min_gameplay_time_lev_dist',
    'max_gameplay_time_max_gameplay_time_lev_dist',
    'name_name_lev_dist'
]
F_3 = F.loc[F['feature_name'].isin(include_features_3)]
H_3 = em.extract_feature_vecs(I, feature_table=F_3, attrs_after='label', show_progress=False)
cross_validation_eval(H_3)
Explanation: Iteration 3: CV
End of explanation
# Convert the I into a set of feature vectors using F
# Here, we add name edit distance as a feature
include_features_4 = [
    'min_num_players_min_num_players_lev_dist',
    'max_num_players_max_num_players_lev_dist',
    'min_gameplay_time_min_gameplay_time_lev_dist',
    'max_gameplay_time_max_gameplay_time_lev_dist',
    'name_name_jac_qgm_3_qgm_3'
]
F_4 = F.loc[F['feature_name'].isin(include_features_4)]
H_4 = em.extract_feature_vecs(I, feature_table=F_4, attrs_after='label', show_progress=False)
cross_validation_eval(H_4)
Explanation: Iteration 4: CV
End of explanation
# Apply train, test set evaluation
I_table = em.extract_feature_vecs(I, feature_table=F_2, attrs_after='label', show_progress=False)
J_table = em.extract_feature_vecs(J, feature_table=F_2, attrs_after='label', show_progress=False)
matchers = [
 #em.DTMatcher(name='DecisionTree', random_state=0),
 #em.RFMatcher(name='RF', random_state=0),
 #em.NBMatcher(name='NaiveBayes'),
 em.LogRegMatcher(name='LogReg', random_state=0),
 #em.SVMMatcher(name='SVM', random_state=0)
]
for m in matchers:
    m.fit(table=I_table, exclude_attrs=['_id', 'ltable_id', 'rtable_id','label'], target_attr='label')
    J_table['prediction'] = m.predict(
        table=J_table, 
        exclude_attrs=['_id', 'ltable_id', 'rtable_id', 'label'], 
        target_attr='label',
    )
    print(m.name)
    em.print_eval_summary(em.eval_matches(J_table, 'label', 'prediction'))
    J_table.drop('prediction', axis=1, inplace=True)
    print('')
    
log_matcher = matchers[0]
J_table['prediction'] = m.predict(
        table=J_table, 
        exclude_attrs=['_id', 'ltable_id', 'rtable_id', 'label'], 
        target_attr='label',
    )
print(m.name)
em.print_eval_summary(em.eval_matches(J_table, 'label', 'prediction'))
J_table.drop('prediction', axis=1, inplace=True)
print('')
candidate_set_C1.csv
Explanation: Train-Test Set Accuracy
End of explanation
<END_TASK>