Example #1
0
def initialize_user_preference_value_based_on_preferred_item(
        user_preference_data, item_info_dict, categorical_attributes,
        numerical_attributes):

    user_preference_value_dict = {}
    user_preferred_item = user_preference_data['phones']
    user_preferred_item_dict = {}
    for item_id in user_preferred_item:
        user_preferred_item_dict[len(user_preferred_item_dict) +
                                 1] = item_info_dict[item_id]

    user_preferred_item_df = pd.DataFrame.from_dict(user_preferred_item_dict,
                                                    orient='index')
    # pp.pprint(user_preferred_item_df)
    for attr in categorical_attributes:
        user_preferred_item_attr_df = user_preferred_item_df[attr]
        user_preference_value_dict[
            attr] = user_preferred_item_attr_df.value_counts().to_dict()
    for attr in numerical_attributes:
        user_preferred_item_attr_df = user_preferred_item_df[attr].astype(str)
        user_preferred_item_attr_value_dict = user_preferred_item_attr_df.value_counts(
        ).to_dict()
        attr_rank_label_list = helper.get_numerical_attribute_rank_label(attr)
        for rank in attr_rank_label_list:
            if rank not in user_preferred_item_attr_value_dict.keys():
                user_preferred_item_attr_value_dict[rank] = 0
        user_preference_value_dict[attr] = user_preferred_item_attr_value_dict

    # pp.pprint(user_preference_value_dict)
    time_helper.print_current_time()
    print(
        "Initialize User Model ---- Initialize preference value based on the user's selected preferred items."
    )

    return user_preference_value_dict
Example #2
0
    def post(self):
        start = time.process_time()
        time_helper.print_current_time()
        print("Update User Model ---- start")


        json_data = request.get_json(force=True)
        user_profile = json_data['user_profile']
        user_interaction_dialog = user_profile['logger']['latest_dialog']
        user_browsed_items = user_profile['logger']['browsedItems']
        user_model = user_profile['user']
        current_recommended_item = user_profile['topRecommendedItem']
        key = 'id'
        # update the user model (three parts)
        updated_user_preference_model, updated_user_constraints, updated_user_critique_preference = user_modeling.update_user_model(user_model, \
            user_interaction_dialog, user_browsed_items, current_recommended_item, categorical_attributes, numerical_attributes, key, item_info_dict)
        user_profile['user']['user_preference_model'] = updated_user_preference_model
        user_profile['user']['user_constraints'] = updated_user_constraints
        user_profile['user']['user_critique_preference'] = updated_user_critique_preference
        
        # update the user interaction log 
        # for log in user_interaction_dialog:
        #     user_profile['logger']['dialog'].append(copy.deepcopy(log))
        
        # user_profile['logger']['latest_dialog'] = []
        
        end = time.process_time()
        time_helper.print_current_time()
        print ('Update User Model ---- run time : %ss ' % str(end-start))

        return json.dumps(user_profile)
Example #3
0
def initialize_user_preference_model(user_preference_data, item_info_dict,
                                     categorical_attributes,
                                     numerical_attributes):
    #  ---- 2020/05
    #  version 1: initialize_user_preference_value --- based on specified preference value (e.g. specific brand, or range of price...)
    #  user_initial_preference_value =  initialize_user_preference_value(user_preference_data, categorical_attributes, numerical_attributes)

    #  ---- 2020/09
    #  version 2: initialize_user_preference_value --- based on selected preferred mobile phone (user_preference_data contains N preferred mobile phone id)
    user_initial_preference_value = initialize_user_preference_value_based_on_preferred_item(
        user_preference_data, item_info_dict, categorical_attributes,
        numerical_attributes)

    user_preference_attribute_frequency = initialize_user_preference_attribute_frequency(
        categorical_attributes, numerical_attributes)
    user_preference_model = {
        'preference_value': user_initial_preference_value,
        'attribute_frequency': user_preference_attribute_frequency
    }

    # pp.pprint(user_preference_model)

    time_helper.print_current_time()
    print(
        "Initialize User Model ---- Preference Model about %d categorical attributes."
        % len(categorical_attributes))
    time_helper.print_current_time()
    print(
        "Initialize User Model ---- Preference Model about %d numerical attributes."
        % len(numerical_attributes))
    return user_preference_model
