Python+Neo 4 jタイムネット構築TOP 100映画知識図譜

14447 ワード

Python+Neo 4 jタイムネット構築TOP 100映画知識図譜
環境
1、Neo 4 j 3.5.6(2019年6月25日)
2、Java 1.8.0_181
3、Annaconda 3
 
一、準備
Neo 4 jインストール:https://blog.csdn.net/gggggao/article/details/93595137
二、ノード関係分析
目的:知識スペクトルの構築を学び、試行し、タイムネットの映画ランキングを選択して試行する.
タイムネットリンク:http://www.mtime.com/top/movie/top100/
Python+Neo4j构建时光网TOP100电影知识图谱_第1张图片
データをneo 4 jにインポートする方法は5つあり、ここでは最後の方法(Neo 4 j-import)を用いてインポートを行う
Python+Neo4j构建时光网TOP100电影知识图谱_第2张图片
Webページのソースコードを表示して分析した後、抽出されたノードとリレーショナル・オブジェクトは次のように決定されます.
  :
    |----  
            |----index:ID
            |----properity: rank, src, name, movie_en, year
            |----label
    |----  
            |----index:ID
            |----properity: director
            |----label
    |----  
            |----index:ID
            |----properity: actor
            |----label
​
​
  :
    |----    
                  |----start:START_ID
                  |----end:END_ID
                  |----properity: relation
                  |----type:TYPE

 
三、映画知識図譜の構築
3.1データの抽出
3.1.1 Webページのダウンロード
本稿ではBeautifulSoupを用いてデータを抽出し,urlのhtmlファイルをまずダウンロードする
def download_page(url):
    headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36'}
    return requests.get(url, headers = headers).content

3.1.2解析ページ
次にダウンロードしたページを解析し、すべての映画情報のリスト、すなわちmovie_を得るlist
def parse_timesmovie_html(html):
    soup = BeautifulSoup(html, features="lxml")     #parse tool: BeautifulSoup
    movie_list = []  # movie_node list: sava all the movie info into the list
    movie_list_soup = soup.find('ul', attrs={'id':'asyncRatingRegion'})     #find body
    #get the data of: rank, movie_name, src, director, movie_actor[]; then save in the
    for movie_li in movie_list_soup.find_all('li'):
        rank = movie_li.find('div', attrs={'class': 'number'}).getText()   #rank of movie
        movie_info = movie_li.find('div', attrs={'class': 'mov_con'})
        movie_temp = movie_info.find('a').getText().split("\xa0")     #name of movie
        movie_name = movie_temp[0]
        year = movie_temp[1].split(" ")[-1].replace('(','').replace(')','')       #release date of movie
        movie_en_name = movie_temp[1][:-7]  #English name of movie
        #print(movie_en_name)
        src = movie_info.find('a')['href']      #src of movie
        # extract the infomation of director&actor
        person_info = movie_info.select('p')
        # director of movie
        director = person_info[0].find('a').string
        # actors of movie
        movie_actor = []
        for act in person_info[1].find_all('a'):
            movie_actor.append(act.string)
​
        movie_info_all = {'rank': rank,
                      'src': src,
                      'movie_name': movie_name,
                      'movie_en_name': movie_en_name,
                      'year': year,
                      'director': director,
                      'actor': movie_actor
                      }
        movie_list.append(movie_info_all)
    return movie_list

3.1.3重複ノードの処理
1人の監督が複数の映画を撮ったり、1人の俳優が複数の映画を演じたりする場合があることを知っています.そのため、重複する可能性のあるノード(監督と俳優)を処理し、ノードの辞書に戻る必要があります.
def handle_entity(person_list):
    director_list, actor_list = [], []
    dir_dic, actor_dic = {}, {}
​
    # separate infomation from person_list
    for elm in person_list:
        director_list.append(elm['director'])
        actor_list.extend(elm['actor'])
    #utilize set() to remove duplicate data from the list[]
    director_set=set(director_list)
    actor_set = set(actor_list)
    #save data to the dictionary
    for index,value in enumerate(director_set):
        dir_dic[index] = value
    for index,value in enumerate(actor_set):
        actor_dic[index] = value
    
    return dir_dic, actor_dic

