知识图谱操作(二)Neo4j -设计基础SQL(CYPHER查询)
·
Expand:将一个实体扩张至该节点所有相关的实体集
def expand(self, entity_name):
query = (
"MATCH (a:Entity {name: $entity_name})-[r]->(b:Entity) "
"RETURN b AS child,r.type AS relation_type"
)
with self.driver.session() as session:
result = session.run(query, entity_name=entity_name)
linked_nodes = []
for record in result:
if record["child"].id is not None and record["child"].id != '':
linked_nodes.append(
{
"id": record["child"].id,
"name": record["child"]["name"],
"type": record["relation_type"],
}
)
return linked_nodes
Describe:返回该实体的所有描述(Description)
def describe(self, entity_name):
query = (
"MATCH (a:Entity {name: $entity_name})-[r]->(b:Description) "
"RETURN b AS des,r.type AS relation_type"
)
with self.driver.session() as session:
result = session.run(query, entity_name=entity_name)
types = []
descriptions = []
for record in result:
now_type = record["relation_type"]
if now_type not in types:
matched = []
types.append(now_type)
for flag in result:
if flag["relation_type"] == now_type:
matched.append(
{"name": flag["des"]["name"],
"page": flag["des"]["page_num"]
})
descriptions.append(
{
"type": now_type,
"data": matched
}
)
return descriptions
Struct:生长基于指定实体在知识图谱中的x层y节点关键子图
def struct(self, entity_name):
query = (
"""
MATCH (e:Entity {name: $entity_name})-[r1:RELATION]->(first_level)
WITH e, r1, first_level
MATCH (first_level)-[r2:RELATION]->(second_level)
WITH e, r1, first_level, r2, second_level
ORDER BY first_level, second_level
WITH e, r1, first_level, collect(second_level)[..2] AS limited_second_level_nodes, collect(r2)[..2] AS limited_second_level_rels
UNWIND range(0, size(limited_second_level_nodes)-1) AS idx
WITH e, r1, first_level, limited_second_level_nodes[idx] AS second_level, limited_second_level_rels[idx] AS r2
WITH e, r1, first_level, r2, second_level
LIMIT 20
RETURN e, r1, first_level, r2, second_level,
'e1: ' + id(e) + ', e2: ' + id(first_level) + ', e3: ' + id(second_level) +
', r1: ' + type(r2) + ' (source: ' + id(startNode(r2)) + ', target: ' + id(endNode(r2)) + ')' AS path
"""
)
with self.driver.session() as session:
result = session.run(query, entity_name=entity_name)
data = []
links = []
vertex_ids = set()
edge_ids = set()
for record in result:
node = record["e"]
first_level = record["first_level"]
second_level = record["second_level"]
r1 = record["r1"]
r2 = record["r2"]
if node.id not in vertex_ids:
data.append({
"id": node.id,
"name": node["name"],
"des": node["name"],
"symbolSize": 50,
"category": 0,
})
vertex_ids.add(node.id)
if first_level.id not in vertex_ids:
data.append({
"id": first_level.id,
"name": first_level["name"],
"des": first_level["name"],
"symbolSize": 50,
"category": 1,
})
vertex_ids.add(first_level.id)
if second_level.id not in vertex_ids:
data.append({
"id": second_level.id,
"name": second_level["name"],
"des": second_level["name"],
"symbolSize": 50,
"category": 2,
})
vertex_ids.add(second_level.id)
if r1.id not in edge_ids:
links.append({
"name": r1.type,
"des": r1["type"],
"source": r1.start_node.id,
"target": r1.end_node.id,
})
edge_ids.add(r1.id)
if r2.id not in edge_ids:
links.append({
"name": r2.type,
"des": r2["type"],
"source": r2.start_node.id,
"target": r2.end_node.id,
})
edge_ids.add(r2.id)
return data, links
def exercise(self, entity_name, questions=None):
if questions is None:
questions = []
query = (
"""
MATCH (e:Entity {name: $entity_name})-[r1:Exercise]->(q)
WHERE q.answer_text IS NOT NULL AND q.answer_text <> ''
RETURN q AS question
LIMIT 20
"""
)
with self.driver.session() as session:
result = session.run(query, entity_name=entity_name)
for record in result:
text = record['question']['problem_text']
answer = record['question']['answer_text']
id = record['question'].id
type = record['question']['problem_type']
questions.append({
"text": text,
"answer": answer,
"type": type,
"id": id,
})
if len(questions) < 3:
expands = self.expand(entity_name)
for expand in expands:
self.exercise(expand["name"], questions)
return questions
向量化计划通过Faiss向量数据库实现.
具体路线流程如下图:
import faiss
import numpy as np
from sentence_transformers import SentenceTransformer
def read_text_file(file_path):
with open(file_path, 'r', encoding='utf-8') as file:
lines = file.readlines()
return [line.strip() for line in lines if line.strip()]
def text_to_vectors(texts, model_name='all-MiniLM-L6-v2'):
model = SentenceTransformer(model_name)
vectors = model.encode(texts, show_progress_bar=True)
return vectors
def build_faiss_index(vectors, index_path='faiss_index'):
d = vectors.shape[1]
index = faiss.IndexFlatL2(d)
index.add(vectors)
faiss.write_index(index, index_path)
def search_faiss_index(query_vector, index_path='faiss_index', top_k=5):
index = faiss.read_index(index_path)
distances, indices = index.search(query_vector, top_k)
return distances, indices
def main():
txt_file_path = 'ComputerNetwork.txt'
texts = read_text_file(txt_file_path)
vectors = text_to_vectors(texts)
build_faiss_index(vectors)
query_text = "查询文本"
query_vector = text_to_vectors([query_text])
distances, indices = search_faiss_index(query_vector)
print("查询结果:")
for i, index in enumerate(indices[0]):
print(f"文本: {texts[index]}, 距离: {distances[0][i]}")
if __name__ == "__main__":
main()
文本嵌入后,考虑对嵌入的向量归入Faiss库
归入Faiss向量库
创建L2距离的Faiss索引
dimension = embedding_out_dim # 经过Embedding后的向量维度
index = faiss.IndexFlatL2(dimension) # 使用L2距离的平面索引
使用Faiss索引查找5个最近邻向量
query_vector = vector
k = 5 # 查找前5个最近邻
distances, indices = index.search(query_vector, k)
print("最近邻索引:", indices)
print("最近邻距离:", distances)
更多推荐

所有评论(0)