Example #4
0
def initialize_user_preference_attribute_frequency(categorical_attributes,
                                                   numerical_attributes):
    user_preference_attribute_frequency_dict = {}
    for attr in categorical_attributes:
        user_preference_attribute_frequency_dict[attr] = 1
    for attr in numerical_attributes:
        user_preference_attribute_frequency_dict[attr] = 1

    time_helper.print_current_time()
    print(
        "Initialize User Model ---- Initialize attribute frequency as 1 for all attributes."
    )

    return user_preference_attribute_frequency_dict
Example #5
0
def initialize_user_preference_value(user_preference_data,
                                     categorical_attributes,
                                     numerical_attributes):

    user_preference_value_dict = {}
    for attr in categorical_attributes:
        if attr not in user_preference_data.keys():
            user_preference_data[attr] = []
        user_preference_value_dict[attr] = categorical_attribute_preference(
            user_preference_data[attr])
    for attr in numerical_attributes:
        if attr not in user_preference_data.keys():
            user_preference_data[attr] = []
        user_preference_value_dict[attr] = numerical_attribute_preference(
            user_preference_data[attr], attr)

    pp.pprint(user_preference_value_dict)
    time_helper.print_current_time()
    print(
        "Initialize User Model ---- Initialize preference value based on the user's specified preference data."
    )

    return user_preference_value_dict
Example #6
0
def update_user_model(user_model, user_interaction_dialog, user_browsed_items,
                      current_recommended_item, categorical_attributes,
                      numerical_attributes, key, item_info_dict):
    updated_user_preference_value = user_model['user_preference_model'][
        'preference_value']
    updated_user_attribute_frequency = user_model['user_preference_model'][
        'attribute_frequency']
    updated_user_constraints = user_model['user_constraints']
    updated_user_critique_preference = user_model['user_critique_preference']
    numerical_crit_direction_limit = ['higher', 'lower', 'normal', 'similar']

    updated_user_preference_model = user_model['user_preference_model']

    for utterance_info in user_interaction_dialog:
        current_action = utterance_info['action'].lower()
        # Condition 1: user critiquing / system suggest critiquing - Yes
        # -> update (1) user critique preference, (2) preference model: attribute frequency, (3) user constraints,

        time_helper.print_current_time()
        print("Update User Model ---- User Action: %s." % (current_action))

        if current_action == "user_critique" or current_action == "accept_suggestion":
            critique_list = []
            if 'critique' in utterance_info.keys():
                critique_list = utterance_info['critique']
            critique_item_info = item_info_dict[current_recommended_item]

            time_helper.print_current_time()
            print("Update User Model (%s) ---- Number of Critiques: %d." %
                  (current_action, len(critique_list)))

            for crit in critique_list:
                for attr, criti_value in crit.items():
                    if attr not in numerical_attributes and attr not in categorical_attributes:
                        time_helper.print_current_time()
                        print("Unrecognized attributes: %s." % attr)
                        continue

                    if attr in numerical_attributes and criti_value not in numerical_crit_direction_limit:
                        time_helper.print_current_time()
                        print("Unrecognized critique direction: %s." %
                              criti_value)
                        continue

                    # preference model: attribute frequency
                    updated_user_attribute_frequency[
                        attr] = updated_user_attribute_frequency[attr] * 2
                    time_helper.print_current_time()
                    print("update attribute frequence: attribute (%s) - %f. " %
                          (attr, updated_user_attribute_frequency[attr]))
                    # user critique preference
                    updated_user_critique_preference = update_user_critique_preference(updated_user_critique_preference, attr,\
                        criti_value, critique_item_info, numerical_attributes, 'pos')
            # pp.pprint(updated_user_critique_preference)

            # user constraint
            constraint_number = 5
            updated_user_constraints = update_user_constraints(
                updated_user_critique_preference, constraint_number)
            # pp.pprint(updated_user_constraints)

            time_helper.print_current_time()
            print(
                "Update User Model ---- Number of Current User Constraints: %d."
                % len(updated_user_constraints))

        # Condition 2:  system suggest critiquing - No
        # -> update (1) user critique negative
        if current_action == 'reject_suggestion':
            critique_list = []
            if 'critique' in utterance_info.keys():
                critique_list = utterance_info['critique']
            critique_song_info = current_recommended_item

            time_helper.print_current_time()
            print("Update User Model (%s) ---- Number of Critiques: %d." %
                  (current_action, len(critique_list)))

            for crit in critique_list:
                for attr, criti_value in crit.items():

                    check_consective_reject_SC = False
                    # check if there are consective rejected critiques within the same attribute (decrease the attribute frequency)
                    if len(updated_user_critique_preference) > 0:
                        latest_user_critique_preference = updated_user_critique_preference[
                            -1]
                        # time_helper.print_current_time()
                        # print("latest_critique: ", latest_user_critique_preference)
                        if attr in numerical_attributes and latest_user_critique_preference[
                                'pos_or_neg'] == 'neg' and latest_user_critique_preference[
                                    'attribute'] == attr:
                            check_consective_reject_SC = True
                            updated_user_attribute_frequency[
                                attr] = updated_user_attribute_frequency[
                                    attr] / 2
                            time_helper.print_current_time()
                            print(
                                "update attribute frequence: attribute (%s) - %f. "
                                %
                                (attr, updated_user_attribute_frequency[attr]))

                    if check_consective_reject_SC == False:
                        updated_user_attribute_frequency[
                            attr] = updated_user_attribute_frequency[
                                attr] * 0.75
                        time_helper.print_current_time()
                        print(
                            "update attribute frequence: attribute (%s) - %f. "
                            % (attr, updated_user_attribute_frequency[attr]))

                    # user critique preferencef
                    updated_user_critique_preference = update_user_critique_preference(
                        updated_user_critique_preference, attr, criti_value,
                        critique_song_info, numerical_attributes, 'neg')

        # Condition 3: accept the recommendation
        if current_action == "accept_item" or current_action == "request_rate":

            # --- Revise ---- system critique - accept -> update critique preference, attribute frequency, user constraints
            # # if the recommended item is based on system critiques
            # # -> update (1) user critique preference (if "sys_critique"), (2) preference model: attribute frequency, (3) user constraints,

            # if len(sys_critique_list) > 0:
            #     critique_list = sys_critique_list
            #     critique_item_id = utterance_info['critiqued_item']
            #     critique_item_info = {}
            #     for item in user_listened_longs:
            #         if item['id'] == critique_item_id:
            #             critique_item_info = item

            #     for crit in critique_list:
            #         for attr, criti_value in crit.items():
            #             # preference model: attribute frequency
            #             updated_user_attribute_frequency[attr] = updated_user_attribute_frequency[attr] + 1
            #             # user critique preference
            #             updated_user_critique_preference = update_user_critique_preference(updated_user_critique_preference, attr, criti_value, critique_item_info, numerical_attributes)

            #     # user constraint
            #     constraint_number = 3
            #     updated_user_constraints = update_user_constraints(updated_user_critique_preference, constraint_number)

            # ------------------------------------------------
            # Update preference value based on the liked items
            # ------------------------------------------------
            liked_item_info = item_info_dict[current_recommended_item]
            updated_user_preference_value = update_user_preference_value(
                updated_user_preference_value, liked_item_info,
                categorical_attributes, numerical_attributes)

            time_helper.print_current_time()
            print(
                "Update User Model ---- Update preference value based on the accepted item."
            )

    updated_user_preference_model = {
        'preference_value': updated_user_preference_value,
        'attribute_frequency': updated_user_attribute_frequency
    }

    return updated_user_preference_model, updated_user_constraints, updated_user_critique_preference
