Есть ли способ ускорить мой сценарий рекомендации python? - PullRequest
1 голос
/ 19 марта 2020

Чтобы изучить системы рекомендаций, я сделал довольно основательную c, основанную на некоторых данных Twitter. Работает хорошо, единственное, что для запуска требуется 15-20 минут. Я почти уверен, что сделал много ошибок новичка, которые вызвали это, так как это должно было начаться примерно через полминуты.

Что я знаю, так это то, что эта проблема не вызвана функцией load_data (), так как эта функция занимает около 10 секунд без остальной части кода. Любое понимание того, где я ошибся?

#!/usr/bin/env python3
import sys

from operator import itemgetter
from collections import defaultdict




def load_data():

    n = 50
    with open(sys.argv[1], 'r') as f_user_sim:

        #build dictionary of all users and similarities
        sim_dict = dict()
        for line in f_user_sim:
            line = line.strip().split()
            user1, user2, sim = line[0], line[1], line[2]
            if not user1 in sim_dict:
                sim_dict[user1] = []
            sim_dict[user1].append((user2, sim))

        #for each user, sort its list of other users by similarity, resize list according to n
        for u in sim_dict:
            newlist = sorted(sim_dict[u], key=itemgetter(1), reverse=True)[:n]
            sim_dict[u] = newlist
        return sim_dict

def VIP(user):
    with open(sys.argv[3], 'r') as f_training_matrix:
        vip_dict = list()
        for line in f_training_matrix:
           if line.split()[0] == user:
                vip_dict.append(line.split()[1])
    return vip_dict

def VIP_counter(user,simusers):
    # list of vips the user already follows
    uservips = VIP(user)
    # makes list of lists of vips that users follow
    viplist = []
    for u in simusers:
        viplist.append(VIP(u))
    # convert list of lists to counted dict
    counts = dict()
    for i in viplist:
        for j in i:
            if j not in uservips and j != user:
                counts[j] = counts.get(j,0) +1
    # sort dict
    sorteddict = sorted(counts.items(), key=lambda x: x[1], reverse=True)
    topten = sorteddict[:10]
    #convert list of tuples to str of keys with spaces
    return ' '.join([str(elem[0]) for elem in topten])



def main():
    simdict = load_data()

    # open input and output files
    with open(sys.argv[4], 'r') as f_input:
        with open('recommender_s2922916.dev.output', 'w+') as f_output:
           for line in f_input:
                user = line.strip()

                # make list of N similar users
                simusers = []
                for i in simdict[user][:10]:
                    simusers.append(i[0])

                # for all similar users, list every VIP they follow in list and enumerate them, output the the ten highest in spaced out string form
                counts = VIP_counter(user,simusers)
                # write the output
                f_output.write(counts)
                f_output.write('\n')

if __name__ == "__main__":
    main()

1 Ответ

0 голосов
/ 19 марта 2020

Используйте pandas фреймы данных для чтения / записи / обработки операций кода. В этом сценарии вы получите больше.

Например:

def VIP(user):
    df = pd.read_csv(sys.argv[3], usecols=[0,1], names=['colA', 'colB'], header=None)
    return df[df.colA==user]

Вы можете улучшить все методы вашего кода без циклов, сравнений, разбиений и создания новых элементов данных. Не рекомендуется выполнять простые операции, как это было сделано для больших наборов данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...