设置用于聚类分析的 SQLite 数据库
Setting up SQLite database for cluster analysis
我对数据库完全陌生。我想获得一些关于如何设置和使用 SQLite 数据库进行聚类分析和主题建模任务的建议。
我有一个 2 GB 的文件,其中每一行都是一个 json 对象。这是来自文件的 json 对象示例:
{"body": "Heath Ledger's Joker...", "subreddit_id": "t5_2qh3s", "name": "t1_clpmhgo", "author": "l3thaln3ss", "created_utc": "1414799999", "subreddit": "movies", "parent_id": "t3_2kwdi3", "score": 1, "link_id": "t3_2kwdi3", "sub_type": "links - high"}
我已经像这样创建了一个 SQLite 数据库:
import json
import sqlite3
import sys
def main(argv):
if len(argv) != 2:
sys.exit("Provide a database name.")
dbName = argv[1]
db = sqlite3.connect(dbName)
db.execute('''CREATE TABLE IF NOT EXISTS Comments
(name text primary key,
author text,
body text,
score integer,
parent_id text,
link_id text,
subreddit text,
subreddit_id text,
sub_type text,
created_utc text,
foreign key (parent_id) references Comment(name));''')
db.commit()
db.close()
if __name__ == "__main__":
main(sys.argv)
这是数据库的良好初始设置吗?
我正在像这样填充数据库:
import json
import sqlite3
import sys
def main(argv):
if len(argv) != 2:
sys.exit("Provide a comment file (of json objects) name.")
fname = argv[1]
db = sqlite3.connect("commentDB")
columns = ['name', 'author', 'body', 'score', 'parent_id', 'link_id', 'subreddit', 'subreddit_id', 'sub_type', 'created_utc']
query = "insert or ignore into Comments values (?,?,?,?,?,?,?,?,?,?)"
c = db.cursor()
with open(fname, 'r') as infile:
for comment in infile:
decodedComment = json.loads(comment)
keys = ()
for col in columns:
keys += (decodedComment[col],)
print str(keys)
print
c.execute(query, keys)
c.close()
db.commit()
db.close()
if __name__ == "__main__":
main(sys.argv)
最终,我将根据评论中共享的常用词、用户评论的位置以及通过分析在 subreddit 评论中找到的词获得的主题模型差异来对 subreddit 进行聚类。请注意,我有更多 2 GB 的文件要处理,因此理想情况下,解决方案应该具有相对可扩展性。任何有关如何设置(尤其是通过改进我所写的内容)数据库来完成此类工作的一般性建议将不胜感激。
谢谢!
编辑:删除了有关插入性能的问题。
一些小的改进表明了自己——例如,Comments
的 CREATE TABLE
有一个 references Comment(name)
,我很确定 Comment
是一个拼写错误并且你的意思是Comments
(所以你发布的代码不起作用)。
速度方面,将特别命名的 keys
构建为 tuple
有点浪费——list
会好得多,即替换
keys = ()
for col in columns:
keys += (decodedComment[col],)
和
keys = [decodedComment[col] for col in columns]
为了稍微好一点的性能(可能没有明确记录,但是游标的 execute
方法采用第二个参数,它是一个列表,就像它采用元组一样愉快)。
但总的来说,您的开端不错——在摄取单个 2GB 输入文件后应该没问题。 但是,sqlite,虽然在很多方面都很棒,但并不能很好地扩展到那个大小的倍数——你需要一个 "real" 数据库。我会推荐 PostgreSQL
,但可能 MySQL
(及其变体,例如 MariaDB
)和商业(非开源)产品也不错。
如果 "many more"(2GB 文件)是指数百或数千,甚至 "serious" 专业数据库可能在某个时候开始在接缝处吱吱作响,具体取决于您计划的处理方式向他们投掷; "every word in the comment" 的提及(暗示我想 body
字段需要被处理——词干 &c——进入一个单词集合)在承诺非常繁重的处理即将到来时有点令人担忧。
一旦这成为一个问题,"NoSQL" 产品或 严重 旨在扩大规模的东西,例如 BigQuery,可能值得您花时间。然而,对于小规模的实验,你当然可以从 sqlite 开始,用它来开发你想要的 "clustering" 的算法;然后扩展到 PostgreSQL 或其他任何东西,以检查这些扩展在中等规模上的工作方式;只有在那个时候,如果需要,才需要额外的工作来考虑非关系解决方案,虽然非常强大,但往往需要承诺某些访问模式(关系数据库,您最可能需要的是添加索引,可能更适合更多实验阶段的游戏!)。
传统的 SQL 和 NoSQL 数据库对于此类分析不是特别有用。缺乏允许精细获得的相似性的能力,或根据需要通过聚类算法加速查询的能力。
在大多数实际使用中,您最终会得到这样的工作流程:
- 将数据库中的数据加载到分析应用程序中(通常通过将其转储为某种 CSV 格式)
- 执行分析
- 将结果写回数据库
这不是很漂亮或效率很高,肯定会让您失望。但考虑到即使在商业报价中也缺乏分析灵活性,这就是我们所拥有的。甚至某些商业报价中可用的分析功能(其中一些功能已经足够)也经常以这种方式工作。
在您的特定用例中,可以使用 Lucene 作为后备数据库。如果你有一个聚类算法和实现可以通过Lucene查询加速,那就是。
我对数据库完全陌生。我想获得一些关于如何设置和使用 SQLite 数据库进行聚类分析和主题建模任务的建议。
我有一个 2 GB 的文件,其中每一行都是一个 json 对象。这是来自文件的 json 对象示例:
{"body": "Heath Ledger's Joker...", "subreddit_id": "t5_2qh3s", "name": "t1_clpmhgo", "author": "l3thaln3ss", "created_utc": "1414799999", "subreddit": "movies", "parent_id": "t3_2kwdi3", "score": 1, "link_id": "t3_2kwdi3", "sub_type": "links - high"}
我已经像这样创建了一个 SQLite 数据库:
import json
import sqlite3
import sys
def main(argv):
if len(argv) != 2:
sys.exit("Provide a database name.")
dbName = argv[1]
db = sqlite3.connect(dbName)
db.execute('''CREATE TABLE IF NOT EXISTS Comments
(name text primary key,
author text,
body text,
score integer,
parent_id text,
link_id text,
subreddit text,
subreddit_id text,
sub_type text,
created_utc text,
foreign key (parent_id) references Comment(name));''')
db.commit()
db.close()
if __name__ == "__main__":
main(sys.argv)
这是数据库的良好初始设置吗?
我正在像这样填充数据库:
import json
import sqlite3
import sys
def main(argv):
if len(argv) != 2:
sys.exit("Provide a comment file (of json objects) name.")
fname = argv[1]
db = sqlite3.connect("commentDB")
columns = ['name', 'author', 'body', 'score', 'parent_id', 'link_id', 'subreddit', 'subreddit_id', 'sub_type', 'created_utc']
query = "insert or ignore into Comments values (?,?,?,?,?,?,?,?,?,?)"
c = db.cursor()
with open(fname, 'r') as infile:
for comment in infile:
decodedComment = json.loads(comment)
keys = ()
for col in columns:
keys += (decodedComment[col],)
print str(keys)
print
c.execute(query, keys)
c.close()
db.commit()
db.close()
if __name__ == "__main__":
main(sys.argv)
最终,我将根据评论中共享的常用词、用户评论的位置以及通过分析在 subreddit 评论中找到的词获得的主题模型差异来对 subreddit 进行聚类。请注意,我有更多 2 GB 的文件要处理,因此理想情况下,解决方案应该具有相对可扩展性。任何有关如何设置(尤其是通过改进我所写的内容)数据库来完成此类工作的一般性建议将不胜感激。
谢谢!
编辑:删除了有关插入性能的问题。
一些小的改进表明了自己——例如,Comments
的 CREATE TABLE
有一个 references Comment(name)
,我很确定 Comment
是一个拼写错误并且你的意思是Comments
(所以你发布的代码不起作用)。
速度方面,将特别命名的 keys
构建为 tuple
有点浪费——list
会好得多,即替换
keys = ()
for col in columns:
keys += (decodedComment[col],)
和
keys = [decodedComment[col] for col in columns]
为了稍微好一点的性能(可能没有明确记录,但是游标的 execute
方法采用第二个参数,它是一个列表,就像它采用元组一样愉快)。
但总的来说,您的开端不错——在摄取单个 2GB 输入文件后应该没问题。 但是,sqlite,虽然在很多方面都很棒,但并不能很好地扩展到那个大小的倍数——你需要一个 "real" 数据库。我会推荐 PostgreSQL
,但可能 MySQL
(及其变体,例如 MariaDB
)和商业(非开源)产品也不错。
如果 "many more"(2GB 文件)是指数百或数千,甚至 "serious" 专业数据库可能在某个时候开始在接缝处吱吱作响,具体取决于您计划的处理方式向他们投掷; "every word in the comment" 的提及(暗示我想 body
字段需要被处理——词干 &c——进入一个单词集合)在承诺非常繁重的处理即将到来时有点令人担忧。
一旦这成为一个问题,"NoSQL" 产品或 严重 旨在扩大规模的东西,例如 BigQuery,可能值得您花时间。然而,对于小规模的实验,你当然可以从 sqlite 开始,用它来开发你想要的 "clustering" 的算法;然后扩展到 PostgreSQL 或其他任何东西,以检查这些扩展在中等规模上的工作方式;只有在那个时候,如果需要,才需要额外的工作来考虑非关系解决方案,虽然非常强大,但往往需要承诺某些访问模式(关系数据库,您最可能需要的是添加索引,可能更适合更多实验阶段的游戏!)。
传统的 SQL 和 NoSQL 数据库对于此类分析不是特别有用。缺乏允许精细获得的相似性的能力,或根据需要通过聚类算法加速查询的能力。
在大多数实际使用中,您最终会得到这样的工作流程:
- 将数据库中的数据加载到分析应用程序中(通常通过将其转储为某种 CSV 格式)
- 执行分析
- 将结果写回数据库
这不是很漂亮或效率很高,肯定会让您失望。但考虑到即使在商业报价中也缺乏分析灵活性,这就是我们所拥有的。甚至某些商业报价中可用的分析功能(其中一些功能已经足够)也经常以这种方式工作。
在您的特定用例中,可以使用 Lucene 作为后备数据库。如果你有一个聚类算法和实现可以通过Lucene查询加速,那就是。