3.2 csvファイルの生成
3.2.1ノードcsvファイルの生成
上記の分析に基づいて、3つのノードのcsvファイルを生成します.それぞれは
  • 映画:times_movie_entity.csv
  • 監督:times_director_entity.csv
  • 俳優:times_actor_entity.csv

  • コードは以下の通りです
    #times_movie_entity.csv
    def save_movie_entity(movie_entity_list):
        data = pd.DataFrame({'index:ID': [index+1000 for index in range(len(movie_entity_list))],
                             'rank': [movie['rank'] for movie in movie_entity_list],
                             'src': [movie['src'] for movie in movie_entity_list],
                             'name': [movie['movie_name'] for movie in movie_entity_list],
                             'movie_en': [movie['movie_en_name'] for movie in movie_entity_list],
                             'year': [movie['year'] for movie in movie_entity_list],
                             ':LABEL': 'movie'
                             })
        data.to_csv(r'./times_movie_entity.csv', index=False)
    ​
    #times_director_entity.csv
    def save_director_entity(director_entity_dic):
        data = pd.DataFrame({'index:ID': [item+2000 for item in director_entity_dic.keys()],
                             'director': [val for val in director_entity_dic.values()],
                             ':LABEL': 'director'
                             })
        data.to_csv(r'./times_director_entity.csv', index=False)
    ​
    #times_actor_entity.csv
    def save_actor_entity(actor_entity_dic):
        data = pd.DataFrame({'index:ID': [item+3000 for item in actor_entity_dic.keys()],
                             'actor': [val for val in actor_entity_dic.values()],
                             ':LABEL': 'actor'
                             })
        data.to_csv(r'./times_actor_entity.csv', index=False)

    注意:
    3つのノードをうまく区別するために,彼らのindexを処理し,それぞれ1000,2000,3000,すなわち

    ノードドキュメントのフォーマット規則[2]
    生成されたtimes_movie_entity.csvファイルフォーマットを参照
    Python+Neo4j构建时光网TOP100电影知识图谱_第3张图片
    3.2.2関係csvファイルの生成
    3.2.1によって生成されたノードファイルから、それらの3つの関係ファイルを生成し続けます.
  • 映画
  • 映画
  • 俳優-->監督:times_director_actor_relationship.csv

  • コードは以下の通りです
    #times_movie_director_relationship.csv
    def save_movie_director_relationship(movie_list, movie_dic, director_dic):
        data = pd.DataFrame({':START_ID': [list(director_dic.keys())[list(director_dic.values()).index(info['director'])]+2000 for info in movie_list],
                             ':END_ID': [list(movie_dic.keys())[list(movie_dic.values()).index(info['movie_name'])] for info in movie_list],
                             'relation': 'directed',
                             ':TYPE':'directed'
                             })
        data.to_csv(r'./times_movie_director_relationship.csv', index=False)
    ​
    #times_movie_actor_relationship.csv
    def save_movie_actor_relationship(movie_list, movie_dic, actor_dict):
        relation_list = []
        for movie in movie_list:
            for actor_info in movie['actor']:
                actor_index = list(actor_dict.keys())[list(actor_dict.values()).index(actor_info)]
                movie_index = list(movie_dic.keys())[list(movie_dic.values()).index(movie['movie_name'])]
                info = {
                        'actor_index': actor_index,
                        'movie_index': movie_index
                }
                relation_list.append(info)
    ​
        data = pd.DataFrame({':START_ID': [relation['actor_index']+3000 for relation in relation_list],
                             ':END_ID': [relation['movie_index'] for relation in relation_list],
                             'relation': 'acted',
                             ':TYPE': 'acted'
                             })
        data.to_csv(r'./times_movie_actor_relationship.csv', index=False)
    ​
    #times_director_actor_relationship.csv
    def save_director_actor_relationship(movie_list, director_dic, actor_dict):
        relation_list = []
        for movie in movie_list:
            for actor_info in movie['actor']:
                actor_index = list(actor_dict.keys())[list(actor_dict.values()).index(actor_info)]
                dir_index = list(director_dic.keys())[list(director_dic.values()).index(movie['director'])]
                info = {
                    'actor_index': actor_index,
                    'dir_index': dir_index
                }
                relation_list.append(info)
    ​
        data = pd.DataFrame({':START_ID': [relation['dir_index']+2000 for relation in relation_list],
                             ':END_ID': [relation['actor_index']+3000 for relation in relation_list],
                             'relation': 'cooperate',
                             ':TYPE': 'cooperate'
                             })
        data.to_csv(r'./times_director_actor_relationship.csv', index=False)

    生成されたtimes_director_actor_relationship.csvファイルフォーマットを参照
    Python+Neo4j构建时光网TOP100电影知识图谱_第4张图片
    3.3構築スペクトル
    3.3.1準備作業
    インポートする前にneo 4 jサービスを閉じる
  • 管理者としてカードを打つコマンドプロンプト
  • neo 4 j状態を表示し、実行状態であれば
  • を閉じる.
    Python+Neo4j构建时光网TOP100电影知识图谱_第5张图片
    3.3.2スペクトルの生成
    サービスが終了したら、次の図のようにファイルをインポートします.
    Python+Neo4j构建时光网TOP100电影知识图谱_第6张图片
    コマンドは次のとおりです.
    neo4j-admin import --mode=csv --database=movie.db --nodes D:\TestCodes\Python\CrawlerDemos\Neo4jDemo2\times_actor_entity.csv --nodes D:\TestCodes\Python\CrawlerDemos\Neo4jDemo2\times_director_entity.csv --nodes D:\TestCodes\Python\CrawlerDemos\Neo4jDemo2\times_movie_entity.csv --relationships D:\TestCodes\Python\CrawlerDemos\Neo4jDemo2\times_director_actor_relationship.csv --relationships D:\TestCodes\Python\CrawlerDemos\Neo4jDemo2\times_movie_actor_relationship.csv --relationships D:\TestCodes\Python\CrawlerDemos\Neo4jDemo2\times_movie_director_relationship.csv

    インポート成功
    Python+Neo4j构建时光网TOP100电影知识图谱_第7张图片
    四、スペクトル効果の表示
    コマンドが正常に実行された後、neo 4 jデータベースが1つ増えました:movie.dbには、成功したばかりのデータが格納されています.
    Python+Neo4j构建时光网TOP100电影知识图谱_第8张图片
    データをロードできるようにconfでデフォルトのロードを設定するデータベースに進みます
    Python+Neo4j构建时光网TOP100电影知识图谱_第9张图片
    neo 4 jを開く.conf,入力dbms.active_database=movie.db,以下に示す

    最後にCyper文を入力して宮崎駿のスペクトルを調べます.Cyper文は以下のようになります.match m=(:director{director:' '})-[*..1]-() return m
    クエリーの結果を図に示す
    Python+Neo4j构建时光网TOP100电影知识图谱_第10张图片
    五、Github
    コードgithubアドレス:https://github.com/Gao0505/KnowledgeGraph/tree/master/TimesMovieKG
    リファレンス
    [1]  https://blog.csdn.net/BF02jgtRS00XKtCx/article/details/89078048
    [2]  https://blog.csdn.net/sinat_25479505/article/details/80996402 
    [3]  https://blog.csdn.net/Chen18125/article/details/84101458