学习笔记|从0开始学习机器学习·实践|第一节 建立材料数据库01

学习笔记
从0开始学习机器学习·实践
第一节 建立材料数据库01

写在前面的话

       在这个系列的学习笔记中,可以学习从建立材料数据库到解析结构数据,再进行深度学习等完整的机器学习实践。后续,也将陆续撰写其他如计算材料学(VASP,Gromacs,Gaussian等)还有机器学习理论等从0开始系列笔记。

数据库构建

基于统计概率的机器学习,模型离不开大量的数据,在材料学中,这些数据可以是材料结构或是材料的性质。结构决定性质,因此无论是从结构预测出性质,还是从性质反推出结构,都离不开大量的数据。为此,这方面,Materials Project等大量材料数据库被建立。 这里,我们将学习到如何从这些数据库中拉取我们想要获取的材料数据,本文以钙钛矿晶体结构为例,拉取MP数据库中的钙钛矿以及类钙钛矿的材料数据。

在下面的例子中,不仅能够学习到如何构建数据库,还能够学习或巩固python的用法或技巧。

在python中 # 以及”’XXX”’代表了注释,python脚本在编译运行的过程中会自动跳过这些内容,这些内容都是我在学习过程中,帮助我理解和整理思路时的笔记,希望对你也有所帮助。

materials project

导入包以及常量

from mp_api.client import MPRester
import csv
from tqdm import tqdm

#https://next-gen.materialsproject.org/api 注册获得API_KEY
API_KEY = "APIKEY"
OUTPUT_FILE = "perovskite_dataset.csv"

通过API调用MP数据库,拉取Description中含有perovskite 字段的结构。

 mpr.materials.robocrys.search(keywords=[“perovskite”]

这是MPRester包中的固定写法,使用时,仅需要更换关键词即可搜索其他的材料结构。

def get_robo_perovskites(mpr):

    docs = mpr.materials.robocrys.search(keywords=["perovskite"])
   '''
   等价写法:用set可以避免重复统计
   rob_ids()
   for doc in docs:
   rob_ids.add(doc.material_id)
   '''
    return set(doc.material_id for doc in docs)

拉取Tags标签或remarks标记中含有perovskite 字段的结构。

#材料ID,标签,备注信息
def get_tag_perovskites(mpr):
'''
如返回信息:
MPDataDoc<ProvenanceDoc>(
material_id=MPID(mp-1244953),
remarks=['Amorphous'], ->表明非晶体
tags=['Amorphous'],
fields_not_requested=['builder_meta', 'nsites', 'elements', 'nelements', 
'composition', 'composition_reduced', 'formula_pretty', 'formula_anonymous', 
'chemsys', 'volume', 'density', 'density_atomic', 'symmetry', 'deprecated', 
'deprecation_reasons', 'last_updated', 'origins', 'warnings', 'structure', 
'property_name', 'created_at', 'references', 'authors', 'theoretical', 
'database_IDs', 'history']
)]
'''
    docs = mpr.materials.provenance.search(
        fields=["material_id", "tags", "remarks"]
    )

    ids = []
    for doc in docs:
        '''
        取"tags"字段,如果没有,则返回[]
        等价于
        if "tags" in doc:
          tags=doc["tags"]
         else:
         tags=[]
         or []防止key不存在,直接返回[]
        '''
        tags = doc.get("tags", []) or []
        remarks = doc.get("remarks", []) or []
        '''
        tags + remarks:拼接列表
        等价为:
        for x in (tags+remarks):
        #str(x).lower():将xstring化,小写化
          if "perovskite" in str(x).lower():
            ids.append(doc.get("material_id"))
           return False
        '''

        if any("perovskite" in str(x).lower() for x in (tags + remarks)):
            ids.append(doc.get("material_id"))

    return set(ids)

获取结构性质

def fetch_summary(mpr, material_ids):
    results = []

    batch_size = 1000
    ids_list = list(material_ids)
    '''
    range(0,len(ids_list),batch_size):从0开始,ids_list的长度结束,步长为batch_size
    tqdm():进度条工具表
    
    '''
    for i in tqdm(range(0, len(ids_list), batch_size)):
        #batch_ids:每一次取1000个数据
        batch_ids = ids_list[i:i + batch_size]

        docs = mpr.materials.summary.search(
            material_ids=batch_ids,
            fields=[
                "material_id",
                "formula_pretty",#结构表达式
                "energy_above_hull",#凸包能
                "formation_energy_per_atom",#形成能
                "band_gap",
                "density",
                "volume",
                "nsites"#晶胞内的原子数
            ]
        )

        results.extend(docs)

    return results

存入csv文件

import pandas as pd

rows = []

def save_to_csv(data, filename):
    print("Saving to CSV...")
    df=pd.DataFrame([
    {
    "material_id": d.material_id,
    "formula": d.formula_pretty,
    "energy_above_hull": d.energy_above_hull,
    "formation_energy": d.formation_energy_per_atom,
    "band_gap": d.band_gap,
    "density": d.density,
     "volume": d.volume,
     "nsites": d.nsites
    }
    for d in data
    ])
    df.to_csv(filename,index=True,encoding="utf-8")
    print("CSV saved!")

主函数调用所有方法

def main():
    with MPRester(API_KEY) as mpr:
        robo_ids=get_robo_perovskite(mpr)
        tags_ids=get_tag_perovskite(mpr)
        #取并集
        all_ids=robo_ids|tags_ids
        print(f"Total perovskites:{len(all_ids)}")
        data=fetch_summary(mpr,all_ids)
        save_to_csv(data,OUTPUT_FILENAME)

点击run,运行文件后,可以看到控制台中开始拉取数据库中的数据,运行结束后,文件夹内会存入一个名为“perovskite_dataset.csv”的文件。到此,整个拉取的过程就结束了。打开csv文件,可以看到MP数据库中所有有关钙钛矿的结构以及相应的性质数据。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注