Пример #1
0
def main(p_args):
    # Note 看这里 如果想做50个增量, 就把这个100改成50
    G_INCREMENT_SIZE = int(input('请输入样本数(必须是正整数):'))

    print('\n\n样本数为========>>%d\n' % (G_INCREMENT_SIZE))

    excel_title = ['序号', '地址编号', '省份', '城市', '区/县', '乡', '详细地址(拼接省市区)', '详细地址(PROD地址)', '经度', '纬度', '标准地址', '标准地址是否新地址']

    # 1. 读取地址信息
    old_excel_list = XUtils.excel_to_list(p_read_excel_file_path='./resources/receiving_address_input_1.xlsx',
                                          p_sheet_name='Sheet1',
                                          p_excel_title_list=excel_title)
    old_len = len(old_excel_list)
    print('\n最原始的数据总条数old_excel_list length=====>>%d' % (old_len))
    err_num = 0
    tmp_old_excel_list = []
    for tmp_dict in old_excel_list:
        if XUtils.has_valid_lat_lng(tmp_dict):
            tmp_old_excel_list.append(tmp_dict)
        else:
            err_num += 1
    old_excel_list = tmp_old_excel_list
    print('\n经纬度数据有问题的数据条数  invalid data num======>>%d' % (err_num))
    print('\n真实参与处理的数据条数(即抛弃了非法数据后) old_excel_list length=====>> (%d - %d) = %d\n' % (
        old_len, err_num, len(old_excel_list)))

    XUtils.process_and_dump_2_excel(p_excel_title=excel_title, p_new_excel_list=old_excel_list,
                                    p_new_file='./resources/receiving_address_input_1_ok.xls')

    # 增量
    increment_list = []
    while len(increment_list) < G_INCREMENT_SIZE:
        random_index = random.randint(0, len(old_excel_list) - 1)
        tmp_dict = old_excel_list.pop(random_index)
        increment_list.append(tmp_dict)
    # 存量(即表1)
    stock_list = old_excel_list

    print('存量 increment_list.length===>%d' % (len(increment_list)))
    print('删除了存量后的表1 stock_list.length===>%d' % (len(stock_list)))

    XUtils.process_and_dump_2_excel(p_excel_title=excel_title, p_new_excel_list=stock_list,
                                    p_new_file='./resources/receiving_address_stock_1_ok.xls')

    XUtils.process_and_dump_2_excel(p_excel_title=excel_title, p_new_excel_list=increment_list,
                                    p_new_file='./resources/receiving_address_increment_1_ok.xls')

    return 0
Пример #2
0
def contains(p_new_excel_list=None, p_old_dict=None):
    """
    判断
    :param p_new_excel_list:
    :param p_old_dict:
    :return: rst为true的时候表示能够在p_new_excel_list找到兄弟节点, 否则找不到兄弟节点。 (所谓兄弟节点就是指着这2个点认为是同一个地址), brother_dict是p_old_dict的兄弟节点.
    """
    rst = False
    max_sim = -3721.4728
    brother_dict = None

    # 竟然没有SIM ??????????????
    for tmp_new_dict in p_new_excel_list:

        # Note 利用余弦相似度公式计算两字符串的相似性 (相似度达到0.8则认为是一个地址,否则是2个不同地址, 这个0.8我是随便写的, 可修改)
        # rst_cos_sim = CosineSimilarityStrategy().compare(p_address_dict_a=tmp_new_dict, p_address_dict_b=p_old_dict)

        # NOTE 通过对经纬度的比较,相差百分之一或更小以内的视为同一地址,否则视为两个地址
        # rst_lal = LALPctStrategy().compare(p_address_dict_a=tmp_new_dict, p_address_dict_b=p_old_dict)

        # Note 根据距离来判断(200米)
        match_distance, real_distance = GEODistanceStrategy().compare(
            p_address_dict_a=tmp_new_dict, p_address_dict_b=p_old_dict)
        # real_distance = random.randint(0, 5000000)
        # 2个点的真实距离
        x = real_distance

        # Note 计算字符匹配度
        # 详细地址(拼接省市区)匹配度; 详细地址(PROD地址) 匹配度
        rst_str_diff, sim_string = AddressStringDiffStrategy().compare(
            p_address_dict_a=tmp_new_dict, p_address_dict_b=p_old_dict)
        # sim_string = random.random()
        # a是字符串相似度, b是距离相似度
        a = sim_string

        # 首先判断,已有地址的这一条数据有没有经纬度
        # 如果有
        #       计算距离X
        #       再计算b =(500 - X) / 500, Note 此处的500也作为一个参数,允许调整,见XConstants.FIXED_DISTANCE
        #       这里加上一个b的下限
        #       b下限 =(β - a理论 * α) / (1 - α)
        #       如果b小于这个值
        #       b直接等于这个值
        #       这一步主要保证了当a大于a理论(0.95)时,匹配一定能成功大于β(判定值)0.6
        #       α就是你的FACTER权重
        # 如果没有
        #       b = 0
        if XUtils.has_valid_lat_lng(p_old_dict):
            # 计算根据距离算出来的相似度. 其中x是求大圆算出来的距离, 即2个点的真实距离
            b = (XConstants.FIXED_DISTANCE - x) / XConstants.FIXED_DISTANCE
            # b还影响匹配度, 但是影响程度非常低
            B_MIN = (XConstants.BETA - XConstants.A_THEORY *
                     XConstants.ALPHA) / (1 - XConstants.ALPHA)
            if b < B_MIN:
                b = B_MIN
        else:
            b = 0

        #
        sim = XConstants.ALPHA * a + (1 - XConstants.ALPHA) * b

        # rst = match_distance is True and rst_str_diff is True
        # NOTE 看这里  ...................... 此处也需要人为调整
        if rst is False:
            # 一旦匹配到一个兄弟后, 就认为成功, 后续就无需再考虑rst了, 后续就是去找匹配度更高的兄弟即可
            rst = sim >= 0.6

        tmp_new_dict['sim'] = sim

        # Note 取得sim 最大的作为兄弟返回
        if rst is True:
            if brother_dict is None or tmp_new_dict['sim'] > brother_dict[
                    'sim']:
                brother_dict = tmp_new_dict
                max_sim = brother_dict['sim']

    return rst, brother_dict, max_sim