Example #7
0
def generate_system_critiques_preference_oriented(
        user_info, user_critique_preference, estimated_score_dict, item_pool,
        cur_rec, top_K, unit_or_compound, categorical_attributes,
        numerical_attributes, key):

    # Step 1: Generate a critique array for each item
    item_critique_arrays, item_critique_arrays_dict = generate_critique_array(
        item_pool, cur_rec, categorical_attributes, numerical_attributes, key)

    # Step 2: Find frequent critiques set (Compound & Unit)
    num_critique_sets_dict, rules = apriori(item_critique_arrays,
                                            min_support=min_support,
                                            min_confidence=min_confidence)

    # Step 3: Filter frequent critiques that have conflict with user past critiques.
    categorical_critique_dict, numerical_critique_dict = helper.convert_to_critique_preference_dict(
        user_critique_preference)

    # pp.pprint(categorical_critique_dict)
    # pp.pprint(numerical_critique_dict)

    all_critiques_freq_dict = {}
    frequent_critiques_freq_dict = {}
    for num in unit_or_compound:
        for crit, freq in num_critique_sets_dict[num].items():
            all_critiques_freq_dict[crit] = freq
            if not check_critique_conflict_with_user_preference(
                    crit, cur_rec, categorical_critique_dict,
                    numerical_critique_dict):
                frequent_critiques_freq_dict[crit] = freq
    # pp.pprint(frequent_critiques_freq_dict)

    time_helper.print_current_time()
    print('Frequent critiques (support value: %f):  %d (%s).' %
          (min_support, len(frequent_critiques_freq_dict),
           str(unit_or_compound)))

    # -------------------------------------------------------
    # --------------------  Apropri   -----------------------
    # -------------------------------------------------------

    # # pp.pprint(rules)

    # # Print out every rule with 2 items on the left hand side,
    # # 1 item on the right hand side, sorted by lift
    # rules_rhs = filter(lambda rule: len(rule.lhs) == 1 and len(rule.rhs) == 1, rules)
    # for rule in sorted(rules_rhs, key=lambda rule: rule.lift, reverse=True):
    #     pass
    #     # print(rule) # Prints the rule and its confidence, support, lift, ...

    # -------------------------------------------------------

    if len(frequent_critiques_freq_dict) == 0:
        frequent_critiques_freq_dict = all_critiques_freq_dict
        time_helper.print_current_time()
        print("Generate critiques that may conflict with users' preferences.")
    else:
        time_helper.print_current_time()
        print("Find some critiques that suit users' taste.")

    # Step 3: Obtain the set of items that satisfy the critique
    frequent_critiques_satisfied_items_dict = obtain_critique_items_dict(
        frequent_critiques_freq_dict, item_critique_arrays_dict)
    # pp.pprint(frequent_critiques_satisfied_items_dict)
    # Step 4: Compute critique utility for frequent critiques

    # compatibility_score_dict = recommendation.compute_recommendation_by_MAUT(user_info, item_pool, len(item_pool), categorical_attributes, numerical_attributes)
    user_attribute_frequency = user_info['attribute_frequency']
    sorted_critique_utility_list = compute_critique_utility_preference_oriented(
        user_attribute_frequency, frequent_critiques_freq_dict, min_support,
        frequent_critiques_satisfied_items_dict, estimated_score_dict)

    # time_helper.print_current_time()
    # print('compute critique utility - preference-oriented - Done.')

    # version 1: re-sort SC (put the critiques with same attribute but different directions together)
    top_K = min([top_K, len(sorted_critique_utility_list)])
    sorted_critique_list = resort_critique_list(sorted_critique_utility_list,
                                                top_K, numerical_attributes)

    # top_K = min([top_K, len(sorted_critique_utility_list)])
    # sorted_critique_diveristy_utility_list = compute_critique_diversity_utility(sorted_critique_utility_list, top_K)

    # time_helper.print_current_time()
    # print('obtain critique diversified - Done.')

    # pp.pprint(sorted_critique_diveristy_utility_list)
    topK_critique_item_list = obtain_top_k_critique_with_recommendation_list(
        top_K, sorted_critique_list, frequent_critiques_satisfied_items_dict,
        estimated_score_dict)

    return topK_critique_item_list
