用 ClickHouse 玩轉向量搜索
ChatGPT 火了,順帶着把向量數據庫也帶火了。各種向量數據庫如雨後春筍般的出現在了衆人眼前。
那 ClickHouse 能玩向量搜索嗎?
答案:那必須是可以啦, ClickHouse 可是能把數組玩出花的存在啊!!!
在 ClickHouse 中,可以使用浮點類型的數組保存向量
Array(Float32)
然後用內置的距離函數,得出兩組向量之間的相似度.
目前距離函數支持主流的餘弦相似度和歐幾里得距離:
#餘弦相似度
cosineDistance(vector1, vector2)
#歐幾里得距離
L2Distance(vector1, vector2)
接下來我用一個簡單示例演示:
- 準備一些測試文檔數據,利用 azure openai 的接口幫我們 Embedding 成向量
input_data = [
"ClickHouse是一款高性能的列式數據庫,特別適合處理海量數據。",
"它支持實時分析和查詢,可以在不影響性能的情況下輕鬆搞定大規模數據。",
"ClickHouse的可擴展性強,可以處理PB級別的數據,而且性能表現非常優異。",
"數據存儲和壓縮方面也非常高效,可支持多種數據格式。",
"ClickHouse提供完整的SQL支持,方便用戶進行數據查詢和分析。",
"它可以與各種數據源集成,包括Hadoop、Kafka、Elasticsearch等等。",
"ClickHouse還支持自定義指標和聚合函數,可以根據用戶需求進行定製化操作。",
"作爲一款開源免費的數據庫,ClickHouse的社區非常活躍,擁有強大的生態系統。",
"它還提供了豐富的工具和插件,包括可視化工具、ETL工具等等,方便用戶進行數據分析和處理。",
"總的來說,ClickHouse是一款非常優秀的數據庫產品,可以滿足各種數據處理和分析的需求。"
]
embeddings_data = []
for i in range(len(input_data)):
data = openai.Embedding.create(input=input_data[i], engine=embedding_model).data[0]["embedding"]
embeddings_data.append([i, input_data[i], data])
# print(data)
- 建一張 MergeTree,用浮點數組保存向量數據
client = clickhouse_connect.get_client(host='ch9.nauu.com', username='default')
client.command('DROP TABLE IF EXISTS test_embedding_ch')
client.command(
"""
CREATE TABLE test_embedding_ch
(
`key` UInt32,
`content`String,
`text_embedding` Array(Float32)
)
ENGINE = MergeTree
ORDER BY key
""")
result = client.query('DESCRIBE TABLE test_embedding_ch')
print (result.column_names[0:2])
print (result.result_columns[0:2])
client.insert('test_embedding_ch', embeddings_data, column_names=['key', 'content','text_embedding'])
- 將用戶提問同樣向量化
q = ""
while q != 'quit':
q = input("請提問: ")
if q!="quit":
# print("q: "+q)
data = openai.Embedding.create(input=q, engine=embedding_model).data[0]["embedding"]
result = query(data)
for i in range(len(result.result_rows)):
print("no:{} {} score:{} ".format(result.result_rows[i][0],result.result_rows[i][1],result.result_rows[i][2]))
4. 利用距離函數,輕鬆通過 SQL 實現向量的相似度查詢
def query(d):
sql = "SELECT key,content,L2Distance(text_embedding,{embeddings}) AS score FROM test_embedding_ch ORDER BY score ASC LIMIT 5".format(embeddings=d)
print(sql)
result = client.query(sql)
return result
最終效果:
快去試一試吧 :)
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/k594BaTXMoYcnmvpzO3xDw