Мстители возвращаются на свою территорию в северной части штата Нью-Йорк. В Торонто большая группа злодеев нападает на рестораны! Мстители собираются.

Теперь, отбросив то, что вы знаете о составах Мстителей в истории, давайте предположим, что эта версия обычно состоит из Капитана Америки, Железного человека, Росомахи, Халка, Черной вдовы, Человека-муравья, Осы, Тора, Человека-паука и Соколиного Глаза.

Капитан Америка просматривает свой состав и получает сообщение. Оказывается, у кроткого Питера Паркера не такая уж кроткая грипповая инфекция… э… «паутинный грипп», назовем это. Не имея возможности присоединиться к Мстителям в этой миссии, Капитан Америка вынужден выяснить, кем его заменить. Ситуация в Торонто не улучшается, и решение должно быть принято, но с таким количеством супергероев капитан Роджерс хочет быстро принять лучшее из возможных решений. К счастью для капитана Роджерса, Дуэйн работает на базе Мстителей. Дуэйн — специалист по данным, и у Дуэйна есть несколько наборов данных, с которыми он может работать:

  1. Набор данных о супергероях: https://www.kaggle.com/datasets/claudiodavi/superhero-set
  2. Социальная сеть вселенной Marvel: https://www.kaggle.com/datasets/csanhueza/the-marvel-universe-social-network
  3. Статистика и способности персонажей комиксов Marvel: https://www.kaggle.com/datasets/spatika/marvel-comics-characters-stats-and-powers

Во-первых, Дуэйн загружает свои наборы данных с пандами в python:

import pandas as pd
superheropowers=pd.read_csv('superheroes_power_matrix.csv')
heronet=pd.read_csv('hero-network.csv')
alignment=pd.read_csv('marvel_characters_info.csv')

Давайте посмотрим, какой тип данных находится в каждом:

Силы супергероев — это логическая матрица с метками «Истина» или «Ложь» для определенных способностей героя.

Heronet — это крайний список героев, связанных с другими на основе их совместного появления в комиксах.

Добавлен набор данных Alignment, чтобы мы могли соответствующим образом классифицировать наших героев и злодеев. В то время как в комиксах мировоззрение несколько произвольно, Дуэйн решил не рисковать, вызвав «плохого парня» вместо нашего прикованного к постели героя.

Дуэйн замечает, что необходимо выполнить некоторую очистку данных, прежде чем эти данные можно будет использовать. Простая очистка и слияние наших разных фреймов данных должны помочь.

#construct a small dataframe with just hero name and alignment and capitalize
alignment=alignment[['Name', 'Alignment']]
alignment['Name']=[x.upper() for x in alignment['Name']]
superheropowers['Name']=[x.upper() for x in superheropowers['Name']]

#clean the heronet dataframe
heronet['hero1'] = heronet['hero1'].str.split('/').str[0]
heronet['hero2'] = heronet['hero2'].str.split('/').str[0]

#get a Marvel only dataset. we can do this because our hero net is only
#marvel characters 
hero1=set(heronet['hero1'])
hero2=set(heronet['hero2'])
heroset=list(hero1.union(hero2))
marvelchars=superheropowers[superheropowers['Name'].isin(heroset)]

#merge our dataframes and set our alighment to good guys
marvelchars=marvelchars.reset_index(drop=True)
marvelheros=marvelchars.merge(alignment, how='inner', left_on='Name', right_on='Name')
goodguys=marvelheros[marvelheros['Alignment']=='good']
goodguys=goodguys.drop_duplicates()
goodguys=goodguys.reset_index(drop=True)

После запуска приведенного выше кода Дуэйн обнаруживает, что у него есть 149 «хороших» супергероев Marvel для работы (за вычетом тех, кто уже есть в команде). Не много, но полезно.

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

from sklearn.metrics.pairwise import cosine_similarity
#we drop unnecessary columns for training purposes and reset our index
trainer=goodguys.drop(['Name', 'Alignment'], axis=1)
trainer=trainer.reset_index(drop=True)
cosine_sim = cosine_similarity(trainer)