Example #8
0
    def post(self):
        start = time.process_time()
        time_helper.print_current_time()
        print("Initialize User Model ---- start")


        json_data = request.get_json(force=True)
        user_profile = json_data['user_profile']
        user_preference_data = user_profile['user']['preferenceData'] # initial preference data: a list of ids of phones that user preferred 

        # initialize the user preference model ** using user preference data
        # preference model consists of two parts: attribute frequency and preference value for each attribute
        user_preference_model = user_modeling.initialize_user_preference_model(user_preference_data, item_info_dict, categorical_attributes, numerical_attributes)
        user_profile['user']['user_preference_model'] = user_preference_model

        time_helper.print_current_time()
        print("Initialize User Model ---- Part 1: User Preference Model --- Done!")

        # initialize the user critique preference (empty)
        user_critique_preference = []
        user_profile['user']['user_critique_preference'] =  user_critique_preference

        time_helper.print_current_time()
        print("Initialize User Model ---- Part 2: User Critique Preference (empty) --- Done!")

        # initialize the user constraints (empty)
        user_constraint = []
        user_profile['user']['user_constraints'] =  user_constraint
        time_helper.print_current_time()
        print("Initialize User Model ---- Part 3: User Constraints (empty) --- Done!")


        ### -------------------------------------------------------------- 
        ### obtain initial recommendations (top 150 based on MAUT)
        initial_recommendations_list = []
        top_K = 150
        method = 'MAUT'
        alpha = 0.5
        topK_recommendations_score_dict = recommendation.compute_recommendation(user_preference_model, user_critique_preference, item_pool, top_K, \
                categorical_attributes, numerical_attributes, method, key, alpha)
       
        if len(topK_recommendations_score_dict) > 0:
            for rec in topK_recommendations_score_dict:
                initial_recommendations_list.append(rec[0])
        user_profile['pool'] = initial_recommendations_list

        time_helper.print_current_time()
        print("Obtain initial recommendation (top 150) based on MAUT --- Done!")

        end = time.process_time()
        time_helper.print_current_time()
        print ('Initialize User Model ---- run time : %ss ' % str(end-start))

        return json.dumps(user_profile)
