30K Views
July 19, 23
スライド概要
(超初心者向け)Orange Data Miningによるマテリアルズ・インフォマティクスハンズオン第三回スライド(仮)
マテリアルズインフォマティクスチュートリアル
(超初心者向け)Orange Data Miningによるマテリアルズ・イ ンフォマティクスハンズオン 第三回 木野日織 (きのひおり)
前置き 大規模言語モデル(LLM)でなく,わかりやすくす るためにここでは具体的にChatGPTもしくはGPTと書 きます。 はじめに,ChatGPTを利用する場合にはオプトアウ トの仕方を各自ご確認ください。
ChatGPTの利用 ChatGPTを利用したPython widget,Pythonスクリプトの作成。 結論: 簡単な作業は試行錯誤しなくても可能です。 多くの場合に何かのエラーが出ますが,GPT-4利用時でも Pythonを全く知らない人は完成できません。 Python widgetではインタプリターが動作しているので少しづつ 少しずつ作成することを薦めます。 Pythonの学習にもChatGPTは役に立ちます。
3.01.show_image.ows
データ ① ①data/w_L64_Orange.csv 4096のデータインスタンスを 持つ列ベクトル
Python widget ② [Python script] window 入力: in_data 出力: out_data となるように書く。 ①
Python widget Python scriptの例 import numpy as np from Orange.data import Table, Domain, ContinuousVariable 点線部分だけを Python widget内に書 くことになる。 chatGPTはこのPython コードを書く助けに なるかという問題。 def python_script(in_data): # 入力データの次元を取得 n = int(np.sqrt(len(in_data))) # 入力データを (N, N) の二次元行列に変換 matrix_data = np.reshape(in_data, (n, n)) # Orange のデータテーブルを作成 domain = Domain([ContinuousVariable(f'feature{i+1}') for i in range(n)]) out_data = Table.from_numpy(domain, matrix_data) return out_data
ChatGPTの利用 やって欲しいことを説明をする。青色は他の目的に対しても必要なプロンプト。 ① ② ③ ④ ⑤ Orange Data MiningのPython widgetを作ってください。 私はPythonの初心者です。平易なコードを作成してください。コメントで説明を追加し てください。 Python widgetの入力引数名をin_data,出力データをout_dataとします in_dataとout_data はOrange.Data.Tableのインスタンスです。 in_dataは一次元の列ベクトル,もしくは行ベクトルが入っています。 これはN*Nのサイ ズです。これを(N,N)のサイズの二次元行列に変換してout_dataにしてください。 Python widgetの中に書きますのですでにin_data変数が存在しています。関数のその他の コードだけ書いてください。Python widgetの中に書きますのでreturn文は不要です。 ①大目的。 ②無いと難しいコードを書く。 ③GPT-4では不要。 ④行ってほしいこと。失敗することもあるがN*Nのサイズの一次元ベクトルからN=sqrt(N*N)とす る程度の類推はできる。 ⑤無いとdef文を含む関数を書くかもしれない。
ChatGPTへのプロンプト この問題だけGPT3.5を利用。他はGPT-4を利用。
import numpy as np # Orangeデータテーブルの配列を取得します。Orangeデータテーブル は基本的にnumpyのndarrayに類似しています array = in_data.X # arrayの長さの平方根を取得します(Nを見つけるため)。Orange Data Miningでは、データは行または列のベクトルとして入力される ため、 # その長さの平方根を取ることで、変換されるべき正方形マトリック スの次元を得ることができます。 N = int(np.sqrt(array.size)) # 入力配列をNxN行列に変換します。 reshaped_array = array.reshape(N, N) # 二次元配列をOrangeデータテーブルに変換します。 from Orange.data import Domain, Table # すべての特徴が連続的(つまり、数値)であるドメインを作成しま す。 domain = Domain([ContinuousVariable(f'feature {i}') for i in range(N)]) # 二次元配列を新しいOrangeデータテーブルに変換します。 out_data = Table(domain, reshaped_array)
②エラー箇所 ①エラー
import numpy as np from Orange.data import Domain, Table, ContinuousVariable # Orangeデータテーブルの配列を取得します。Orangeデータテーブルは基本 的にnumpyのndarrayに類似しています array = in_data.X # arrayの長さの平方根を取得します(Nを見つけるため)。Orange Data Miningでは、データは行または列のベクトルとして入力されるため、 # その長さの平方根を取ることで、変換されるべき正方形マトリックスの次 元を得ることができます。 N = int(np.sqrt(array.size)) # 入力配列をNxN行列に変換します。 reshaped_array = array.reshape(N, N) # すべての特徴が連続的(つまり、数値)であるドメインを作成します。 domain = Domain([ContinuousVariable(f'feature {i}') for i in range(N)]) # 二次元配列を新しいOrangeデータテーブルに変換します。 out_data = Table(domain, reshaped_array)
①上書きコピペ ②Runを 押す。 ③エラーなし。
②[Heat Map] window ② ① ①点線が実線になった (上流が実行されてLink にデータが存在する) ことを確認
Console部分 インタプリターが起動 しています。
①値の確認,コードの記載など Python scriptを書くことができる。 ③完成コードを書 くことができます。 ②こちらで試行 錯誤しながら
3.02.reconstruction.ows
Lassoによるトモグラフ像再構成例 ① ② ①data/XL-4_L64_orange.csv ②Fit interceptにチェック Lasso regression L1)を背タンク Regularization strength 0.0007を選択 ③最初は点線のはず。 ③
回帰係数の表示 ②[Data Table] window ③ ① ④FeatureXのcoefはN*Nの 一次元列ベクトル。それ らを (N,N)に直し,二次元 データを可視化できる [Heat Map]で表示させる。
回帰係数の表示 ②[Heat Map] window ① Interceptを 除いた行の coefを(N,N) に変換する。
GPT-4によりPythonコード作成
import numpy as np
from Orange.data import Domain, Table
# in_dataからintercept行を除去します
filtered_data = in_data[in_data["name"] != "intercept"]
# coefカラムの値を抽出し、numpy配列に変換します
coef_values = np.array([d["coef"].value for d in filtered_data])
# numpy配列の形状を(N, N)の二次元行列に変換します
N = int(np.sqrt(len(coef_values))) # Nを計算します
reshaped_values = coef_values.reshape(N, N)
# 新しいOrangeのデータテーブルを作成します
domain = Domain([f'Feature{i+1}' for i in range(N)]) # ドメイ
ンを作成します
out_data = Table.from_numpy(domain, reshaped_values)
Filtered_dataはindexでないので,
期待通りの動作はしない。
①Pythonコードをコピペして ②押して実行 ③エラーが 起きている。
①Editorの5行目をコピーして ConsoleにペーストしてReturnキーで実 行させる。 ②エラーが起きる。 最初の文でエラーが起きている。
色々やってみたがOrange.Data.Tableのまま ではChatGPTは扱えない。 filtered_data = in_data[in_data[“name”] != “intercept”]文はデータフレームの操作を 行っている,とデータフレームを知ってい る人は分かる。 In_dataを一度データフレームに変換して, Pandasデータフレームを経由するように指 示する。
import numpy as np
import pandas as pd
from Orange.data.pandas_compat import table_to_frame
from Orange.data import Domain, Table
# 1. Orange Data TableをpandasのDataFrameに変換します
df = table_to_frame(in_data)
# 2. 'intercept'行を除いた'data'カラムの値を取得します
filtered_data = df[df["name"] != "intercept"]["coef"]
# 3. 値をN*Nの二次元行列に変換します
N = int(np.sqrt(len(filtered_data))) # Nを計算します
reshaped_values = np.array(filtered_data).reshape(N, N)
# 4. 二次元行列をOrange Data Tableに変換します
domain = Domain([f'Feature{i+1}' for i in range(N)]) # ドメインを作成します
out_data = Table.from_numpy(domain, reshaped_values)
①上書きでコピペする。
②Runで実行する。
③エラ-が起きる。
①df[“name”]でエラーが起きて いるらしい。 ②dfを表示するとnameカラムが 無い。
import pandas as pd from Orange.data.pandas_compat import table_to_frame # Orange Data Tableを含めてpandasのDataFrameに変換します df = table_to_frame(in_data, include_metas=True)
①Editorから一行づつConsole へコピペして実行していく。 ②domain行でエラーが起きて いることが分かる。
from Orange.data import Domain, ContinuousVariable, Table … domain = Domain([ContinuousVariable(f'Feature{i+1}') for i in range(N)]) # ドメインを作成します …
コード修正
import numpy as np
import pandas as pd
from Orange.data.pandas_compat import table_to_frame
from Orange.data import Domain, ContinuousVariable, Table
# Orange Data Tableを含めてpandasのDataFrameに変換します
df = table_to_frame(in_data, include_metas=True)
# 'intercept'行を除いた'data'カラムの値を取得します
filtered_data = df[df["name"] != "intercept"]["coef"]
# 値をN*Nの二次元行列に変換します
N = int(np.sqrt(len(filtered_data))) # Nを計算します
reshaped_values = np.array(filtered_data).reshape(N, N)
# 二次元行列をOrange Data Tableに変換します
domain = Domain([ContinuousVariable(f'Feature{i+1}') for i in range(N)]) # ドメインを作成します
out_data = Table.from_numpy(domain, reshaped_values)
①エラーなし。
(N,N)の二 次元に変 換された。
問題:DOSからセミコア元素の特定 • 回帰 • 次元圧縮 • 分類(classification) • クラスタリング(clustering) を用いた応用。
データ生成過程 固溶体第一原理計算のセミコア領域の電子状態密度DOS(エネルギーvs大きさ)を用いる。 第一原理計算計算過程 複数元素を指定 入力 第一原理 計算 出力 物理量 DOSもその一つ 第一原理計算(演繹法)の因果関係 原因 結果 セミコア順位を持つ元素が 含まれる その元素の特徴を持つセミコアエネ ルギー領域のDOSが観測される。
分類問題設定 セミコア元素の特徴を 持つDOS セミコア元素を答え(ラベル)として回帰す る。 該当するセミコア元素を説明変数空間 でクラスタリングする。 光学スペクトルから物質を同定する問題設定と同じ。 簡単のため、セミコアエネルギー領域にセミコア順位を持つ元素を一つだけ含む元素組み合わせを選択する。
観測データファイル 300データインスタンス 50説明変数:セミコアエネルギー領域のエネルギー点 目的変数(6カテゴリ):Bi,Hf,Hg,Mo,Nb,Sn Bi Log10 (DOS(𝐸𝐸)) valence 𝐸𝐸 𝐸𝐸𝐹𝐹 エネルギー Green関数からDOSを計算する際に、小さなImaginary partを入れているのでDOS(E)=0にはならない。 Phys. Rev. Materials 6, 023802 (2022).
観測データ 似ている。 縦軸,横軸の範囲は全てのパネルで同じ。 似ている。 似ている。
問題 交差検定で分類予測モデルをつくる。 DOSのどの部分から予測モデルが作成されているの かを確認する。
分類ワークフロー 既出ワークフロー(2.03.cls_CV.ows)に [Save Data]をつける。 ① data/hea4_d os_selected_ Orange.csv を選択 ③[Test and Score] Cross Validation Number of folds: 5 を選択 ③ ④[Confusion Matrix] Learners: Logistic Regression を選択 ②Regularization type: Lasso(L1)を選択。 ⑤追加
分類ワークフロー 過程を文章で表す。 A) ファイルから観測データを読み込む。 B) 観測データで交差検定により正規化関 数を含む分類予測モデルを作成し,ある ハイパーパラメタの予測値と分類性能 を得る。 C) 交差検定の予測値から混同行列を得る。 D) 全観測データで正規化関数を含む Logstic回帰モデルを作る。
交差検定による分類性能 F1=0.980 C~4がもっともF1が大きい。
線形係数 C=4 係数0が多く,説明変数のごく一 部を参照しているのかが分かる。 =各semicoreの”特徴”を表している。
Logistic regressionの係数を保存 ① ② “{folder}/data_generated/dos_cls_coefficients.csv” 後で使う。
3.03.dos_clustering.ows
クラスタリングワークフロー A) 観測データを読み込む。 B) 観測データを正規化する。 C) PCAで変換した観測データを低 次元化する。 D) 観測データを多様体学習で低次 元化する。 E) 変換された観測データを正規化 する。 F) 変換された観測データをkMeansでクラスタリングする。 G) 変換された観測データをPCAで 低次元化する。 E) B) C) A) G) F) D) 説明変数の種類数はPCA/Manifold learingの変換後の次元数。
正規化選択肢が幾つかあります。 A)Hea4_dos_selected_Orange.csv B)Normalize features:Standarize μ=0,σ2=1。 C)6次元。Option: Normalize variablesをチェックしない。 D)Method=t-SNE, Metrix=Enclidean,Perplexity=25 E)選択しない。 F) Number of Clusters: Fixed=6 G) 2次元。Option: Normalize variablesをチェックしない。 E) B) C) A) G) F) D)
PCAで次元圧縮した場合 • 六次元の説明変数 に対してk-Means法 を適用している。 • 表示は二次元で 行っている。 • Hf-Nb • Mo-Hg • Bi-Sn が隣り合っている。 もしくは混じってい る。 元々 • Hf-Nb • Mo-Hg • Bi-Sn はスペクトルがよく 似ていた。 Hf Bi Nb Mo Hg Sn
3.04.dos_ML_clustering.ows
t-SNEで次元圧縮する場合のワークフ ロー A) [PCA]-{Preprocess (1)] のリンクを削除 B) [Manifold learning]{Transformed Data}{Data}[Preprocess (1)] とつなぐ。 A) B)
t-SNEで次元圧縮した場合 ①PCAで低次元化してから可視化し ているのでPC1とPC2を選ぶ 同一クラスターに異なる セミコアが混じっていま すが, PCAの場合より分布が分離 しているように見える。 実際は高次元空間上にあ り,表示が二次元である ことに注意。
クラスタリングと分類 クラスタリングはできました。 K-Meansでクラスタリングできるということは分布が分離しているという仮定が入りますが,高次元 空間でのクラスタリングで何が起きているのかわかりません。この場合に分布は分離していないかも しれませんが,分類の目的変数値と予測値,クラスタリングでのセミコア元素名とクラスター名の関 係と似ているので,クラスタリング結果に対して分類の混同行列と評価指標を計算してみます。(ク ラスタリングの評価指標にはなりません。) 分類 クラスタリング 目的変数 予測値 セミコア元素 クラスター名 Bi Bi Bi C1 Bi Bi Bi C1 Nb Bi Nb C1 Nb Nb Nb C2
3.05.dos_clustering_cls_score.ows
ワークフローの作成 “回帰スコア”評価 “混同行列”評価
from Orange.data.pandas_compat import table_to_frame
from sklearn.metrics import f1_score, precision_score, recall_score, accuracy_score
from collections import Counter
import pandas as pd
from Orange.data import Table
# 1. Convert the input data to a pandas dataframe
df = table_to_frame(in_data, include_metas=True)
# 2. Extract "semicore" and "Cluster" categories and align the names
# Find the most common "Cluster" for each "semicore"
semicore_cluster_map = df.groupby('semicore')['Cluster'].agg(lambda x:
Counter(x).most_common(1)[0][0])
# Apply the mapping to the "semicore" column
df['semicore'] = df['semicore'].map(semicore_cluster_map)
# 3. Compute the clustering performance between "semicore" and "Cluster"
f1 = f1_score(df['semicore'], df['Cluster'], average='weighted')
precision = precision_score(df['semicore'], df['Cluster'], average='weighted')
recall = recall_score(df['semicore'], df['Cluster'], average='weighted')
accuracy = accuracy_score(df['semicore'], df['Cluster'])
# Create a DataFrame to hold the results
results_df = pd.DataFrame({
'F1 Score': [f1],
'Precision': [precision],
'Recall': [recall],
'Accuracy': [accuracy]
})
# Convert the results DataFrame to an Orange Table
out_data = Table.from_pandas_df(results_df)
②エーラ箇所 ①エラー
from Orange.data.pandas_compat import table_to_frame, pandas_df_to_table
from sklearn.metrics import f1_score, precision_score, recall_score, accuracy_score
from collections import Counter
import pandas as pd
# 1. Convert the input data to a pandas dataframe
df = table_to_frame(in_data, include_metas=True)
# 2. Extract "semicore" and "Cluster" categories and align the names
# Find the most common "Cluster" for each "semicore"
semicore_cluster_map = df.groupby('semicore')['Cluster'].agg(lambda x:
Counter(x).most_common(1)[0][0])
# Apply the mapping to the "semicore" column
df['semicore'] = df['semicore'].map(semicore_cluster_map)
# 3. Compute the clustering performance between "semicore" and "Cluster"
f1 = f1_score(df['semicore'], df['Cluster'], average='weighted')
precision = precision_score(df['semicore'], df['Cluster'], average='weighted')
recall = recall_score(df['semicore'], df['Cluster'], average='weighted')
accuracy = accuracy_score(df['semicore'], df['Cluster'])
# Create a DataFrame to hold the results
results_df = pd.DataFrame({
'F1 Score': [f1],
'Precision': [precision],
'Recall': [recall],
'Accuracy': [accuracy]
})
# Convert the results DataFrame to an Orange Table
out_data = pandas_df_to_table(results_df)
途中でファイルを使いたくない。一度データフレームを作成していること が困難の原因なので,データフレームを作らない方法を尋ねる。
from Orange.data.pandas_compat import table_to_frame from sklearn.metrics import f1_score, precision_score, recall_score, accuracy_score from collections import Counter from Orange.data import Table, Domain, ContinuousVariable # 1. Convert the input data to a pandas dataframe df = table_to_frame(in_data, include_metas=True) # 2. Extract "semicore" and "Cluster" categories and align the names # Find the most common "Cluster" for each "semicore" semicore_cluster_map = df.groupby('semicore')['Cluster'].agg(lambda x: Counter(x).most_common(1)[0][0]) # Apply the mapping to the "semicore" column df['semicore'] = df['semicore'].map(semicore_cluster_map) # 3. Compute the clustering performance between "semicore" and "Cluster" f1 = f1_score(df['semicore'], df['Cluster'], average='weighted') precision = precision_score(df['semicore'], df['Cluster'], average='weighted') recall = recall_score(df['semicore'], df['Cluster'], average='weighted') accuracy = accuracy_score(df['semicore'], df['Cluster']) # Create the domain (variables) domain = Domain([ContinuousVariable(name) for name in ['F1 Score', 'Precision', 'Recall', 'Accuracy']]) # Create the data (in the form of a list of lists) data = [[f1, precision, recall, accuracy]] # Convert the data and domain to an Orange Table out_data = Table(domain, data)
①警告が出ている。動いてい るが修正を依頼する。
from Orange.data.pandas_compat import table_to_frame from sklearn.metrics import f1_score, precision_score, recall_score, accuracy_score from collections import Counter from Orange.data import Table, Domain, ContinuousVariable # 1. Convert the input data to a pandas dataframe df = table_to_frame(in_data, include_metas=True) # 2. Extract "semicore" and "Cluster" categories and align the names # Find the most common "Cluster" for each "semicore" semicore_cluster_map = df.groupby('semicore')['Cluster'].agg(lambda x: Counter(x).most_common(1)[0][0]) # Apply the mapping to the "semicore" column df['semicore'] = df['semicore'].map(semicore_cluster_map) # 3. Compute the clustering performance between "semicore" and "Cluster" f1 = f1_score(df['semicore'], df['Cluster'], average='weighted') precision = precision_score(df['semicore'], df['Cluster'], average='weighted') recall = recall_score(df['semicore'], df['Cluster'], average='weighted') accuracy = accuracy_score(df['semicore'], df['Cluster']) # Create the domain (variables) domain = Domain([ContinuousVariable(name) for name in ['F1 Score', 'Precision', 'Recall', 'Accuracy']]) # Create the data (in the form of a list of lists) data = [[f1, precision, recall, accuracy]] # Convert the data and domain to an Orange Table using Table.from_list out_data = Table.from_list(domain, data)
①エラー,警告がなくなる。
回帰評価指標
ワークフローの作成 “回帰スコア”評価 “混同行列”評価
混同行列 df[“semicore”]とdf[“Cluster”]から計算可能。 from sklearn.metrics import confusion_matrix import pandas as pd # sklearnのconfusion_matrix関数を使用して混同行列を計算 matrix = confusion_matrix(df['semicore'], df['Cluster']) # カテゴリ名を取得 categories = sorted(set(df['semicore']).union(df['Cluster'])) # 混同行列をデータフレームに変換 df_cm = pd.DataFrame(matrix, index=categories, columns=categories) Confusion_maxtrixとcategoriesが別々なのが気持ち悪 い。
from sklearn.metrics import confusion_matrix import pandas as pd # カテゴリ名を取得 categories = sorted(set(df['semicore']).union(df['Cluster'])) # sklearnのconfusion_matrix関数を使用して混同行列を計算 matrix = confusion_matrix(df['semicore'], df['Cluster'], labels=categories) # 混同行列をデータフレームに変換 df_cm = pd.DataFrame(matrix, index=categories, columns=categories)
from Orange.data.pandas_compat import table_from_frame # Orange.data.Tableへの変換 out_data = table_from_frame(df_cm)
混同行列
線形係数(再) C=4 係数0が多く,説明変数のごく一 部を参照しているのかが分かる。 =各semicoreの”特徴”を表している。
DOSと分類係数を関連付けた可視化 目的:回帰モデルが説明変数のどの部分から作成されているの かを可視化する。 手段:GPT4で生成したPythonコードをjupyter notebookで実行し ながら完成させる。 ファイル: データファイル“{folder}/data/hea4_dos_selected_Orange.csv”に対 して分類をした。Logistic回帰の係数を係数ファイル “{folder}/data_generated/dos_cls_coefficients.csv”に保存した。 作業: ①データファイルのsemicore元素をN vs log10_dosNの図を書く。 ②係数ファイルに対して,N vs log10_dosN(係数)の図を書く。 ③上の2つの図を上下に並べる。 完成予定図 ① ② ③
データファイルの確認 エクセルによる表示 ①データファイルを読み 込む。その際にデータ ファイルの2,3行目を 読み飛ばす。 ②log10_dosN, N=1,3,…,99 をy軸にするために行列 を転置する。 ③x軸を加える。
# pandasというデータ操作に便利なライブラリをインポートします。 import pandas as pd import numpy as np # 関数を定義します。この関数は、データファイルのパスを引数として受け取ります。 def process_data(file_path): 以下のPythonコードを書いてください。 私はPythonの初心者なの で私が理解できるようにソースコードに説明を追加してください。 以下の作業を行ってください。 1. データファイル名を“../data/hea4_dos_selected_Orange.csv”と してます。データファイルをデータフレーム df_dataとして読 み込みます。データファイルの最初の行を1行目として2行 目と3行目は読み飛ばしてください。 2. selected_semicore変数を”Bi”としてください。 dfからsemicore カラムがsemicoreであるデータを選択してください 3. log10_dos1,log10_dos3,log10_dos5,...,log10_dos99までのカラム を選択してください。選択部分の行列を転置してください。 4. dos10_dosNのNに対応する1,3,5,…,99を新たなカラムxに追加し てください。 5. ここまで行う関数を引数データファイルとして作成してくだ さい。 不明事項は私に質問してください。 # pandasのread_csv関数を使ってCSVファイルを読み込みます。 # skiprowsパラメータで2行目と3行目を読み飛ばします。 df_data = pd.read_csv(file_path, skiprows=[1,2]) ←skiprowsを間違える場合あり。 # selected_semicore変数を定義します。 selected_semicore = "Bi" # dfからsemicoreカラムがselected_semicoreと一致するデータを選択します。 df_selected = df_data[df_data['semicore'] == selected_semicore] # 選択したいカラムの名前を作成します。 selected_columns = ['log10_dos' + str(i) for i in range(1, 100, 2)] # selected_columnsに含まれるカラムだけを選択します。 df_selected = df_selected[selected_columns] # 行列を転置します。転置により、元々のカラムが行に、行がカラムになります。 df_transposed = df_selected.transpose() # "x"カラムを作成します。これは元々のカラム名(log10_dosN)のN部分に相当します。 df_transposed['x'] = [int(column.split('log10_dos')[1]) for column in df_transposed.index] # 転置したデータフレームを返します。 return df_transposed # この関数を呼び出し、結果を表示します。 result = process_data("../data/hea4_dos_selected_Orange.csv") print(result)
(可視化できることの確認) 上のresultを用いて図を書きます。 1. 横軸をxカラムの値,縦軸をxカラム 以外としてください。 2. 図は黒色のみ用いてください。図 で線の透過性を表すアルファ値を 0.05としてください。 # 必要なライブラリをインポートします。 import matplotlib.pyplot as plt # matplotlibを使ってグラフを描きます。 # xカラムをx軸に、それ以外のカラムをそれぞれy軸としてプロットします。 for column in result.columns: if column != 'x': plt.plot(result['x'], result[column], color='black', alpha=0.05) # グラフの表示 plt.show()
係数ファイル エクセルによる表示 ①データファイルを読み 込む。その際にデータ ファイルの2,3行目を 読み飛ばす。 ②x軸を加える。
# 必要なライブラリをインポートします。 import pandas as pd import matplotlib.pyplot as plt 以下のPythonコードを書いてください。 私はPythonの 初心者なので私が理解できるようにソースコードに説 明を追加してください。 以下の作業を行ってください。 1. 係数ファイル名を “../data_generated/dos_cls_coefficients.csv”とします。 係数ファイルをデータフレーム df_coefとして読み 込みます。ファイルは1行目から始まるとして,2 行目と3行目は読み飛ばしてください。 2. selected_semicore変数を”Bi”としてください。 log10_dos1,log10_dos3,log10_dos5,...,log10_dos99ま でのリストを作成してください。 3. nameカラムが上のリストの行を選択しててくださ い。 4. dos10_dosNのNに対応する1,3,5,…,99をカラムxに追 加してください。 5. x軸をxカラム,y軸カラム名がselected_semicoreであ るデータとして図示してください。 不明事項は私に質問してください。 # 関数を定義します。この関数は、係数ファイルのパスを引数として受け取ります。 def plot_coefficients(file_path): # pandasのread_csv関数を使ってCSVファイルを読み込みます。 # skiprowsパラメータで2行目と3行目を読み飛ばします。 df_coef = pd.read_csv(file_path, skiprows=[1,2]) # selected_semicore変数を定義します。 selected_semicore = "Bi" # 選択したいカラムの名前を作成します。 selected_columns = ['log10_dos' + str(i) for i in range(1, 100, 2)] # nameカラムがselected_columnsに含まれる行を選択します。 df_selected = df_coef[df_coef['name'].isin(selected_columns)] # "x"カラムを作成します。これは元々のカラム名(log10_dosN)のN部分に相当します。 df_selected['x'] = [int(name.split('log10_dos')[1]) for name in df_selected['name']] # matplotlibを使ってグラフを描きます。 # xカラムをx軸に、selected_semicoreカラムをy軸にしてプロットします。 plt.plot(df_selected['x'], df_selected[selected_semicore]) # グラフの表示 plt.show() # この関数を呼び出し、結果を表示します。 plot_coefficients("../data_generated/dos_cls_coefficients.csv")
# 必要なライブラリをインポートします。 import pandas as pd import matplotlib.pyplot as plt 上のコードを実行したところ df_selected['x'] = [int(name.split('log10_dos')[1]) for name in df_selected['name’]] でA value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead というメッセージが出たのでコードを修正してください。 # 関数を定義します。この関数は、係数ファイルのパスを引数として受け取ります。 def plot_coefficients(file_path): # pandasのread_csv関数を使ってCSVファイルを読み込みます。 # skiprowsパラメータで2行目と3行目を読み飛ばします。 df_coef = pd.read_csv(file_path, skiprows=[1,2]) # selected_semicore変数を定義します。 selected_semicore = "Bi" # 選択したいカラムの名前を作成します。 selected_columns = ['log10_dos' + str(i) for i in range(1, 100, 2)] # nameカラムがselected_columnsに含まれる行を選択します。 df_selected = df_coef[df_coef['name'].isin(selected_columns)].copy() # コピーを作成 # "x"カラムを作成します。これは元々のカラム名(log10_dosN)のN部分に相当します。 df_selected.loc[:, 'x'] = [int(name.split('log10_dos')[1]) for name in df_selected['name']] # matplotlibを使ってグラフを描きます。 # xカラムをx軸に、selected_semicoreカラムをy軸にしてプロットします。 plt.plot(df_selected['x'], df_selected[selected_semicore]) # グラフの表示 plt.show() # この関数を呼び出し、結果を表示します。 plot_coefficients("../data_generated/dos_cls_coefficients.csv")
# 必要なライブラリをインポートします。 import pandas as pd import matplotlib.pyplot as plt # 関数を定義します。この関数は、係数ファイルのパスを引数として受け取ります。 def plot_coefficients(file_path): # pandasのread_csv関数を使ってCSVファイルを読み込みます。 # skiprowsパラメータで2行目と3行目を読み飛ばします。 df_coef = pd.read_csv(file_path, skiprows=[1,2]) selected_rowsの図を棒グラフにしてくださ い。その際にy軸が0の位置に直線を引い てください。 # selected_semicore変数を定義します。 selected_semicore = "Bi" # 選択したいカラムの名前を作成します。 selected_columns = ['log10_dos' + str(i) for i in range(1, 100, 2)] # nameカラムがselected_columnsに含まれる行を選択します。 df_selected = df_coef[df_coef['name'].isin(selected_columns)].copy() # コピーを作成 # "x"カラムを作成します。これは元々のカラム名(log10_dosN)のN部分に相当します。 df_selected.loc[:, 'x'] = [int(name.split('log10_dos')[1]) for name in df_selected['name']] # matplotlibを使って棒グラフを描きます。 # xカラムをx軸に、selected_semicoreカラムをy軸にしてプロットします。 plt.bar(df_selected['x'], df_selected[selected_semicore]) # y=0の位置に直線を引きます。 plt.axhline(0, color='black') # グラフの表示 plt.show() # この関数を呼び出し、結果を表示します。 plot_coefficients("../data_generated/dos_cls_coefficients.csv")
# 必要なライブラリをインポートします。 import pandas as pd import matplotlib.pyplot as plt import numpy as np # データフレームから特定のデータを選択し、新しいカラムを追加する関数 def process_data(df, selected_semicore): # selected_semicoreで指定したデータを選択します。 df_selected = df[df['semicore'] == selected_semicore] # "log10_dos1", "log10_dos3", ..., "log10_dos99"という名前のカラムを選択します。 df_selected = df_selected.filter(regex='log10_dos[13579]') # DataFrameを転置します。 df_transposed = df_selected.T データフィルに対する図を上,係数ファイル に対する図を下に配置した一つの図にする コードを書いてください。 データファイル名,係数ファイル名, selected_semicoreを引数として図を書く関数を 作成してください。 # "dos10_dosN"の"N"に対応する1, 3, 5, ..., 99を新たなカラム"x"に追加します。 df_transposed['x'] = [int(column.split('log10_dos')[1]) for column in df_transposed.index] return df_transposed # 関数を定義します。この関数は、データファイルと係数ファイルのパス、及びselected_semicoreを引数として受け取ります。 def plot_data_and_coefficients(data_file_path, coef_file_path, selected_semicore): # データファイルを読み込みます。 df_data = pd.read_csv(data_file_path, skiprows=[1,2]) df_data_transposed = process_data(df_data, selected_semicore) # 係数ファイルを読み込みます。 df_coef = pd.read_csv(coef_file_path, skiprows=[1,2]) df_coef_selected = df_coef[df_coef['name'].isin(df_data_transposed.index)].copy() df_coef_selected.loc[:, 'x'] = [int(name.split('log10_dos')[1]) for name in df_coef_selected['name']] # matplotlibを使って図を作成します。subplotを使って2つのグラフを一つの図に配置します。 fig, ax = plt.subplots(2, 1) # データファイルに対する図を上に配置します。 for i in range(len(df_data_transposed.columns) - 1): ax[0].plot(df_data_transposed['x'], df_data_transposed.iloc[:, i], color='black', alpha=0.05) # 係数ファイルに対する図を下に配置します。 ax[1].bar(df_coef_selected['x'], df_coef_selected[selected_semicore]) ax[1].axhline(0, color='black') # グラフの表示 plt.show() # この関数を呼び出し、結果を表示します。 plot_data_and_coefficients("../data/hea4_dos_selected_Orange.csv", "../data_generated/dos_cls_coefficients.csv", "Bi")
図を書かせてみると先程の図と違う。 通常の簡易的なデバック作業と同じく 途中で print(df_selected), df_selectedのデータインスタンス数を確認する print(df_selected.shape) などを挟むなどしておかしくなった箇所を探すことが できるだろう。 はじめの方の df_selected = df_selected.filter(regex='log10_dos[13579]’) がおかしい。
# 必要なライブラリをインポートします。 import pandas as pd import matplotlib.pyplot as plt import numpy as np # データフレームから特定のデータを選択し、新しいカラムを追加する関数 def process_data(df, selected_semicore): # selected_semicoreで指定したデータを選択します。 df_selected = df[df['semicore'] == selected_semicore] log10_dos1, log10_dos2, …, log10_dos99までで log10_dosNのNは1からはじまり99まで2刻みの数を 取ります。 コードを書き換えてください。 # "log10_dos1", "log10_dos3", ..., "log10_dos99"という名前のカラムを選択します。 # ここで、Nは1から始まり2刻みとなるように変更します。 df_selected = df_selected.filter(regex='log10_dos[1-9][02468]?') 相変わらずおかしい。 人間と同様に一度思い # "dos10_dosN"の"N"に対応する1, 3, 5, ..., 99を新たなカラム"x"に追加します。 込むと抜けられない。 df_transposed['x'] = [int(column.split('log10_dos')[1]) for column in df_transposed.index] # DataFrameを転置します。 df_transposed = df_selected.T return df_transposed # 関数を定義します。この関数は、データファイルと係数ファイルのパス、及びselected_semicoreを引数として受け取ります。 def plot_data_and_coefficients(data_file_path, coef_file_path, selected_semicore): # データファイルを読み込みます。 df_data = pd.read_csv(data_file_path, skiprows=[1,2]) df_data_transposed = process_data(df_data, selected_semicore) # 係数ファイルを読み込みます。 df_coef = pd.read_csv(coef_file_path, skiprows=[1,2]) df_coef_selected = df_coef[df_coef['name'].isin(df_data_transposed.index)].copy() df_coef_selected.loc[:, 'x'] = [int(name.split('log10_dos')[1]) for name in df_coef_selected['name']] # matplotlibを使って図を作成します。subplotを使って2つのグラフを一つの図に配置します。 fig, ax = plt.subplots(2, 1) # データファイルに対する図を上に配置します。 for i in range(len(df_data_transposed.columns) - 1): ax[0].plot(df_data_transposed['x'], df_data_transposed.iloc[:, i], color='black', alpha=0.05) # 係数ファイルに対する図を下に配置します。 ax[1].bar(df_coef_selected['x'], df_coef_selected[selected_semicore]) ax[1].axhline(0, color='black') # グラフの表示 plt.show() # この関数を呼び出し、結果を表示します。 plot_data_and_coefficients("../data/hea4_dos_selected_Orange.csv", "../data_generated/dos_cls_coefficients.csv", "Bi")
(選択法を変える。) "log10_dos"を含む文字列のカラムを 用いるとしてprocess_data関数を書き 換えてください。 def process_data(df, selected_semicore): # selected_semicoreで指定したデータを選択します。 df_selected = df[df['semicore'] == selected_semicore] # "log10_dos"を含む名前のカラムを選択します。 df_selected = df_selected.loc[:, df_selected.columns.str.contains('log10_dos')] # DataFrameを転置します。 df_transposed = df_selected.T # "dos10_dosN"の"N"に対応する数値を新たなカラム"x"に追加します。 df_transposed['x'] = [int(column.split('log10_dos')[1]) for column in df_transposed.index] return df_transposed
図のタイトルをselected_semicore変数の値
としてください。図をファイルに保存し
てください。ファイル名は
selected_semicore+"_cls_coef.png"とします。
# 必要なライブラリをインポートします。
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# データフレームから特定のデータを選択し、新しいカラムを追加する関数
def process_data(df, selected_semicore):
# selected_semicoreで指定したデータを選択します。
df_selected = df[df['semicore'] == selected_semicore]
# 関数を定義します。この関数は、データファイルと係数ファイルのパス、及びselected_semicoreを引数として受け
取ります。
def plot_data_and_coefficients(data_file_path, coef_file_path, selected_semicore):
# データファイルを読み込みます。
df_data = pd.read_csv(data_file_path, skiprows=[1,2])
df_data_transposed = process_data(df_data, selected_semicore)
# 係数ファイルを読み込みます。
df_coef = pd.read_csv(coef_file_path, skiprows=[1,2])
df_coef_selected = df_coef[df_coef['name'].isin(df_data_transposed.index)].copy()
df_coef_selected.loc[:, 'x'] = [int(name.split('log10_dos')[1]) for name in df_coef_selected['name']]
# matplotlibを使って図を作成します。subplotを使って2つのグラフを一つの図に配置します。
fig, ax = plt.subplots(2, 1)
# タイトルを追加します。タイトルはselected_semicoreの値にします。
fig.suptitle(selected_semicore)
# データファイルに対する図を上に配置します。
for i in range(len(df_data_transposed.columns) - 1):
ax[0].plot(df_data_transposed['x'], df_data_transposed.iloc[:, i], color='black', alpha=0.05)
# "log10_dos"を含む名前のカラムを選択します。
df_selected = df_selected.loc[:, df_selected.columns.str.contains('log10_dos')]
# 係数ファイルに対する図を下に配置します。
ax[1].bar(df_coef_selected['x'], df_coef_selected[selected_semicore])
ax[1].axhline(0, color='black')
# DataFrameを転置します。
df_transposed = df_selected.T
# グラフをPNGファイルとして保存します。ファイル名はselected_semicore+"_cls_coef.png"にします。
plt.savefig(f"{selected_semicore}_cls_coef.png")
# "dos10_dosN"の"N"に対応する数値を新たなカラム"x"に追加します。
df_transposed['x'] = [int(column.split('log10_dos')[1]) for column in
df_transposed.index]
return df_transposed
# グラフの表示
plt.show()
# この関数を呼び出し、結果を表示します。
plot_data_and_coefficients("../data/hea4_dos_selected_Orange.csv", "../data_generated/dos_cls_coefficients.csv", "Bi")
(すでに分かったと思いますが, 毎回全部書き換えようとするので, 完成している関数をそのまま使う ように指示する。) # データファイルを読み込みます。 df = pd.read_csv("../data/hea4_dos_selected_Orange.csv", skiprows=[1,2]) # "semicore"カラムの一意な値を取得します。 unique_semicore_values = df["semicore"].unique() df[“semicore”]の重複しない全ての 値に対して関数 plot_data_and_coefficientsを呼んで 図を作成してください。 関数plot_data_and_coefficientsは再 表示しないでください。 # 一意な値それぞれに対して、plot_data_and_coefficients関 数を呼び出します。 for semicore_value in unique_semicore_values: plot_data_and_coefficients("../data/hea4_dos_selected_Orang e.csv", "../data_generated/dos_cls_coefficients.csv", semicore_value) semicore が六元素の図を書けた。
DOSと回帰係数の可視化結果 Hf Hg Mo ①確率が逆にな るようにほぼ同 じ位置の係数が 選ばれている。 Nb Bi ②確率が逆にな るようにほぼ同 じ位置の係数が 選ばれている。 ③Biのピーク は見ていない。 Sn ④この位置の 大きさで比較 している。 人間にとっては不思議だが,機械学習手法はこのデータを分類するにはこの特徴量が良いと判断した。
注意 今の結果は六元素の場合の分類モデルに限る話です。他の元素が入るとまた異なるでしょう。 人間だと(今のデータに無い別の元素組み合わせの場合を考えて)凹凸構造とその位置を 見るでしょう。(今の手法では凹凸構造を選択できないという問題点はある。) しかし,機械学習だと数値データおよび使用する説明変数の範囲内でのみ妥当な特徴量を 選択します。 機械学習モデルが見ている重要な特徴量は人間が重要と思う特徴量とは異なります。 参考文献: arXiv:1905.03540v4, Mitsubara, “Embedding Human Knowledge into Deep Neural Network via Attention Map” arXiv:2101.05307v2, Eloi Zablocki et al., “Explainability of deep visionbased autonomous driving systems: Review and challenges”
プログラミングにおけるChatGPTの利用 同じプロンプトでも答えは変わる場合が多い。 よくある例の方が成功率は高い。 例)Orange.Data.Tableでなくデータフレームに一度変換 して,データフレームで複雑な作業を行う,とする。 簡単なコードはGPT-3.5でもできるが,少し複雑に なっただけで作れなくなる。 Pythonを知らない方:GPT-4でもほぼ不可能。 Python初心者:GPT-4を推奨。Python初心者はコー ドの誤りを見つけるのが大変なのでGPT-4でコード を作るより,GPT-4の例を通してPythonを学びなが ら変換するのが適切な利用方法。 Python中級者:GPT-3.5の回答をヒントに使うだけ で十分かもしれない。完全にプロンプトから作成 するより,GPTの回答に人間がコードを補足した方 が速いだろう。 GPT-3.5 GPT-4 Python知らない方 X △ Python初心者 △ ◯ Python中級者 ◯ ◯
プログラミングにおけるChatGPTの利用 例) domain = Domain([ContinuousVariable(f'feature{i+1}') for i in range(n)]) out_data = Table.from_numpy(domain, matrix_data) Documentを全部読むのは苦痛だが,ChatGPTと のやり取りを通じて,この場合はDomainクラ スを使うというOrangeのデータ構造の定義が分 かる。目的に応じてどこから学習すれば良いの か当たりが付けられるのは大きな利点。 また,OrangeでPython widgetを使うには 1. インフォマティクス側の連続変数の知識 2. Pythonの知識 3. Orange Data Mining classの知識 が必要。 今は, 1.インフォマティクス側の連続変数の知識がある, 2.Pythonの知識もすこしある, としている。 ChatGPTで足りない一点の知識を支援してもらえれば 理解が容易になる。
プログラミングにおけるChatGPTの利用 プログラミング問題=初期状態(A)と終状態(D)を指 定して中身を考えてもらう問題。 実行することで(動作するという意味での)正確 性は判断できる。 しかし,GPTによるコード生成,プログラム動作 確認,エラーの指摘の一連のループだけでは必ず しも完成しない。→右図 結果に誤りがある可能性を必ず考慮する。 ある程度Pythonの知識があるとコードの誤り が分かる。 一見動作していても誤りがある可能性がある ので途中でチェックを行うなどの工夫が必要。 例)変数の表示。配列の大きさの比較。用 いているカラム名の表示など。 例)動作を確認しながら徐々に作る。 例)NewChatで新規作成して比較。 A B B’ B’’ ① C C’ C’’ 上流を変えると ② 簡単に解決でき る→NewChatを … 行う。 修正 実行時 エラー D ③繰り返すと,一見動作す るコードはできるかもしれ ない。 ④しかし,結果(D)が正確 かどうかは別の問題。
プログラミングにおけるChatGPTの利用 現状では,ChatGPTがあるとプログラミング言語やインフォマティクス(を勉強 しなくても/の知識が無くても)良いというわけでは無い。 しかし,ChatGPTを使わないのは他の人がChatGPTを使うので量で負ける。 以前よりも,人間が,多くの分野で(正確な)知識を持つ必要がある。 そのためにChatGPTを支援させるのが現在のところ妥当な使い方。 という印象を持つ。
引用元 • 使用した,同梱した英語フォントは https://commons.wikimedia.org/wiki/File:Old_English_typeface.svg から取得しました。 • 使用した,同梱した漢字フォントは「筆文字フリー素材集」 http://fudemoji-free.com/ から取得しました。 DOSデータ:Phys. Rev. Materials 6, 023802 のunpublished data