Neo4j は、オープンソースの高性能グラフ データベースです。複雑な関係を持つ大規模なデータを保存、取得、処理するように設計されています。従来のリレーショナル データベースとは異なり、Neo4j はグラフ構造を使用してデータを表します。ノードはエンティティを表し、エッジはエンティティ間の関係を表します。これにより、Neo4j は、関係性の高いデータを処理する際に非常に強力かつ効率的になります。
Neo4j の主な機能の一部を次に示します。
-
グラフ データベース: Neo4j は、データを保存および管理するためのグラフ モデルを提供する、ネイティブの完全なグラフ ベースのデータベースです。これにより、ソーシャル ネットワーク、推奨システム、サイバーセキュリティなどの複雑なデータ関係を簡単に処理できるようになります。
-
柔軟なデータ モデル: Neo4j のデータ モデルは非常に柔軟で、さまざまな種類のエンティティや関係を簡単に表現できます。独自のノード ラベルとエッジ タイプを定義し、それらにプロパティを追加して、データ構造をより適切に表現できます。
-
高性能: Neo4j は、効率的なグラフ走査アルゴリズムとインデックス作成メカニズムを使用することにより、優れたパフォーマンスを実現します。複雑なグラフ クエリを迅速に実行でき、深いトラバースと高速な関係ナビゲーションをサポートします。
-
ネイティブ クエリ言語: Neo4j は、Cypher と呼ばれるネイティブ クエリ言語を使用して、グラフ データの操作とクエリを実行します。Cypher には、ノードとエッジのマッチング、パス トラバーサル、集計操作など、さまざまなグラフ クエリ パターンを簡単に表現できる直感的な構文があります。
-
ACID トランザクションのサポート: Neo4j は、アトミック性、一貫性、分離性、耐久性 (ACID) トランザクション機能をサポートします。これにより、信頼性の高い永続化メカニズムを提供しながら、データの整合性と一貫性が確保されます。
-
エコシステムとツールのサポート: Neo4j には、視覚化ツール、ETL ツール、ドライバー、統合ライブラリなどを含む、豊富なエコシステムとツールのサポートがあります。これらのツールを使用すると、開発者やデータ アナリストが Neo4j データベースを簡単に使用および操作できるようになります。
以下に示すように、 Neo4j 公式 Web サイトはここにあります。
必要に応じてダウンロード、インストールして使用できます。
インストール完了後の起動時のスクリーンショットは以下のとおりです。
今回インストールしたのはバージョン1.5.8です。
Neo4jのデータベースには学生時代に接しており、インストールして簡単に練習しただけで、その後テーマの方向性が変わったため触れることはなかったのですが、たまたまこのグラフデータベースを目にしました。最近、週末に何もすることがなかったときにまたやってみました。内容、考えてみてください。
それでは、実践的な開発プロジェクトを始めましょう、ここでは主に、前回のプロジェクトで収集した豚関連繁殖病データセットをベンチマークとして使用し、ナレッジグラフに基づく質疑応答システムを構築します。
ナレッジ グラフは、構造化された知識を整理、表現、保存するために使用されるグラフィカルな知識ベースです。これは、現実世界の実体、概念、およびそれらの間の関係をグラフィック構造として表し、知識をより深く理解し、分析するのに役立ちます。
ナレッジ グラフは通常、次の 3 つの主要コンポーネントで構成されます。
-
エンティティ: エンティティは、人、場所、アイテム、イベントなど、現実世界の特定のものを表します。各エンティティには、一意の識別子と関連する属性情報があります。
-
属性: 属性は、エンティティの特性とプロパティを記述します。たとえば、人物エンティティには名前、年齢、性別などの属性を含めることができます。
-
関係: 関係は、エンティティ間の接続と関連性を表します。これらは、「で動作している」、「に位置している」、「サブセット/スーパーセットである」など、エンティティ間の意味論的な関係を記述します。
ナレッジ グラフの利点は、複雑な関係をキャプチャして表現し、ナレッジを保存およびクエリするための構造化された方法を提供できることです。インテリジェントな推奨システム、質問と回答のシステム、セマンティック検索エンジン、その他のアプリケーションの構築に使用できます。ナレッジ グラフを使用すると、より高度なデータ分析、意味論的推論、情報抽出を実行できます。
たとえば、百科事典を例に挙げると、ナレッジ グラフでは、さまざまなトピック、登場人物、イベントなどのエンティティをグラフィック構造に編成し、関係を使用してそれらをリンクできます。このようにして、特定の人物の家族を見つけたり、出来事の歴史的背景を理解したりするなど、関連する知識を簡単に閲覧して発見することができます。
まず、以下に示すデータセットを簡単に見てみましょう。
"猪附红细胞体病": {
"name": "猪附红细胞体病",
"desc": "由附红细胞体寄生于猪的红细胞表面或游离于血浆、组织液及脑脊液中引起的一种人畜共患病,猪发病时,皮肤发红,故又称“猪红皮病”。",
"cause": "附红细胞体病是由多种原因引发的疾病,只有在应激和肌体抗病力降低的情况下才会诱发此病。如饲养管理不良、天气突变、突然换料、更换圈舍、密度过大等应激因素或患猪瘟、猪蓝耳病、传染性胸膜肺炎、猪链球菌病、副猪嗜血杆菌病等慢性病时,最易并发和继发附红细胞体病。",
"prevent": "预防本病的发生应加强猪场的卫生防疫,消除各种应激因素。在温热季节应定期喷洒杀虫剂,以杀灭蚊、蝇、蜱、牛虻、体虱、跳蚤等吸血昆虫,消除传染媒介。发病猪只要进行及时有效的治疗。对无治疗价值的病猪应及时进行淘汰,以清除传染源。阳性猪群,饲料中可添加强力霉素等,以消除隐性感染。购入猪只要进行血液检查,防止引入病猪或隐性感染猪。本病流行季节给予预防用药,可在饲料中添加上强力霉素或金霉素添加剂,或每公斤饲料添加90毫克阿散酸,连续使用30天,或每月使用7-10天。 防重于治是养猪的最后方法。",
"cure_lasttime": "一般3-14天。",
"cure_way": "⑴血虫净(或三氮眯、贝尼尔) 每公斤体重用5mg-10mg,用生理盐水稀释成5%溶液,分点肌肉注射,1天1次,连用3天。⑵咪唑苯脲每公斤体重用1mg-3mg,1天1次,连用2天-3天。⑶四环素、土霉素(每公斤体重10mg)和金霉素(每公斤体重15mg)口服或肌注或静注,连用7天-14天。⑷新胂凡纳明按每公斤体重10mg-15mg静脉注射,一般3天后症状可消失。",
"easy_get": "不同年龄的猪均有易感性,通常发生在哺乳猪、怀孕的母猪以及受到高度应激的肥育猪身上。",
"symptom": [
"体温升高为40.5℃~42℃",
"皮肤发红,指压退色",
"精神不振",
"食欲减退",
"怕冷聚堆",
"咳嗽",
"流鼻涕",
"呼吸困难",
"尿液淡黄",
"发病中期,病猪行走时后躯摇晃,喜卧厌立,便秘或拉稀,精神沉郁,呼吸困难",
"血液稀薄,色淡,往往随注射针孔流血不止",
"皮毛枯燥",
"背腹部毛色铁锈色",
"皮肤苍白",
"耳内侧、背侧、颈背部、腹侧部皮肤出现暗红色出血点,可视黏膜轻度肿胀,初期潮红,后期苍白",
"轻度黄疸",
"尿液淡黄、淡红或呈红褐色,卧地不起",
"后期,病猪耳朵变蓝色、坏死,排血便和血红蛋白尿,最后四肢呈游泳状划动,呼吸困难,衰竭死亡"
],
"recommand_drug": [
"抗生素",
"磺胺类",
"砷制剂",
"血虫净",
"三氮眯",
"贝尼尔",
"咪唑苯脲",
"四环素",
"土霉素",
"金霉素",
"新胂凡纳明"
],
"checks": [
"猪附红细胞体病的发热、贫血、黄疸等症状具有一定的诊断意义,其他临床症状,如食欲减退、呼吸急迫、心悸亢进等非特征性症状在本病的诊断上意义不大。",
"猪患附红细胞体病后全身各部均无特征性的病理变化,一般无需作病理学检查。因此,对本病确诊,必须先进行实验室检查。",
"实验室诊断的方法很多,如可用间接红细胞凝集试验、补体结合试验、相差显微镜观察和染色血液涂片观察等。",
"间接红细胞凝集试验和补体结合试验反应敏感、检出率高,但试验条件要求高,需要时间较长。",
"相差显微镜观察和染色血液涂片观察以及鲜血直接压片,所需设备和药品较少,且操作简单、快捷,检出率也较高,一般在半个小时内即可作出确切诊断。"
],
"departments": [
"寄生虫病"
],
"methods": [
"温热季节定期喷洒杀虫剂",
"及时治疗发病猪只,无治疗价值的猪只应及时淘汰",
"阳性猪群,饲料中可添加强力霉素等,以消除隐性感染。",
"购入猪只要进行血液检查,防止引入病猪或隐性感染猪。"
],
"acompany_with": [
"链球菌病",
"猪水肿病",
"仔猪副伤寒",
"猪肺疫",
"猪丹毒",
"猪瘟",
"弓形虫病"
]
}
上記は 1 つの疾患の関連コンテンツの詳細ですが、非常に多くのコンテンツが含まれていることがわかります。
以下に、いくつかの一般的な豚の病気を紹介します。
{
"猪附红细胞体病": {
"疾病所属类别": "寄生虫病",
"疾病诊断要点": "相差显微镜观察和染色血液涂片观察以及鲜血直接压片,所需设备和药品较少,且操作简单、快捷,检出率也较高,一般在半个小时内即可作出确切诊断。",
"疾病推荐药物": "新胂凡纳明",
"疾病预防措施": "购入猪只要进行血液检查,防止引入病猪或隐性感染猪。"
},
"副猪嗜血杆菌病": {
"疾病所属类别": "细菌性传染病",
"疾病诊断要点": "该病易与传染性胸膜肺炎相混淆,但该病引起的病变多数为脑膜炎,关节炎和四肢跛行等,而传染性胸膜性肺炎较少见。",
"疾病推荐药物": "阿莫西林",
"疾病预防措施": "疫苗免疫"
},
"猪支原体肺炎": {
"疾病所属类别": "传染病",
"疾病诊断要点": "其他内脏一般无明显变化。",
"疾病推荐药物": "中药方剂 (苏子、杏仁、款冬花、桔梗、甘草、陈皮、鱼腥草等)",
"疾病预防措施": "加强消毒,保持栏舍清洁、干燥通风。"
},
"猪圆环病毒病": {
"疾病所属类别": "病毒性传染病",
"疾病诊断要点": "血清学检查:是生前诊断的一种有效手段。诊断本病的方法有:间接免疫荧光法(IIF),免疫过氧化物单层培养法,ELISA方法,聚合酶链式反应(PCR)方法,核酸探针杂交及原位杂交试验(ISH)等方法。",
"疾病推荐药物": "选用新型的抗病毒剂如干扰素、白细胞介导素、免疫球蛋白、转移因子等进行治疗,同时配合中草药抗病毒制剂,会取得明显治疗效果。",
"疾病预防措施": "加强饲养管理"
},
"猪链球菌病": {
"疾病所属类别": "人畜共患病",
"疾病诊断要点": "药敏试验",
"疾病推荐药物": "抗生素",
"疾病预防措施": "加强饲养管理"
},
"猪伪狂犬病": {
"疾病所属类别": "急性传染病",
"疾病诊断要点": "血清学诊断可直接用免疫荧光法、间接血凝抑制试验、琼脂扩散试验、补体结合试验、酶联免疫吸附试验、乳胶凝集试验。",
"疾病推荐药物": "猪血清抗体",
"疾病预防措施": "同时,还要严格控制犬、猫、鸟类和其他禽类进入猪场,严格控制人员来往,并做好消毒工作及血清学监测等,这样对本病的防制也可起到积极的推动作用。"
}
次に、データのロード、解析、保存の操作を完了するプログラムを開発する必要があります。ここでは、pigMedicalGraph クラスが次のように定義されています。
#!usr/bin/env python
# encoding:utf-8
from __future__ import division
"""
功能: 猪类疾病知识图谱构建
"""
import os
import json
from py2neo import Graph,Node
class pigMedicalGraph:
def __init__(self):
def read_nodes(self):
def create_node(self, label, nodes):
def create_diseases_nodes(self, disease_infos):
def create_graphnodes(self):
def create_graphrels(self):
def create_relationship(self, start_node, end_node, edges, rel_type, rel_name):
1 つ目は、以下に示すように、ローカル データをロードして解析することです。
count = 0
with open(self.data_path, encoding="utf-8") as f:
data_dict = json.load(f)
for one_key in data_dict:
data_json = data_dict[one_key]
disease_dict = {}
count += 1
print(count)
disease = data_json["name"]
print(disease)
disease_dict["name"] = disease
if type(disease) == list:
diseases += disease
disease = disease[0]
else:
diseases.append(disease)
disease_dict["desc"] = ""
disease_dict["cause"] = ""
disease_dict["prevent"] = ""
disease_dict["cure_lasttime"] = ""
disease_dict["cure_way"] = ""
disease_dict["symptom"] = ""
disease_dict["recommand_drug"] = ""
print("59")
if "symptom" in data_json:
symptoms += data_json["symptom"]
for symptom in data_json["symptom"]:
has_symptom.append([disease, symptom])
if "checks" in data_json:
checks += data_json["checks"]
for check in data_json["checks"]:
need_check.append([disease, check])
if "departments" in data_json:
departments += data_json["departments"]
for department in data_json["departments"]:
belongs_to.append([disease, department])
if "methods" in data_json:
methods += data_json["methods"]
for method in data_json["methods"]:
recommand_method.append([disease, method])
if "desc" in data_json:
disease_dict["desc"] = data_json["desc"]
if "prevent" in data_json:
disease_dict["prevent"] = data_json["prevent"]
if "cause" in data_json:
disease_dict["cause"] = data_json["cause"]
if "easy_get" in data_json:
disease_dict["easy_get"] = data_json["easy_get"]
if "cure_way" in data_json:
disease_dict["cure_way"] = data_json["cure_way"]
if "cure_lasttime" in data_json:
disease_dict["cure_lasttime"] = data_json["cure_lasttime"]
if "recommand_drug" in data_json:
recommand_drug1 = data_json["recommand_drug"]
drugs += recommand_drug1
for drug in recommand_drug1:
recommand_drug.append([disease, drug])
disease_infos.append(disease_dict)
次のステップでは、ナレッジ グラフにノードを作成します。実装は次のとおりです。
def create_node(self, label, nodes):
"""
创建节点
"""
count = 0
for node_name in nodes:
node = Node(label, name=node_name)
self.g.create(node)
count += 1
print(count, len(nodes))
return
次に、以下に示すように、ナレッジ グラフに疾患ノードの作成を実装します。
def create_diseases_nodes(self, disease_infos):
"""
创建知识图谱中疾病的节点
"""
count = 0
for disease_dict in disease_infos:
print(disease_dict)
node = Node(
"Disease",
name=disease_dict["name"],
desc=disease_dict["desc"],
cause=disease_dict["cause"],
prevent=disease_dict["prevent"],
cure_lasttime=disease_dict["cure_lasttime"],
cure_way=disease_dict["cure_way"],
easy_get=disease_dict["easy_get"],
recommand_drug=disease_dict["recommand_drug"],
symptom=disease_dict["symptom"],
)
print("132")
self.g.create(node)
count += 1
print(count)
return
次のステップでは、ナレッジ グラフ エンティティ ノード タイプ スキーマを作成します。コア実装は次のとおりです。
self.create_diseases_nodes(disease_infos)
self.create_node("checks", checks)
self.create_node("departments", departments)
self.create_node("diseases", diseases)
self.create_node("drugs", drugs)
self.create_node("methods", methods)
self.create_node("symptoms", symptoms)
次に、以下に示すように、エンティティ関連付けエッジを作成します。
def create_relationship(self, start_node, end_node, edges, rel_type, rel_name):
"""
创建实体关联边
"""
count = 0
# 去重处理
set_edges = []
for edge in edges:
set_edges.append("".join(edge))
all = len(set(set_edges))
for edge in set(set_edges):
edge = edge.split("")
p = edge[0]
q = edge[1]
query = (
"match(p:%s),(q:%s) where p.name='%s' and q.name='%s' create (p)-[rel:%s{name:'%s'}]->(q)"
% (start_node, end_node, p, q, rel_type, rel_name)
)
try:
self.g.run(query)
count += 1
print(rel_type, count, all)
except Exception as e:
print(e)
return
最後に、以下に示すように、エンティティ関係エッジを作成します。
self.create_relationship("diseases", "departments", belongs_to, "belongs_to", "属于")
self.create_relationship("diseases", "checks", need_check, "need_check", "疾病诊断结果")
self.create_relationship(
"diseases", "drugs", recommand_drug, "recommand_drug", "疾病推荐药品"
)
self.create_relationship(
"diseases", "methods", recommand_method, "recommand_method", "疾病预防措施"
)
self.create_relationship("diseases", "symptoms", has_symptom, "has_symptom", "疾病症状")
self.create_relationship(
"diseases", "diseases", acompany_with_, "acompany_with_", "疾病并发疾病"
)
この時点で、データの分析とロード操作は基本的に完了します。
以下に示すように、neo4j データベース デスクトップで直接開いて表示できます。
http://localhost:7474/browser/を直接コピーすることもできます。
以下に示すように、ブラウザで開くだけです。
明らかにブラウザ側の操作や可視化がスムーズになったように感じます。
ここでは、ナレッジ グラフの機能を直接使用して、ナレッジ クエリに答えることができます。簡単な実装は次のとおりです。
class ChatRobot:
def __init__(self):
self.classifier = QuestionClassifier()
self.parser = QuestionPaser()
self.searcher = AnswerSearcher()
def chat_main(self, sent):
answer = "尊敬的用户您好,我是AI医药智能助理,希望可以帮到您!"
res_classify = self.classifier.classify(sent)
if not res_classify:
return answer
res_sql = self.parser.parser_main(res_classify)
print("res_sql: ", res_sql)
final_answers = self.searcher.search_main(res_sql)
if not final_answers:
return answer
else:
return "\n".join(final_answers)
if __name__ == "__main__":
handler = ChatRobot()
while True:
question = input("user:")
answer = handler.chat_main(question)
print("AI:", answer)
出力例は次のとおりです。
次に、neo4j データベースの視覚的なプレゼンテーションを簡単に見てみましょう。
各ブロックには、グラフ、テーブル、テキスト、コードの 4 つの表現または保存形式が含まれています。次に、以下に示すように、実際の例で示します。
【グラフ】
【テーブル】
{
"start": {
"identity": 284,
"labels": [
"diseases"
],
"properties": {
"name": "猪圆环病毒病"
},
"elementId": "284"
},
"end": {
"identity": 230,
"labels": [
"departments"
],
"properties": {
"name": "病毒性传染病"
},
"elementId": "230"
},
"segments": [
{
"start": {
"identity": 284,
"labels": [
"diseases"
],
"properties": {
"name": "猪圆环病毒病"
},
"elementId": "284"
},
"relationship": {
"identity": 0,
"start": 284,
"end": 230,
"type": "belongs_to",
"properties": {
"name": "属于"
},
"elementId": "0",
"startNodeElementId": "284",
"endNodeElementId": "230"
},
"end": {
"identity": 230,
"labels": [
"departments"
],
"properties": {
"name": "病毒性传染病"
},
"elementId": "230"
}
}
],
"length": 1.0
}
【文章】
╒════════════════════════════════════════════════════╕
│"p" │
╞════════════════════════════════════════════════════╡
│[{"name":"猪圆环病毒病"},{"name":"属于"},{"name":"病毒性传染病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪圆环病毒病"},{"name":"属于"},{"name":"病毒性传染病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪圆环病毒病"},{"name":"属于"},{"name":"病毒性传染病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪圆环病毒病"},{"name":"属于"},{"name":"病毒性传染病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪圆环病毒病"},{"name":"属于"},{"name":"病毒性传染病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪圆环病毒病"},{"name":"属于"},{"name":"病毒性传染病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪圆环病毒病"},{"name":"属于"},{"name":"病毒性传染病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪圆环病毒病"},{"name":"属于"},{"name":"病毒性传染病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪圆环病毒病"},{"name":"属于"},{"name":"病毒性传染病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪肾虫病"},{"name":"属于"},{"name":"寄生虫病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪肾虫病"},{"name":"属于"},{"name":"寄生虫病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪肾虫病"},{"name":"属于"},{"name":"寄生虫病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪肾虫病"},{"name":"属于"},{"name":"寄生虫病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪肾虫病"},{"name":"属于"},{"name":"寄生虫病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪肾虫病"},{"name":"属于"},{"name":"寄生虫病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪肾虫病"},{"name":"属于"},{"name":"寄生虫病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪肾虫病"},{"name":"属于"},{"name":"寄生虫病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪肾虫病"},{"name":"属于"},{"name":"寄生虫病"}] │
├────────────────────────────────────────────────────┤
│[{"name":"猪流行性腹泻"},{"name":"属于"},{"name":"急性肠道传染病"}]│
├────────────────────────────────────────────────────┤
│[{"name":"猪流行性腹泻"},{"name":"属于"},{"name":"急性肠道传染病"}]│
├────────────────────────────────────────────────────┤
│[{"name":"猪流行性腹泻"},{"name":"属于"},{"name":"急性肠道传染病"}]│
├────────────────────────────────────────────────────┤
│[{"name":"猪流行性腹泻"},{"name":"属于"},{"name":"急性肠道传染病"}]│
├────────────────────────────────────────────────────┤
│[{"name":"猪流行性腹泻"},{"name":"属于"},{"name":"急性肠道传染病"}]│
├────────────────────────────────────────────────────┤
│[{"name":"猪流行性腹泻"},{"name":"属于"},{"name":"急性肠道传染病"}]│
├────────────────────────────────────────────────────┤
│[{"name":"猪流行性腹泻"},{"name":"属于"},{"name":"急性肠道传染病"}]│
└────────────────────────────────────────────────────┘
【コード】
このコードを直接コピーして Neo4j デスクトップで実行すると、ブラウザ ページと同じ結果が得られます。
興味があれば、独自のアプリケーション システムの開発と構築に挑戦することもできます。