Example #9
0
    def post(self):

        start = time.process_time()
        time_helper.print_current_time()
        print("Get System Critiques ---- start")



        json_data = request.get_json(force=True)
        user_profile = json_data['user_profile']
        user_preference_model = user_profile['user']['user_preference_model'] 
        user_critique_preference = user_profile['user']['user_critique_preference'] 
        user_constraints = user_profile['user']['user_constraints'] 
        item_pool_name_list = user_profile['pool']
        new_item_pool_name_list = user_profile['new_pool']

        user_interaction_log = user_profile['logger']

        cur_rec = user_profile['topRecommendedItem']
        cur_rec = copy.deepcopy(item_info_dict[cur_rec])

        item_pool = []
        user_pool_item_info_dict = {}
        for item in item_pool_name_list:
            item_pool.append(item_info_dict[item])
            user_pool_item_info_dict[item] = item_info_dict[item]
        time_helper.print_current_time()

     
        new_item_pool = []
        new_pool_item_info_dict = {}
        for item in new_item_pool_name_list:
            new_item_pool.append(item_info_dict[item])
            new_pool_item_info_dict[item] = item_info_dict[item]


        top_K = 3
        unit_or_compound = [1,2]
        

        item_pool_for_SC = item_pool
        new_item_pool_state = False

        if len(new_item_pool) > 0:
            new_item_pool_state = True
            item_pool_for_SC = new_item_pool

        time_helper.print_current_time()
        print("Get System Critiques ---- Item Pool: %d songs" % len(item_pool_for_SC))

        # whether or not to filter recommendation using hard constraints
        # minimal_threshold = 150
        # filtered_item_pool = recommendation.filter_items_by_user_constraints(user_constraints, item_pool, minimal_threshold,\
        #     categorical_attributes, numerical_attributes, key)
        # time_helper.print_current_time()
        # print("Filter By User Constraints --- after filtering, %d phones left." % len(filtered_item_pool))

        # filtered_item_pool = item_pool
        method = 'MAUT_COMPAT'
        alpha = 0.5
        top_k_candidates = 150

        # top_k_candidates = min([top_k_candidates, len(filtered_item_pool)])
        estimated_score_dict = recommendation.compute_recommendation(user_preference_model, user_critique_preference, item_pool_for_SC, len(item_pool_for_SC), categorical_attributes, numerical_attributes, method, key, alpha, sort=True)
        time_helper.print_current_time()
        print("Get System Critiques ---- Obtain item utility score by %s method (alpha:%f) --- Done." %(method, alpha))

        
        sorted_candidated_list = []
        for rec in estimated_score_dict:
            sorted_candidated_list.append(rec[0])
        

        estimated_score_dict = dict(estimated_score_dict)
        selected_item_pool = []
        for item in item_pool:
            if item[key] in sorted_candidated_list:
                selected_item_pool.append(item)
        time_helper.print_current_time()
        print('select %d recommendation for generating critiques.' % len(selected_item_pool))



        sys_crit_version = 'preference_oriented' # preference_oriented / diversity_oriented / personality_adjusted
        time_helper.print_current_time()
        print("Get System Critiques ---- system critique generation version: %s" % sys_crit_version)

        state = 'SC_and_Recommendation'
        sys_crit = None
        sys_crit = system_critiquing.generate_system_critiques_preference_oriented(user_preference_model,  user_critique_preference, estimated_score_dict, selected_item_pool, cur_rec, top_K, unit_or_compound, categorical_attributes , numerical_attributes, key)



        time_helper.print_current_time()
        print(state)
        # time_helper.print_current_time()
        # pp.pprint(sys_crit)
        sys_crit_with_rec_list = {'state': state, 'result': sys_crit}

        end = time.process_time()
        time_helper.print_current_time()
        print ('Get System Critiques ---- run time : %ss ' % str(end-start))

        return json.dumps(sys_crit_with_rec_list), 201



        return json.dumps(sys_crit_with_rec_list), 201