Однако Дуэйн не просто хочет получить похожего героя, который может заполнить пробел. Это чувствительно ко времени! Мстителям нужен герой, с которым один из нынешних героев может быстро связаться, и тот, кто работал с некоторыми из них, прежде чем разрешить более легкое сотрудничество. Дуэйн решает использовать социальную сеть Marvel Character, чтобы помочь ему принять решение. Он сделает это с помощью пакета networkx в python.

import networkx as nx
#we are only concerned with the network of our avengers team so we center on their social networks
#hawkeye is listed as hawk in this dataset
avengers=['captain america', 'ant-man', 'iron man', 'black widow', 'thor', 'spider-man', 'hulk', 'hawk', 'wasp', 'Wolverine']
avengers=[x.upper() for x in avengers]
avengernet = heronet[(heronet['hero1'].isin(avengers)) | (heronet['hero2'].isin(avengers))]
G=nx.from_pandas_edgelist(avengernet, source='hero1', target='hero2')

Теперь у Дуэйна есть сеть героев, связанных с нашими Мстителями, и модель для расчета сходства между персонажами. Сладкий! Теперь ему просто нужно собрать их вместе с небольшим преобразованием данных.

Сначала он получает оценки сходства для потенциальных замен больного Питера Паркера.

#we get our index for SPIDER-MAN
index1=goodguys.index[goodguys['Name']=='SPIDER-MAN'].tolist()[0]
#we calculate the cosine similarities of other heroes with SPIDER-MAN and sort
similar_char = list(enumerate(cosine_sim[index1]))
similar_char.sort(key=lambda x:x[1], reverse= True)
#we don't need SPIDER-MAN to compare with himself so we skip him.
sorted_score = similar_char[1:]

#Now we construct a dataframe with the heroes and their similarity scores
potentials=[]
score=[]
i = 0
for item in sorted_score:
  cosscore=item[1]
  char_name=goodguys[goodguys.index==item[0]]['Name'].values[0]
  potentials.append(char_name)
  score.append(cosscore)
#we will only center on the 10 highest similarity scores
  i = i+1
  if i > 10:
      break
dfconstruct=pd.DataFrame({'potential name':potentials, 'cos_score':score})

Дуэйн получает некоторые интересные результаты из своего косинусного подобия. Затем Дуэйн получает оценки центральности близости для этих потенциальных замен и создает совокупную оценку центральности и сходства, чтобы определить замену Человека-паука.

#calculate centrality and put into a dataframe
centralities1=nx.closeness_centrality(G)
centdf=pd.DataFrame(centralities1.items(), columns=['Name', 'Closeness_Centrality'])
#ensure the recommendations from centralities are in our list of similar heroes
recommended1=centdf[centdf['Name'].isin(potentials)]
#we also want to exclude our avengers already on the team
recommended1=recommended1[~recommended1['Name'].isin(avengers)]
#construct a sorted dataframe and join it onto our similarities dataframe
sortedrecs=recommended1.sort_values(by='Closeness_Centrality', ascending=False)
recommendationdf=sortedrecs.merge(dfconstruct, how='inner', left_on='Name', right_on='potential name')
#create an aggregate score and drop unnecessary columns
recommendationdf['comboscore']=recommendationdf['Closeness_Centrality']*recommendationdf['cos_score']
recommendationdf=recommendationdf.sort_values(by='comboscore', ascending=False)
recommendationdf=recommendationdf[['Name', 'Closeness_Centrality', 'cos_score', 'comboscore']]

Бам! Дуэйн входит в десятку рекомендуемых героев!

Похоже, что Beast станет первым звонком Стива Роджерса!

Примечания

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

Если вам понравилось, поставьте лайк и подпишитесь, а также посетите мой GitHub, где будет доступен этот код! https://github.com/noahmott