Example #10
0
    def post(self):

        start = time.process_time()
        time_helper.print_current_time()
        print("Get Recommendation ---- start")


        json_data = request.get_json(force=True)
        user_profile = json_data['user_profile']
        user_preference_model = user_profile['user']['user_preference_model'] 
        user_critique_preference = user_profile['user']['user_critique_preference'] 
        user_constraints = user_profile['user']['user_constraints'] 
        item_pool_name_list = user_profile['pool']
        new_item_pool_name_list = user_profile['new_pool']

        item_pool = []
        user_pool_item_info_dict = {}
        for item in item_pool_name_list:
            item_pool.append(item_info_dict[item])
            user_pool_item_info_dict[item] = item_info_dict[item]

        new_item_pool = []
        new_pool_item_info_dict = {}
        for item in new_item_pool_name_list:
            new_item_pool.append(item_info_dict[item])
            new_pool_item_info_dict[item] = item_info_dict[item]




        # Filter the items that the user has browsed 
        # user_interaction_log = user_profile['logger']
        # user_browsed_items = user_interaction_log['browsedItems']
        # for item_key in user_browsed_items:
        #     item_info = item_info_dict[item_key]
        #     item_pool.remove(item_info)
        # time_helper.print_current_time()
        # print("Filter Phone Data ---- Filter %d items that the user has browsed, %d items left. -- Done!" % (len(user_browsed_items), len(item_pool)))


        top_K = 20
        method = 'MAUT_COMPAT' # (1) MAUT (2) COMPAT (3) MAUT_COMPAT
        alpha = 0.5 # Linear combination weight: alpha-> weight for MAUT score; 1-alpha -> weight for COMPAT score

        minimal_threshold = 20
        time_helper.print_current_time()
        print("Get Recommendation ---- Method: %s (alpha:%f)." % (method,alpha)) 
         
        topK_recommendations_score_dict = {}
        if len(new_item_pool) > 0:
            topK_recommendations_score_dict = recommendation.compute_recommendation(user_preference_model, user_critique_preference, new_item_pool, top_K, \
                categorical_attributes, numerical_attributes, method, key, alpha)
        else: 
            filtered_item_pool = recommendation.filter_items_by_user_constraints(user_constraints, item_pool, minimal_threshold,\
                categorical_attributes, numerical_attributes, key)
        
            time_helper.print_current_time()
            print("Filter by User Constraints --- after filtering, %d items left." % len(filtered_item_pool))
                
            if len(filtered_item_pool) > 0:
                topK_recommendations_score_dict = recommendation.compute_recommendation(user_preference_model, user_critique_preference, filtered_item_pool, top_K, \
                    categorical_attributes, numerical_attributes, method, key, alpha)

        topK_recommendation_list = []
        if len(topK_recommendations_score_dict) > 0:
            for rec in topK_recommendations_score_dict:
                topK_recommendation_list.append(rec[0])
        time_helper.print_current_time()
        print("Get Recommendation ---- Obtained top %d recommended items. "% len(topK_recommendation_list)) 
        

        updated_item_pool = []

        if len(new_item_pool) > 0:
            time_helper.print_current_time()
            print("Get Recommendation ---- New Pool: %d songs." % (len(new_item_pool))) 
            time_helper.print_current_time()
            print("Get Recommendation ---- Original Item Pool: %d songs." % (len(item_pool))) 
            integrated_item_pool = new_item_pool + item_pool 
            assert(len(integrated_item_pool) == len(item_pool) + len(new_item_pool))

            max_item_pool_number = min([150, len(integrated_item_pool)])
            updated_item_pool = recommendation.update_recommendation_pool(user_preference_model, user_critique_preference, new_item_pool, integrated_item_pool, max_item_pool_number, categorical_attributes, numerical_attributes, method, alpha)
            print("Get Recommendation ---- Updated Item Pool: %d songs." % (len(updated_item_pool))) 
            
            user_profile['pool'] = updated_item_pool
            user_profile['new_pool'] = []

        recommendation_and_user_profile = {'recommendation_list': topK_recommendation_list, 'user_profile': user_profile}
        
        end = time.process_time()
        time_helper.print_current_time()
        print ('Get Recommendation ---- run time : %ss ' % str(end-start))


        return json.dumps(recommendation_and_user_profile), 201
Example #11
0
categorical_attributes = ['brand','nettech','os1', 'nfc', 'year', 'fullscreen']
numerical_attributes = ['phone_size', 'phone_weight', 'camera', 'storage', 'ram', 'price']

#  Load Phone Data
phone_data_file = 'data/new_phone_data.json'
phone_data = load_data.load_json_data(phone_data_file)
 # 'id' in music domain and 'id' in phone domain 

#  Load Phone Data
key = 'id'
item_pool = copy.deepcopy(phone_data['pool'])
item_info_dict = {}
for item in item_pool:
    item_info_dict[item[key]] = item
time_helper.print_current_time()
print("Load Phone Data (%d)---- Done!" % len(item_pool))


# 操作(post / get)资源列表
class InitializeUserModel(Resource):
    def post(self):
        start = time.process_time()
        time_helper.print_current_time()
        print("Initialize User Model ---- start")


        json_data = request.get_json(force=True)
        user_profile = json_data['user_profile']
        user_preference_data = user_profile['user']['preferenceData'] # initial preference data: a list of ids of phones that user preferred 
Example #12
0
def filter_items_by_user_constraints(user_constraints, item_pool,
                                     minimal_threshold, categorical_attributes,
                                     numerical_attributes, key):

    # revise

    filtered_item_pool = copy.deepcopy(item_pool)
    filter_by_top_critique = False

    for critique_unit_dict in user_constraints:
        filtered_id_list = []
        attr = critique_unit_dict['attribute']
        crit_direction = critique_unit_dict['crit_direction']
        crit_value = ''
        if attr in numerical_attributes:
            crit_value = critique_unit_dict['value']
        time_helper.print_current_time()
        print(critique_unit_dict)

        if attr in categorical_attributes:

            if type(crit_direction) == str:
                if attr == 'nettech' and '/' not in crit_direction:
                    for item in filtered_item_pool:
                        if crit_direction not in item[attr]:
                            filtered_id_list.append(item[key])
                else:
                    for item in filtered_item_pool:
                        if item[attr].lower() != crit_direction.lower():
                            # print(item[attr])
                            filtered_id_list.append(item[key])

            if type(crit_direction) == list:
                if attr == 'nettech':
                    for item in filtered_item_pool:
                        for crit_v in crit_direction:
                            if crit_v not in item[attr]:
                                filtered_id_list.append(item[key])
                                break
                else:
                    for item in filtered_item_pool:
                        if item[attr] not in crit_direction:
                            filtered_id_list.append(item[key])

        if attr in numerical_attributes:
            cur_index = crit_value
            _index, rank_total = helper.get_numerical_attribute_rank(attr, -1)

            for item in filtered_item_pool:

                item_index = item[attr]
                satisfied_flag = False

                if item_index == cur_index and crit_direction == 'similar':
                    satisfied_flag = True

                # case 1: current critiqued item value has been already the lowest range - allows to return items within same range
                if cur_index == 1:
                    if item_index <= cur_index and crit_direction == 'lower':
                        satisfied_flag = True

                # case 2: current critiqued item value has been already the highest range - allows to return items within same range
                elif cur_index == rank_total:
                    if item_index >= cur_index and crit_direction == 'higher':
                        satisfied_flag = True

                else:
                    if item_index < cur_index and crit_direction == 'lower':
                        satisfied_flag = True
                    if item_index > cur_index and crit_direction == 'higher':
                        satisfied_flag = True

                if satisfied_flag == False:
                    filtered_id_list.append(item[key])

        updated_filtered_item_pool = []
        for item in filtered_item_pool:
            if item[key] not in filtered_id_list:
                updated_filtered_item_pool.append(item)

        time_helper.print_current_time()
        print("number of filtered items: %d" % len(filtered_item_pool))
        time_helper.print_current_time()
        print("number of items after filtering: %d" %
              len(updated_filtered_item_pool))

        if filter_by_top_critique and len(
                updated_filtered_item_pool) < minimal_threshold:
            return filtered_item_pool

        else:
            filtered_item_pool = copy.deepcopy(updated_filtered_item_pool)
            filter_by_top_critique = True

    return filtered_item_pool
Example #13
0
def compute_recommendation_compatibility_score(user_critique_preference,
                                               item_pool,
                                               top_K,
                                               categorical_attributes,
                                               numerical_attributes,
                                               key,
                                               sort=True):

    # based on user critique preference and item value
    # calculate the compatibility score for each item

    # item compatibility score
    item_compatibility_score_dict = {}

    categorical_critique_dict, numerical_critique_dict = helper.convert_to_critique_preference_dict(
        user_critique_preference)

    for each_item in item_pool:
        item_id = each_item[key]
        item_compatibility_score = 0

        satisfied_critique_attribute_list = []
        unsatisfied_critique_attribute_list = []

        # 1. Categorical Attributes
        for attr in categorical_critique_dict.keys():
            critique_on_attribute = categorical_critique_dict[attr]['pos']
            if each_item[attr] in critique_on_attribute:
                satisfied_critique_attribute_list.append(attr)
            else:
                unsatisfied_critique_attribute_list.append(attr)

        # 2. Numerical Attributes
        for attr in numerical_critique_dict.keys():
            critique_on_attribute = numerical_critique_dict[attr]
            if each_item[attr] > critique_on_attribute[0] and each_item[
                    attr] < critique_on_attribute[1]:
                satisfied_critique_attribute_list.append(attr)
            else:
                unsatisfied_critique_attribute_list.append(attr)

        if len(satisfied_critique_attribute_list) > 0:
            item_compatibility_score = len(
                satisfied_critique_attribute_list) / (
                    len(satisfied_critique_attribute_list) +
                    len(unsatisfied_critique_attribute_list))
        item_compatibility_score_dict[item_id] = item_compatibility_score

    # pp.pprint(item_compatibility_score_dict)

    time_helper.print_current_time()
    print(
        "Get Recommendation ---- Compute recommendation compatibility score (COMPAT) ---- Done."
    )

    if sort:
        sorted_item_compatibility_score_list = helper.sort_dict(
            item_compatibility_score_dict)
        top_K_recommmendation_list = sorted_item_compatibility_score_list[
            0:top_K]
        return top_K_recommmendation_list
    else:
        return item_compatibility_score_dict
Example #14
0
def compute_recommendation_by_MAUT(user_preference_model,
                                   item_pool,
                                   top_K,
                                   categorical_attributes,
                                   numerical_attributes,
                                   key,
                                   sort=True):
    # based on user preference model and item value
    # use MAUT to estimate the user's preference for each item

    user_pref_attribute_frequency = user_preference_model[
        'attribute_frequency']
    user_pref_preference_value = user_preference_model['preference_value']

    # item utility
    item_utility_dict = {}

    # compute the attribute weight (normalization)-> the user's attribute preference
    user_pref_attribute_weight_dict = obtain_attribute_weight(
        user_pref_attribute_frequency)

    # user preference to item w.r.t. each attribute
    user_item_preference_value_dict = {}

    for each_item in item_pool:
        item_id = each_item[key]
        item_utility = 0
        # Step 1: Obtain the value for each attributes
        # 1. Categorical Attributes
        for attr in categorical_attributes:
            user_item_preference_value_dict[
                attr] = categorical_attributes_value_function(
                    user_pref_preference_value[attr], each_item[attr], attr)
        # 2. Numerical Attributes
        for attr in numerical_attributes:
            user_item_preference_value_dict[
                attr] = numerical_attributes_value_function(
                    user_pref_preference_value[attr], each_item[attr], attr)

        # Step 2: Calculate the utility
        # 1. Categorical Attributes
        for attr in categorical_attributes:
            item_utility = item_utility + user_pref_attribute_weight_dict[
                attr] * user_item_preference_value_dict[attr]
        # 2. Numerical Attributes
        for attr in numerical_attributes:
            item_utility = item_utility + user_pref_attribute_weight_dict[
                attr] * user_item_preference_value_dict[attr]

        item_utility_dict[item_id] = item_utility
        # print(item_utility)

    time_helper.print_current_time()
    print(
        "Get Recommendation ---- Compute recommendation Multi-attribute Utility score (MAUT) ---- Done."
    )

    if sort:
        sorted_item_utility_list = helper.sort_dict(item_utility_dict)
        # pp.pprint(sorted_item_utility_list)
        top_K_recommmendation_list = sorted_item_utility_list[0:top_K]
        print("Get Recommendation ---- MAUT Sort ---- Done.")

        return top_K_recommmendation_list
    else:
        return item_utility_dict