経営判断・発想支援
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
開始行:
[[由利恵]]
*目次 [#e890b3d5]
#CONTENTS
**目的 [#z78b3c7b]
近年,経営環境は大きく変化しており,いわゆるVUCA な時代を...
~
~
~
***使用するファイル全部 [#ta19c6d2]
|扱うデータ|用途|ファイル名|ファイルの場所|
|システムの内部処理|flaskを用いたシステムの記述|appli_2.p...
|ドライバーのファイル|自分の環境に合わせたChromeDriverの...
|staticファイル|javascriptや画像のファイルが入っている|st...
|↑の中身|3Dグラフを作成するときのjavascriptのファイル|mai...
|↑の中身|javascriptで読み込む用のjsonファイル|output.json...
|↑の中身|グラフのボタンを作成する用の画像|xy2.png/xyz2.pn...
|テキストデータ|集めてきたテキストデータの一時保存|text_d...
|ベクトル(数値)|2次元に圧縮したベクトル|vectors.pickle|...
|ベクトル(数値)|15次元に圧縮したベクトル|vectors_15.pic...
|シルエット係数|それぞれのクラス数におけるシルエット係数...
|クラスタリング結果|クラスタリングの結果のデータ|df_umap....
|simpson係数|simpson係数の値と単語の出現回数など|jaccard_...
|ユーザー辞書|各クラスターのユーザー辞書の保存|user_dic_{...
|共起語ネットワーク|2dの共起語ネットワークのhtmlファイル|...
~
*動かし方 [#ccda06db]
1.practiceの中のappli_2.pyを動かす.~
2.必要なモジュールをすべて入れる.(pip installなど)~
⚠umapとMeCabは少し名前が違うモジュールなので注意,そのほ...
-Sentence-BERTを動かすときに"fugashi"をインストールする必...
pip install umap-learn
pip install mecab-python3
2'.termextractはpipではインストールできないため別の入れ...
-詳しくは> [[termextract>#qbb8ab79]]
3.すべてのインストールが完了したらlocalhost:5000にアクセ...
⚠必ずlocalhost:5000にアクセス!~
-詳しくは>[[3Dグラフ>#gd773348]]~
*スクレピング処理 [#w90988e1]
***ChromeDriverのインストール [#j661bc61]
まず、ChromeDriverをインストールする.自身のGoogleChrome...
わからなかったらここを見て👇~
👉https://zenn.dev/ryo427/articles/7ff77a86a2d86a
~
**1.データ取得 [#c9661663]
***seleniumのインストール [#j661bc61]
seleniumをインストールする.バージョン3でもよいが,プログ...
<pythonのとき>
pip install selenium
<notebookのとき>
!python -m pip install selenium
***必要なモジュールをインポートする. [#h00fd477]
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
***driverのオプションを設定する. [#b380d497]
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
--headless ヘッドレスモード(バックグラウンドで起動)
--no-sandbox sandboxモードを解除する(クラッシュ回避)
--disable-dev-shm-usage パーティションが小さすぎることに...
***chromedriverのパスを設定する. [#b380d497]
インストールしたchromedriver.exeの場所を指定する.
driver_path = "chromedriver-win64/chromedriver.exe"
***driverを作成する. [#b380d497]
driver1 = webdriver.Chrome(service=ChromeService(driver_...
driver1.implicitly_wait(10)
--implicitly_wait(10) 指定した時間要素が見つかるまで待機.
⚠seleniumのバージョンによってコードの書き方が異なる場合が...
)
***urlの指定方法 [#uff6c3d3]
urlでユーザーからのキーワードと取得する年数を指定する.
url_1 = (
"https://patents.google.com/?q=("
+ str(keyword)
+ ")&before=priority:"
+ str(2000)
+ "1231&after=priority:"
+ str(2000)
+ "0101&sort=old"
)
--str(keyword):ここにユーザーから取得したキーワードを入...
--&before=priority:* + str(XXXX) + 1231&after=priority:...
➡priorityがXXXX年の0101(一月一日)から1231(十二月三十一...
***取得方法 [#c0fff484]
def W1(url):
driver1.get(url)
try:
results1 = driver1.find_element(
By.XPATH, '//*[@id="count"]/div[1]/span[1...
).text.replace(",", "")
if int(results1) <= 10:
p_n_1 = 1
else:
p_n_1 = int(results1) // 10
except Exception as e:
print("error")
for p1 in range(p_n_1 + 1):
driver1.get(url + "&page=" + str(p1))
link1 = driver1.find_elements(
By.XPATH,
'//*[@id="resultsContainer"]/section/sear...
)
for i1 in range(len(link1)):
try:
link_url1 = "https://patents.google.c...
"data-result"
)
patt1 = pat_text(link_url1)
patt1.get_soup()
# patt.get_title()
patt1.get_claims()
d_save1 = []
d_save1.append(patt1.get_description())
d_save1.append(link1[i1].get_attribut...
desc1.append(d_save1)
except Exception as e:
print(e)
1.urlから中身を取得する.~
2.find_elementで検索結果の数を取得する.~
3.{p_n_1}にページ数を渡す.(何ページあるのかを直接取得で...
--検索結果に表示された特許の数{results}が10以下ならp_n_1...
---resultsはGoogle Patantsに表示される「About ****** resu...
➡(結果の数値が4桁1,000などの場合は「,」があるとうまく処...
4.各ページの中から特許番号を取得する.~
--for文でページ分回す~
---driver1.get(url + "&page=" + str(p1))この部分でページ...
5.find_elementで特許番号(例:patent/JP5965646B2/ja)の部...
--link1にはそのページの取得した特許番号が含まれる要素がす...
---.get_attribute("data-results")の部分は実際の「patent/J...
6.取得した番号をもとにhtmlのurlを作成し,関数(pat_text)...
7.pat_textからの本文と特許番号をd_save1に渡す.~
👇実際の取得結果~
#ref(テキストフォーマット2.jpg)
~
~
**2.並列化 [#ad9614fa]
スクレイピングの高速化を試みた,今回はthreadsを用いて並列...
import threading
thr1 = threading.Thread(target=W1, args=(url_1,))
thr2 = threading.Thread(target=W2, args=(url_2,))
thr3 = threading.Thread(target=W3, args=(url_3,))
thr4 = threading.Thread(target=W4, args=(url_4,))
thr5 = threading.Thread(target=W5, args=(url_5,))
thr6 = threading.Thread(target=W6, args=(url_6,))
~~~~~省略~~~~~
thr24まで
~~~~~~~~~~~~
threadを一年ごとに設定する.~
それを6年ずつ実行する~
要素が混在しないように一年ごととそれぞれのスレッドごとにd...
desc01 = []
desc02 = []
desc03 = []
desc04 = []
if int(year) == 24:
#6年分
desc1 = []
desc2 = []
desc3 = []
desc4 = []
desc5 = []
desc6 = []
#各スレッドのスタート
thr1.start()
thr2.start()
thr3.start()
thr4.start()
thr5.start()
thr6.start()
#各スレッドの処理が終了するまで待機
thr1.join()
thr2.join()
thr3.join()
thr4.join()
thr5.join()
thr6.join()
desc01 = desc1 + desc2 + desc3 + desc4 + desc5 + ...
if int(year) == 18 or int(year) == 24:
~~~~~省略~~~~~
thr7からthr12まで
~~~~~~~~~~~~
desc02 = desc1 + desc2 + desc3 + desc4 + desc5 + ...
if int(year) == 12 or int(year) == 18 or int(year) ==...
~~~~~省略~~~~~
thr13からthr18まで
~~~~~~~~~~~~
desc03 = desc1 + desc2 + desc3 + desc4 + desc5 + ...
~~~~~省略~~~~~
thr19からthr24まで
~~~~~~~~~~~~
desc04 = desc1 + desc2 + desc3 + desc4 + desc5 + desc6
-選択された年数によって動かす処理の数を変えている.
最後に各スレッドのdescを合わせる
desc = desc01 + desc02 + desc03 + desc04
~
**3.保存の仕方と例外 [#c1eb3f9b]
ほかのルーティングでテキストデータを参照したい場合がある.~
csvに保存してもよいが,文字化けなどの可能性もあるため今回は
pickleモジュールを用いてpickle形式のファイルで保存する.~
-保存する場合
with open('text_data.pickle', mode='wb') as fo:
pickle.dump(desc,fo)
--保存される元のデータは{desc}
--保存先のpickleファイルは{text_data.pickle}
-呼びだしたい場合
with open('text_data.pickle', mode='br') as fi:
desc = pickle.load(fi)
--読み込むpickleファイルは{text_data.pickle}
--保存先の変数は{desc}
最後に,取得できたデータの要素数によって例外処理を追加す...
要素数が0の場合に正しく動作しないことや,要素数が少なすぎ...
desc_len = len(desc)
if desc_len < 30:
return redirect(url_for('start'))
-{desc}の要素数が30未満の時はredirectでstart(トップペー...
*Sentence-BERT [#u506e563]
事前学習モデルは”sonoisa/sentence-bert-base-ja-mean-token...
model = SentenceBertJapanese("sonoisa/sentence-bert-base...
-モデルの指定はここで行う.~
SentenceBertJapaneseの中身はここを参照👇~
👉https://huggingface.co/sonoisa/sentence-bert-base-ja-me...
~
~
*UMAP [#d75a68f0]
UMAPでSentence-BERTから得られたベクトルを2次元と15次元に...
-15次元のベクトルは後述するクラスタリングなどに用いる.
-2次元のベクトルは散布図のプロットに用いる.
**UMAPのパラメータ [#w17b6077]
-n neighbors>
n_neighbors パラメータは,各データポイントの埋め込みにお...
点の数を指定する.~
-min_dist>
min_distパラメータは,UMAP によって生成される低次元埋め込...
タ点間の最小距離を制御する.~
-n_components>
n_components パラメータは,UMAP によって生成される埋め込...
を指定する.~
-metric>
metricパラメータは,データ間の類似度や距離を算出するため...
ことができる.~
実際の値
sentence_vectors_umap_15 = umap.UMAP(n_components=15,
random_state=42,
n_neighbors = 25,
min_dist = 0.1,
metric = 'cosine')....
上記は15次元の場合,2次元にするときはn_componentsの値を2...
ベクトル化されたデータもpickleを用いて保存しておく.~
with open('vectors_15.pickle', mode='wb') as fo:
pickle.dump(sentence_vectors_umap_15, fo)
with open('vectors.pickle', mode='wb') as fo:
pickle.dump(sentence_vectors_umap_2, fo)
~
*シルエット分析 [#e6771c98]
K-medoidsでクラスタリングを行うために最適なクラスター数を...
シルエット分析はクラスタリング結果における凝縮度と乖離度...
クラスター数が3から19まで(20以上だと多すぎるかな?)のシ...
-プログラム
def show_silhouette(labels):
cluster_labels = np.unique(labels)
num_clusters = cluster_labels.shape[0]
silhouette_vals = silhouette_samples(data, labels) ...
# 可視化
y_ax_lower, y_ax_upper = 0, 0
y_ticks = []
for idx, cls in enumerate(cluster_labels):
cls_silhouette_vals = silhouette_vals[labels==cls]
cls_silhouette_vals.sort()
y_ax_upper += len(cls_silhouette_vals)
y_ticks.append((y_ax_lower + y_ax_upper) / 2.0)
y_ax_lower += len(cls_silhouette_vals)
silhouette_avg = np.mean(silhouette_vals)
silhouette_df.append(silhouette_avg)
-実際の結果
#ref(シルエット.png)
この場合は一番シルエット係数が高い15を最適なクラスター数...
~
*クラスタリング [#cda78d69]
クラスタリングにはk-medoidsを用いる.~
k-meansではデータの外れ値が大きい場合,クラスタリングの結...
-クラスタリングを行った結果はそれぞれのベクトルにクラスタ...
df_umap_2 = pd.DataFrame(data=sentence_vectors_umap_2, c...
df_umap_2["class"] = ["cluster"+str(x) for x in predicte...
df_umap_15 = pd.DataFrame(data=sentence_vectors_umap_15,...
df_umap_15["class"] = ["cluster"+str(x) for x in predict...
df_umap_2.to_pickle('df_umap.pkl')
~
**タイトルの提示 [#sd94bd78]
各データの重心とのユークリッド距離を計算する.~
centers = kmeans_model.cluster_centers_
df_umap_15["distance"] = np.nan
for j in range(class_n):
class_name = str("cluster" + str(j))
d = df_umap_15[df_umap_15["class"] == class_name]
for i in range(d.shape[0]):
v = d.iloc[i, :]
v = v[:-2]
distances = np.subtract(v, centers[j])
distances_squared = np.square(distances)
distance1 = np.sqrt(np.sum(distances_squared))
df_umap_15.at[d.index[i], "distance"] = distance1
-df_umap_15に新しくdistanceという列を追加する.
--最初に列を追加する理由は,後から入れると,最初はdistanc...
df_umap_15["distance"] = np.nan
-dfの横列にはベクトルにプラスして「クラス番号」と「distan...
そこで,vのサイズをcentersと合わせるために後ろの2つの要素...
v = v[:-2]
-求められた距離を求めたデータに対応付けて"distance"に代入...
df_umap_15.at[d.index[i], "distance"] = distance1
~
それぞれのクラスについて先ほど求めたdistanceを用いてタイ...
for a in tqdm.tqdm(range(class_n)):
vec_dis = df_umap_15[df_umap_15["class"] == "cluster...
vec_dis_sorted = vec_dis.sort_values('distance')
title_all = []
# #ランダム
# if text.shape[0] >= 10:
# random_n = 10
# else:
# random_n = text.shape[0]
# for i in tqdm.tqdm(random.sample(range(text.shape[...
for i in tqdm.tqdm(range(vec_dis_sorted.head(10).sha...
# target_text = text.iloc[i][0]
target_text = pd.DataFrame(df[0]).loc[vec_dis_so...
tagged_text = get_mecab_tagged(target_text)
terms = term_ext(tagged_text)
compound = remove_single_words(terms)
title_all.extend([termextract.core.modify_agglut...
set1 = sorted([k for k, v in collections.Counter(tit...
title.append("/".join(set1[0:3]))
+クラスに含まれる要素を取り出す.
+その要素を{distance}が小さい順に並べ替える.
+小さいものから10個取り出す.
➡それらが10個未満の場合はすべて取り出す.
+重要語を計算し,その中から重要度が高いものを取り出す.
title_all.extend([termextract.core.modify_agglutinative_...
↳それぞれの文章からトップ3を抜き出す.
set1 = sorted([k for k, v in collections.Counter(title_a...
↳それらを重要度が高い順に並べ替える.
title.append("/".join(set1[0:3]))
↳最後にトップ3を抜き出す.
**散布図グラフの描画 [#qe5ab135]
散布図の描画は2次元で行う.~
また,散布図の下には各クラスターの内容を表示する.~
散布図にはデータのプロットと,データのクラスリングの結果...
クラスタリング結果の見方は,データの色と点の形からクラス...
その番号とクラスターの内容を照らし合わせる.~
marker_styles = [
".",
",",
"o",
"v",
"^",
"<",
">",
"1",
"2",
"3",
"4",
"8",
"s",
"p",
"*",
"h",
"H",
"+",
"x",
"D",
"d",
]
-グラフに表示するときの点の形を事前に定義する.
**グラフの画像保存 [#h6adf354]
作成されたグラフは画像形式度保存してhtml上に出力する.
buf: BytesIO = BytesIO()
# figure.savefig(buf, format='png')
figure.savefig(buf, bbox_inches="tight")
with buf:
data = buf.getvalue()
img_data = base64.b64encode(data).decode("ascii")
img_src: str = "data:image/png;base64," + img_data
-matplotlibで作成したグラフを画像形式で保存する.保存した...
**htmlでの表示 [#xe6ab4e0]
<div style="height: 50%;">
<a href="{{ img_src }}" data-lightbox="group"><img s...
</div>
-上記のように表示する.~
~
-実際の結果
#ref(散布図.jpg)
~
*選択したクラスターとグラフの大きさ [#je205489]
**クラスターに含まれる特許 [#db28ac17]
選択したクラスターに含まれている特許の実際のGoogle Patent...
スクレイピングの時に取得した特許番号の部分を使ってurlを作...
詳しく知りたい場合はjinja2のfor文の書き方を調べるとよい.~
-select.html
<h1>特許一覧</h1>
{% for x in plat_index %}{%set plat_index_loop = loop %}
{% for y in plat_index2 %}{%if loop.index==plat_index_lo...
<ul>
<a href=https://patents.google.com/{{x}} target="_bl...
</ul>
{% endif %}
{% endfor %}
{% endfor %}
**グラフの大きさの選択 [#pee44f2c]
グラフの大きさを描画する共起関係の数をもとに設定する.
-select.html
<form action="/graph" method="POST">
<div class="flexbox">
<div class="flex-item">
<button type="submit" style="height: 250px;">
<img src="static/xyz2.png" alt="Button I...
</button>
</div>
<div style="font-size:large" class="flex-item">3...
<div class="yoko">
<label>
<input type="radio" name="3g_size" class...
</label>
<label>
<input type="radio" name="3g_size" class...
</label>
<label>
<input type="radio" name="3g_size" class...
</label>
</div>
</div>
</form>
*分かち書き [#ldc6d820]
**termextract [#qbb8ab79]
専門用語や複合語などを抽出するためのモジュール
***モジュールの入れ方 [#q35d9ead]
以下のサイトからtermextractをダウンロードする.~
~
👉http://gensen.dl.itc.u-tokyo.ac.jp/pytermextract/~
ダウンロードしたら,ダウンロード先のファイル(termextract...
コマンドプロンプトで,以下の操作を行う.~
pip install .
~
***core.pyの変更 [#pd0b1db6]
既存のcore.pyを用いるとエラーが起こる場合があるため変更す...
まず自身のパソコンのtermextractがインストールされているフ...
-保存場所の確認方法
import termextract
print(termextract.__path__)
このファイルの中のcore.pyを変更する.(今回はcore2.pyとし...
core2.pyにした時のモジュールの定義
import termextract.core2
~
変更箇所
from decimal import Decimal
~~~~~~~~~~~~~~~~~~~
84| importance = Decimal(importance) ** (1 / (2 * Decima...
~~~~~~~~~~~~~~~~~~~
エラーが起こる理由はおそらく重要度を計算するときに,計算...
~
**Janomeの辞書登録 [#c7686f71]
termextractの出力結果をもとにJanomeの辞書の登録を行う.~
csv形式で与えることでユーザー辞書を登録することができる.~
termextactはjanomeを用いる元のmecabを用いるものがあるが,...
-termextractの定義部分~
CHASEN_ARGS = r' -F "%m\t%f[7]\t%f[6]\t%F-[0,1,2,3]\t%f[...
CHASEN_ARGS += r' -U "%m\t%m\t%m\t%F-[0,1,2,3]\t\t\n"'
m = MeCab.Tagger(ipadic.MECAB_ARGS + CHASEN_ARGS)
m.parse('')
def get_mecab_tagged(text):
node = m.parseToNode(text)
buf = ''
while node:
if node.surface:
buf += node.surface + '\t' + node.feature + ...
node = node.next
return buf
def term_ext(tagged_text):
frequency = termextract.mecab.cmp_noun_dict(tagged_t...
lr = termextract.core2.score_lr(
frequency,
ignore_words=termextract.mecab.IGNORE_WORDS,
lr_mode=1, average_rate=1)
term_imp = termextract.core.term_importance(frequenc...
return Counter(term_imp)
def remove_single_words(terms):
c = Counter()
for cmp, value in terms.items():
if len(cmp.split(' ')) != 1:
c[termextract.core.modify_agglutinative_lang...
return c
-辞書作成部分
for i in tqdm.tqdm(range(text.shape[0])):
target_text = text.iloc[i][0]
tagged_text = get_mecab_tagged(target_text)
terms = term_ext(tagged_text)
compound = remove_single_words(terms)
for cmp_noun, value in compound.most_common(10):
# print(termextract.core.modify_agglutinative_la...
df_frequency.append(termextract.core.modify_aggl...
app_list = [-1, -1, 1000, '名詞', '固有名詞', '*', '...
app_list2 =['*', '*']
for i in range(len(df_frequency)):
df_append=[]
df_append.append(df_frequency[i])
df_append.extend(app_list)
df_append.append(df_frequency[i])
df_append.extend(app_list2)
df_csv_frequency.append(df_append)
df_dictio=pd.DataFrame(df_csv_frequency)
df_dictio.to_csv("user_dic_" + str(class_set) +".csv", s...
-実際のcsvファイル
#ref(ユーザー辞書2.png)
**分かち書き処理 [#pe2962a7]
sentences = []
sentences_2 = []
for i in tqdm.tqdm(range(text.shape[0])):
target_texts = text.iloc[i]
t = Tokenizer('user_dic_' + str(class_set) +'.csv', ...
texts = target_texts.str.split('。')
wakati_list = []
for s in texts[0]:
words = []
for token in t.tokenize(s):
s_token = token.part_of_speech.split(',')
# 一般名詞、自立動詞(「し」等の1文字の動詞...
if (s_token[0] == '名詞' and s_token[1] == '...
or (s_token[0] == '形容詞' and s_tok...
or (s_token[0] == '名詞' and s_token...
words.append(token.surface)
wakati_list.append(words)
sentences.append(wakati_list)
sentences_2.extend(wakati_list)
# combination_sentences = []
# for words in tqdm.tqdm(sentences_2):
combination_sentences = [list(itertools.combinations(wor...
combination_sentences = [[tuple(sorted(combi)) for combi...
tmp = []
for combinations in combination_sentences:
tmp.extend(combinations)
combination_sentences = tmp
touroku_list = []
for i in tqdm.tqdm(range(len(combination_sentences))):
if (combination_sentences[i][0] in df_frequency) or ...
touroku_list.append(combination_sentences[i])
-df_frequency[]~
それぞれの文章から最大10個重要度が高い順にdf_frequencyに...
for cmp_noun, value in compound.most_common(10):
df_frequency.append(termextract.core.modify_agglutin...
-combination_sentences~
分かち書きで抽出された単語同士の文章中での組み合わせを列...
例:[今日,私,学校,行った]➡[今日,私],[今日,学校],[...
combination_sentences = [list(itertools.combinations(wor...
combination_sentences = [[tuple(sorted(combi)) for combi...
tmp = []
for combinations in combination_sentences:
tmp.extend(combinations)
combination_sentences = tmp
-touroku_list[]~
分かち書きの結果をそのまま使うと,一般的な用語が多く含ま...
そのため,df_frequencyに登録されている重要語が高い用語が...
combination_sentencesの中に重要語が含まれていればそれをto...
for i in tqdm.tqdm(range(len(combination_sentences))):
if (combination_sentences[i][0] in df_frequency) or ...
touroku_list.append(combination_sentences[i])
*共起語ネットワーク [#raa586e3]
**共起関係の導出 [#z9e7882e]
Jaccard係数,Dice係数,Simpson係数の計算を行う.(実際に...
それぞれの係数の値は{jaccard_coef}に格納されている.(変...
-Simpson係数の計算
def make_overlap_coef_data(combination_sentences):
combi_count = collections.Counter(combination_senten...
word_associates = []
for key, value in combi_count.items():
word_associates.append([key[0], key[1], value])
word_associates = pd.DataFrame(word_associates, colu...
words = []
for combi in combination_sentences:
words.extend(combi)
word_count = collections.Counter(words)
word_count = [[key, value] for key, value in word_co...
word_count = pd.DataFrame(word_count, columns=['word...
word_associates = pd.merge(
word_associates,
word_count.rename(columns={'word': 'word1'}),
on='word1', how='left'
).rename(columns={'count': 'count1'}).merge(
word_count.rename(columns={'word': 'word2'}),
on='word2', how='left'
).rename(columns={'count': 'count2'}).assign(
union_count=lambda x: np.minimum(x.count1,x.coun...
).assign(
count_diff=lambda x: np.abs(x.count1 - x.count2)
).assign(jaccard_coef=lambda x: x.intersection_count...
['jaccard_coef', 'intersection_count'], ascendin...
)
--count_diff~
お互いの集合の要素差を求めている
--union_count~
count1とcount2の小さいほうを求める.
--jaccard_coef~
intersection_countをunion_countで割る
-Jaccard係数の計算
~~~~~~~~~~同文~~~~~~~~~~
word_associates = pd.merge(
word_associates,
word_count.rename(columns={'word': 'word1'}),
on='word1', how='left'
).rename(columns={'count': 'count1'}).merge(
word_count.rename(columns={'word': 'word2'}),
on='word2', how='left'
).rename(columns={'count': 'count2'}).assign(
union_count=lambda x: x.count1 + x.count2 - x.in...
).assign(jaccard_coef=lambda x: x.intersection_count...
['jaccard_coef', 'intersection_count'], ascendin...
)
--intersection_count~
要素の共通部分の数
--union_count~
count1とcount2の合計からintercsection_countを引くことで,...
--jaccard_coef~
intersection_countをunion_countで割る
-Dice係数の計算
~~~~~~~~~同文~~~~~~~~~~
word_associates = pd.merge(
word_associates,
word_count.rename(columns={'word': 'word1'}),
on='word1', how='left'
).rename(columns={'count': 'count1'}).merge(
word_count.rename(columns={'word': 'word2'}),
on='word2', how='left'
).rename(columns={'count': 'count2'}).assign(
union_count=lambda x: x.count1 + x.count2
).assign(jaccard_coef=lambda x: 2 * x.intersection_c...
['jaccard_coef', 'intersection_count'], ascendin...
)
--union_ount~
count1とcount2の合計
--jaccard_coef
intersection_countの2倍をunion_countで割る.
実際の出力結果
#ref(関係.jpg)
-intersection_countにはword1とword2が同時に出てくる回数.
-count1はword1の出現回数
-count2はword2の出現回数
-union_countはcount1とcount2の小さいほうの数
-count_diffはcount1とcount2の要素数の差
-jaccard_coefはsimpson係数の値
⚠カラムの名前が混在しているので注意!
***しきい値の設定 [#ydce4187]
より良い結果を得るためにしきい値を設定する.
具体的には
+Simpson係数が1未満のもの
+お互いの要素差が5000未満のもの
jaccard_coef_data = make_overlap_coef_data(touroku_list)
simpson = jaccard_coef_data['count_diff']
simpson2 = jaccard_coef_data['jaccard_coef']
filt = (simpson < 5000) & (simpson2 < 1)
jaccard_coef_data[filt].to_pickle('jaccard_coef.pkl')
**jsonファイルの作成 [#pe7fdb90]
3D Force-Directed Graphに共起関係の情報を送るためにjsonフ...
simpson係数の結果からjsonファイルに変換する
jaccard_coef_data = pd.read_pickle('jaccard_coef.pkl')
got_data = jaccard_coef_data.head(int(g_size))
sources = got_data['word1']#count
targets = got_data['word2']#first
edge_data = zip(sources, targets)
count_list_df = pd.DataFrame([{'first' : i[0], 'second' ...
count_id = count_list_df.stack().drop_duplicates().tolis...
word1 = got_data[['word1','count1']].rename(columns={ 'w...
word2 = got_data[['word2','count2']].rename(columns={ 'w...
df_word_count = pd.concat([word1, word2]).drop_duplicate...
def create_json(nodes, links):
json_data = {
"nodes": nodes,
"links": links
}
return json_data
edge_data = zip(sources, targets)
nodes = []
for _, row in df_word_count.iterrows():
node = {"id": row['word'], "group": 1}
if row['count'] > 3000:
node['group'] = 2
nodes.append(node)
links = [{"source": values[0], "target": values[1], "val...
json_data = create_json(nodes, links)
with open('static/output.json', 'w', encoding='utf-8') a...
json.dump(json_data, json_file, ensure_ascii=False, ...
作成するjsonファイルの形式(output.json)
{
"nodes": [
{
"id": "砂利",
"group": 1
},
{
"id": "実施形態",
"group": 2
},
~~~~~~~~~~省略~~~~~~~~~~
{
"id": "残雪",
"group": 1
},
{
"id": "上顎",
"group": 1
}
],
"links": [
{
"source": "砂利",
"target": "骨材",
"value": 1
},
{
"source": "咬合部",
"target": "歯列",
"value": 1
},
~~~~~~~~~~省略~~~~~~~~~~
{
"source": "ヒドロキシ",
"target": "紫外線吸収剤",
"value": 1
},
{
"source": "実施形態",
"target": "符号",
"value": 1
}
]
}
-"nodes"にはグラフに表示される単語の定義を行う.~
--"id"はノードの単語.~
--"group"は色分けなどをしたいときにノードのグループを指定...
-"links"には共起関係を記述する.~
--"source"は共起元の単語.~
--"target"は共起先の単語.~
--"value"は結ぶ線の大きさを変更するときなどに利用される.~
**3Dグラフ [#gd773348]
3Dグラフの描画にはThree.jsのモジュール”3D Force-Directed ...
参考にしたサイト👉https://vasturiano.github.io/3d-force-g...
javascriptの買い方はサイトを参考にすれば様々な変更が可能.~
⚠モジュールのインポート方法はサイトのものでは行えなかった...
-graph.html
<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<style>body{margin: 0px; padding: 0px;}</style>
</head>
<body>
<button type="button" onclick="history.back()">戻る</b...
<div id="three" style="background-color: aliceblue;"><...
<script type="module" src="https://unpkg.com/three@0.1...
<script type="module" src="https://unpkg.com/3d-force-...
<script type="module" src="https://unpkg.com/three-spr...
<script src="./static/main2.js" charset="utf-8" defer>...
</body>
</html>
--<script type="module" src="https://unpkg.com/three@0.15...
three.jsのインポート
--<script type="module" src="https://unpkg.com/3d-force-g...
3D Force-Directed Graphのモジュールのインポート
--<script type="module" src="https://unpkg.com/three-spri...
テキストをノードにするときに必要なモジュールのインポート
--<script src="./static/main2.js" charset="utf-8" defer><...
プログラムに使うjavascriptのファイルの指定
-main2.js
const highlightLinks = new Set();
const highlightNodes = new Set();
let hoverNode = null;
const Graph = ForceGraph3D()
(document.getElementById("three"))
.jsonUrl('http://localhost:5000/static/output.json')
.nodeLabel('id')
.nodeRelSize(20)
.nodeThreeObject(node => {
const sprite = new SpriteText(node.id);
const group = new SpriteText(node.group)
// const sprite = new SpriteText(`${link.source} ...
sprite.material.depthWrite = false; // make sprit...
if (node.group == '2') {
sprite.color = 'red';
} else {
sprite.color = 'black'
}
sprite.textHeight = 7.5;
return sprite;
})
.onNodeClick(node => {
const distance = 100;
const distRatio = 1 + distance/Math.hypot(node.x,...
const newPos = node.x || node.y || node.z
? { x:node.x * distRatio, y: node.y * distRatio, ...
: { x: 0, y: 0, z: distance};
Graph.cameraPosition(
newPos,
node,
100
)
})
// link
.linkOpacity(0.25)
.linkDirectionalArrowLength(3)
.linkDirectionalArrowRelPos(1)
.linkCurvature(0.01)
.linkDirectionalParticleWidth(2)
.linkDirectionalParticles("value")
.linkDirectionalParticleSpeed(d => d.value * 0.01)
.linkThreeObjectExtend(true)
.linkColor(() => '#708090')
.linkWidth(1)
.backgroundColor("#f8f8f8");
-ここで共起関係を記述したjsonファイルを指定している.~
⚠ここのパスにlocalhost:5000を指定しているため,ローカルで...
.jsonUrl('http://localhost:5000/static/output.json')
-実際に共起語の描画の処理を行っている.~
ノードの色の変更の処理もここで行う.~
.nodeThreeObject
-初期設定だとグラフの回転軸が中央で固定になってしまうため...
.onNodeClick
-矢印の設定もろもろ
.linkOpacity(0.25)
.linkDirectionalArrowLength(3)
.linkDirectionalArrowRelPos(1)
.linkCurvature(0.01)
.linkDirectionalParticleWidth(2)
.linkDirectionalParticles("value")
.linkDirectionalParticleSpeed(d => d.value * 0.01)
.linkThreeObjectExtend(true)
.linkColor(() => '#708090')
.linkWidth(1)
--linkDirectionalParticlesはノードの矢印にアニメーション...
-初期設定では背景の色が黒色だが見にくいため白色に変更して...
.backgroundColor("#f8f8f8")
htmlの
<div id="three" style="background-color: aliceblue;"></d...
javascritpの
<div id="three" style="background-color: aliceblue;"></d...
の部分のidが同じになっていないといけないので注意.
~
実際の出力結果
#ref(3d.jpg)
~
*その他 [#dd9fe27e]
**ロード画面 [#bcf8e2e2]
スクレイピングなどの処理を行っているとき画面がそのままだ...
<div id="loading">
<p>作成中...</p>
</div>
<script>
window.addEventListener('DOMContentLoaded', function...
// ページの表示状態が変わったときに実行
document.addEventListener("visibilitychange", fu...
console.log(document.visibilityState);
document.getElementById('loading').style.display...
});
});
function performSearch() {
var loadingScreen = document.getElementById('loa...
// ロード画面を表示
loadingScreen.style.display = 'flex';
}
</script>
-<div>タグの<p>の中身を変更すれば画面に表示される文字が変...
-ページをブラウザバックしたときにロード画面がそのままにな...
⚠別のタブに移動したときも消えるので注意!
**ブラウザバック [#dcb69e5a]
ブラウザバックをしたときにフォームなどのユーザからの入力...
-ページ遷移するときにそのまま処理の部分に飛ぶのではなく以...
@app.route('/post', methods=['POST'])
def post():
session["class"] = request.form.get("class_select")
return redirect(url_for('select'))
@app.route("/select", methods=["GET", "POST"])
def select():
if 'class' not in session:
return redirect(url_for('select'))
class_set = session["class"]
~~~~~~~~~~省略~~~~~~~~~~
[[技術資料]]
*目次 [#m8988ea1]
#CONTENTS
*目的 [#q895f5ba]
産業連関表を活用した為替変動による波及効果の分析, 金融経...
*使用するファイル [#pe64d1b6]
本研究で使用するファイルはすべてGoogleDriveにある.
&br;
user:iie.lab.tpu.2324@gmail.com
&br;
「マイドライブ」→「学生」→「24_r2戸田」→「保存期間5年」→...
&br;
すべてのzipをダウンロードする.~
&color(red){中山実行プログラム};
#ref(中山実行プログラム.zip)
|フォルダ名|用途|ファイル名|ファイルの場所|
|kawasehendou|為替変動の影響分析|''&color(red){7to12_Yfin...
|kabuka|株価データのデータ収集|''&color(red){7to12_JPX401...
|sankakuka_2|産業連関表の三角化|''&color(red){sankakuka_2...
|soukan|相関ヒートマップの作成|''&color(red){soukan_7to12...
|3Dgraph|jsonファイルの作成|''&color(red){3Dgraph_kihon.i...
|3Dgraph|3Dグラフを可視化するための実行ファイル|app_0114....
|3Dgraph|javascriptで読み込む用のjsonファイル|output_toda...
|3Dgraph|3Dグラフのデータの可視化|index_0114.html|3Dgraph...
|3Dgraph|3Dグラフを作成するときのjavascriptのファイル|mai...
~
***プログラムを修正する [#zb7feed2]
上記で''&color(red){あかで書かれているプログラム};''は,~
csvファイルを書きこんだり,読みこんだりするときに,絶対パ...
そのままでは,「''C:/Users/ta_na/''/...」になっているはず...
その「''C:/Users/ta_na/''」のところを,''すべてのプログラ...
上記でフォルダを置いた絶対パスに修正する必要がある.~
「Visual Studio Code」では,特定の文字列をすべて別の文字...
置換する機能があるので,それを利用しよう.~
***動作環境 [#x9020b74]
Pythonのバージョンは3.12.4を用いる
|ライブラリ名|バージョン|
|selenium|4.27.1|
|panads|1.3.5|
|numpy|1.26.4|
|yfinance|0.2.52|
|matplotlib|3.9.2|
|webdriver-manager|4.0.2|
|beautifulsoup4|4.12.3|
|seaborn|0.13.2|
|pulp|2.9.0|
|networkx|3.4.2|
|flask|3.0.3|
~
モジュールのインストールはコマンドプロンプトでpip install...
バージョンまで指定する場合はコマンドプロンプトでpip insta...
でインストールする
~
*** 各プログラムを実行する [#ce4e9821]
各プログラムを,以下のとおり,''&color(red){順番に};''実...
――――――――――――――~
''1. 7to12_Yfinance.ipynb''~
''2. sankakuka_2020.py''~
''3. 3Dgraph_kihon.ipynb''~
''4. app_0114.py''~
''5. 7to12_JPX401.ipynb''~
''6. soukan_7to12_map_yfinance.ipynb''~
――――――――――――――~
*産業連関分析 [#ea813e90]
**投入係数行列の作成 [#i8722536]
-7to12_Yfinance.ipynb
import numpy as np
import pandas as pd
#2020年国産表37部門
df_kokusan = pd.read_csv("C:/Users/ta_na/OneDrive/デス...
# 3行目以降(インデックス 2 以降)、3列目以降(インデッ...
subset_df_kokusan = df_kokusan.iloc[3:,2:]
# データ型を確認し、必要ならfloatに変換
subset_df_kokusan = subset_df_kokusan.astype(float)
# インデックスをリセットして1からの連番にする
subset_df_kokusan.reset_index(drop=True, inplace=True) ...
subset_df_kokusan.index = subset_df_kokusan.index + 1 ...
# 列名をリセットして1からの連番にする
subset_df_kokusan.columns = range(1, len(subset_df_koku...
#内生部門だけ抽出
# インデックスと列の39以降を削除(1始まりの場合)
subset_df_kokusan = subset_df_kokusan.loc[:37, :37]
print(subset_df_kokusan)
取得した産業連関表から内生部門(37×37の行列)を抜き出す.
~
#国内生産額の抽出
# インデックス48番の行を取得
row_48 = df_kihon.loc[48]
# NaN を含む行を削除
kokunaiseisan_row = row_48.dropna()
# 最初の2行と最後の1行を削除
kokunaiseisan_row = kokunaiseisan_row.iloc[2:-1]
# データ型を確認し、必要ならfloatに変換
kokunaiseisan_row = kokunaiseisan_row.astype(float)
# インデックスをリセットして1からの連番にする
kokunaiseisan_row.reset_index(drop=True, inplace=True) ...
kokunaiseisan_row.index = kokunaiseisan_row.index + 1 ...
print(kokunaiseisan_row)
産業連関表から国内生産額を抽出する.
#粗付加価値額の抽出
# インデックス47番の行を取得
row_47 = df_kihon.loc[47]
# NaN を含む行を削除
arahukakathi_row = row_47.dropna()
# 最初の2行と最後の1行を削除
arahukakathi_row = arahukakathi_row.iloc[2:-1]
# データ型を確認し、必要ならfloatに変換
arahukakathi_row = arahukakathi_row.astype(float)
# インデックスをリセットして1からの連番にする
arahukakathi_row.reset_index(drop=True, inplace=True) ...
arahukakathi_row.index = arahukakathi_row.index + 1 ...
print(arahukakathi_row)
産業連関表から粗付加価値額を抽出する.
# 国産品投入係数行列を計算
coefficient_matrix_kokusan = subset_df_kokusan.div(koku...
coefficient_matrix_kokusan
国産品投入係数行列を作成
# 粗付加価値率(国内生産額÷粗付加価値額)を計算
coefficient_matrix_arahukakathi = arahukakathi_row / ko...
coefficient_matrix_arahukakathi
#こっちのyfinanceのドル円レートを使う
import yfinance as yf
import pandas as pd
# USD/JPYの為替データを取得
usd_jpy = yf.download("JPY=X", start="2024-07-01", end=...
# 終値を取得(Series にする)/ここから、変更が必要にな...
usd_jpy = usd_jpy[['Close']].reset_index().set_index('D...
# 結果を表示
print(type(usd_jpy))
# 結果を表示
print(usd_jpy)
※DataframeがSeriesに変換されない場合、各々で調べてコード...
Seriesに変換されていない場合、この先でエラーが発生する.~
※Yahoo Finance(YF)のAPIやウェブサービスを使用してUSD/JP...
→時間をおいて再度リクエストを試す
※''&color(red){yfinanceのバージョンを0.2.52};''に必ずする...
# 一日の変動率を計算する(当日−前日)/前日
daily_change_rate = usd_jpy.pct_change() * 100
# 最初の1行を削除
daily_change_rate = daily_change_rate.iloc[1:]
# 結果を表示
print(daily_change_rate)
**輸入価格変動の影響 [#x8fea72e]
# 米ドル建て輸入比率を辞書形式で定義
import_ratio_data = {
"食料品・飼料": 56.2,
"繊維品": 36.8,
"金属・同製品": 79.6,
"木材・同製品": 77.1,
"石油・石炭・天然ガス": 97.3,
"化学製品": 28.1,
"はん用・生産用・業務用機器" : 39.3,
"電気・電子機器" : 68.5,
"輸送用機器" : 37.8,
"その他産品・製品" : 62.6,
"輸入計" : 64.4
}
# データをリストに変換
import_ratio_list = [{"カテゴリ": category, "比率": rat...
# 米ドル建て契約比率
R_yunyu = pd.Series([56.2, 79.6, 56.2, 36.8, 77.1, 28.1...
# 産業名リスト
industry_names = [
"農林漁業", "鉱業", "飲食料品", "繊維製品", "パルプ・...
"プラスチック・ゴム製品", "窯業・土石製品", "鉄鋼", "...
"生産用機械", "業務用機械", "電子部品", "電気機械", "...
"建設", "電力・ガス・熱供給", "水道", "廃棄物処理", "...
"情報通信", "公務", "教育・研究", "医療・福祉", "他に...
"対個人サービス", "事務用品", "分類不明"
]
輸入価格変動の影響を求める際に輸入品価格ベクトル Pim を,...
~
各産業の米ドル建て契約比率には日本銀行「輸出・輸入物価指...
2023 年 12 月の値を用いた
https://www.boj.or.jp/statistics/outline/exp/pi/cgpi_2020...
~
#輸入の影響
# 日付ごとの結果を格納する辞書
result_yunyu_dict = {}
# 各日付ごとに計算を実施
for date, delta_E in daily_change_rate.items():
#print(delta_E)
# Delta_P_im の計算
delta_P_im_yunyu = R_yunyu * (-delta_E) / 100 # 各...
# 一次波及の計算
# delta_P_im に一致するインデックスを coefficient_m...
common_indices =
coefficient_matrix_yunyu.index.intersection(delta_P_im_...
sub_matrix = coefficient_matrix_yunyu.loc[common_in...
delta_P_d_1 = sub_matrix.multiply(delta_P_im_yunyu[...
# 完全波及の計算
# 1. I - A_d^T を計算
I = np.eye(len(coefficient_matrix_kokusan)) # 単位...
I_minus_Ad_T = I - coefficient_matrix_kokusan.T.val...
# 2. 逆行列を計算
I_minus_Ad_T_inv = np.linalg.inv(I_minus_Ad_T)
# 3. A_mi^T を計算
A_mi_T = coefficient_matrix_yunyu.T.values
# 4. ΔP_d を計算
delta_P_d_2 = I_minus_Ad_T_inv @ (A_mi_T @ delta_P_...
# 結果を Pandas の Series として保存
delta_P_d_2 = pd.Series(delta_P_d_2, index=range(37))
# インデックスをリセットして1からの連番にする
delta_P_d_2.reset_index(drop=True, inplace=True) #...
delta_P_d_2.index = delta_P_d_2.index + 1 # ...
# 付加価値を分母にしたものに変換
result_yunyu = delta_P_d_2 / coefficient_matrix_ara...
# インデックスを産業名に置き換える
result_yunyu.index = industry_names
# 結果を辞書に保存
result_yunyu_dict[date] = result_yunyu
# 各日付の結果を表示(例)
for date, result in result_yunyu_dict.items():
print(f"=== {date} ===")
print(result)
print("\n")
#ref(nikkei2.png,,720x400)
以下のリンク先の資料の6,7ページ目の計算のプログラムコード
https://www.jcer.or.jp/jcer_download_log.php?post_id=5528...
# 産業・日付ごとのデータを DataFrame に変換
all_results_yunyu = []
for industry in industry_names:
for date, result in result_yunyu_dict.items():
value = result[industry]
all_results_yunyu.append({"日付": date, "産業":...
result_df_yunyu = pd.DataFrame(all_results_yunyu)
print(result_df_yunyu)
# CSV 保存
#result_df_yunyu.to_csv("csv/out_data/industry_date_yun...
index=False, encoding="utf-8-sig")
# 日付を統一形式に変換
result_df_yunyu['日付'] = pd.to_datetime(result_df_yuny...
format='%Y.%m.%d')
# ピボットテーブルで変換
reshaped_df_yunyu = result_df_yunyu.pivot(index='日付',...
# 列名をリセットし、日付を列として戻す
reshaped_df_yunyu.reset_index(inplace=True)
reshaped_df_yunyu.rename(columns={'日付': 'Date'}, inpl...
# 結果を表示
print(reshaped_df_yunyu)
# CSV 保存
reshaped_df_yunyu.to_csv("csv/out_data/industry_date_yu...
結果を見やすい形にしてcsvファイルに保存する.
**輸出価格変動の影響 [#k13ded11]
輸出価格変動の影響を求める際に輸出価格の変化率を「為替の...
輸入価格変動と同様に日本銀行「輸出・輸入物価指数の契約通...
2023 年 12 月の値を用いる.
# 日付を統一形式に変換
result_df_yusyutsu['日付'] = pd.to_datetime(result_df_y...
result_df_yunyu['日付'] = pd.to_datetime(result_df_yuny...
# 二つのデータフレームをマージ
merged_df = pd.merge(result_df_yusyutsu, result_df_yuny...
# 値を加算
merged_df['値_合計'] = merged_df['値_輸出'] + merged_df...
# 結果を表示
print(merged_df)
# 元の産業順序を取得
original_order = merged_df['産業'].drop_duplicates().to...
# ピボットテーブルで変換
reshaped_df_marge = merged_df.pivot(index='日付', colum...
# 列の順序を元の順序に並び替え
reshaped_df_marge = reshaped_df_marge[original_order]
# 列名をリセットし、日付を列として戻す
reshaped_df_marge.reset_index(inplace=True)
reshaped_df_marge.rename(columns={'日付': 'Date'}, inpl...
# 結果を表示
print(reshaped_df_marge)
# CSV 保存
#reshaped_df_marge.to_csv("csv/industry_date_marge_2015...
輸出・輸入の価格変動の影響の差し引きを求める.
# 指定した列を足し合わせて新しい列を作成
reshaped_df_marge['非鉄金属・金属製品'] = (
reshaped_df_marge['非鉄金属'] +
reshaped_df_marge['金属製品']
)
reshaped_df_marge['はん用機械・生産用機械・業務用機械']...
reshaped_df_marge['はん用機械'] +
reshaped_df_marge['生産用機械'] +
reshaped_df_marge['業務用機械']
)
reshaped_df_marge['電気機械・電子部品・情報通信機器'] = (
reshaped_df_marge['電気機械'] +
reshaped_df_marge['電子部品'] +
reshaped_df_marge['情報通信機器']
)
reshaped_df_marge['対事業所サービス・対個人サービス'] = (
reshaped_df_marge['対事業所サービス'] +
reshaped_df_marge['対個人サービス']
)
# 元の列を削除
reshaped_df_marge.drop(
['非鉄金属', '金属製品',
'はん用機械', '生産用機械', '業務用機械',
'電気機械', '電子部品', '情報通信機器',
'対事業所サービス', '対個人サービス',
'水道', '廃棄物処理', '公務', '教育・研究',
'他に分類されない会員制団体', '事務用品', '分類不明'],
axis=1,
inplace=True
)
# 結果を表示
print(reshaped_df_marge)
# CSV 保存
reshaped_df_marge.to_csv("csv/out_data/industry_date_ma...
産業連関表における部門の分け方と業種別株価における業種の...
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import rcParams
# 日本語フォントを指定
rcParams['font.family'] = 'Meiryo' # Windowsの場合はMe...
# 折れ線グラフのプロット
plt.figure(figsize=(15, 6))
for column in reshaped_df_marge.columns:
plt.plot(reshaped_df_marge.index, reshaped_df_marge...
# グラフの設定
plt.title('為替変動による各産業への影響値の推移(2024年7...
plt.xlabel('Date', fontsize=12)
plt.ylabel('付加価値比', fontsize=12)
# 凡例をグラフの外側に配置
plt.legend(title="産業", bbox_to_anchor=(1.05, 1), loc=...
plt.grid(True)
# グラフを表示
plt.tight_layout()
plt.show()
#ref(output_1.png,,実行結果,,720x400)
*3Dグラフの作成 [#eeca9a90]
産業連関表の三角化を行う.
#ref(sankakuka2.png,,720x400)
~
-sankakuka_2020.py
import numpy as np
import pandas as pd
from pulp import LpProblem, LpVariable, LpBinary, lpSum,...
import networkx as nx
import matplotlib.pyplot as plt
# 入力データの読み込み
def read_input_data(file_path):
# CSVファイルを読み込む
df_yunyu = pd.read_csv(file_path)
# セクター数を取得
#NSec = int(df.iloc[0, 1])
NSec = 37
# A行列を取得(2行目以降を数値行列として読み込む)
#A = df.iloc[2:, 2:].replace({',': ''}, regex=True)....
A = df_yunyu.replace({',': ''}, regex=True).values.a...
return NSec, A
# 最適化問題の定義と解決
def solve_triangulation(NSec, A):
problem = LpProblem("Triangulation", LpMaximize)
# セクターの範囲
SSec = range(NSec)
# 決定変数
X = [[LpVariable(f"X_{i}_{j}", cat=LpBinary) for j i...
# 制約条件
for i in SSec:
for j in SSec:
if i < j:
for k in SSec:
if j < k:
problem += X[i][j] + X[j][k] - X...
f"Transitivity1_{i}_{j}_{k}"
problem += X[i][j] + X[j][k] - X...
f"Transitivity2_{i}_{j}_{k}"
# 目的関数
LowSum = lpSum(
(A[i, j] - A[j, i]) * X[i][j] + A[j, i]
for i in SSec for j in SSec if i < j
)
problem += LowSum
# 問題を解く
problem.solve()
# 結果を取り出す
Xo = np.zeros((NSec, NSec))
Rank = np.zeros(NSec)
for i in SSec:
for j in SSec:
if i < j:
Xo[i, j] = value(X[i][j])
elif i > j:
Xo[i, j] = 1 - value(X[j][i])
Xo[i, i] = 1
Rank[i] = sum(Xo[i, :])
return Xo, Rank
# 結果(rank)をファイルに出力
def write_output_data(file_path, Rank):
df = pd.DataFrame({"Sector": np.arange(1, len(Rank) ...
# インデックスをリセットして1からの連番にする
df.reset_index(drop=True, inplace=True) # 現在のイ...
df.index = df.index + 1 # インデックスを1から...
# 産業名リスト
industry_names = [
"農林漁業", "鉱業", "飲食料品", "繊維製品", "パ...
"プラスチック・ゴム製品", "窯業・土石製品", "鉄鋼...
"生産用機械", "業務用機械", "電子部品", "電気機械...
"建設", "電力・ガス・熱供給", "水道", "廃棄物処理...
"情報通信", "公務", "教育・研究", "医療・福祉", "...
"対個人サービス", "事務用品", "分類不明"
]
# インデックスを産業名に置き換える
df.index = industry_names
df.to_csv(file_path, encoding="utf-8-sig")
# Rank 列を昇順でソート
df_rank_sorted = df.sort_values(by="Rank", ascending...
df_rank_sorted.to_csv("C:/Users/ta_na/OneDrive/デス...
# 結果(行列X)をファイルに出力
def write_output_matrix(file_path, matrix):
# 行列をデータフレームに変換して保存
df = pd.DataFrame(matrix)
df.to_csv(file_path, index=False, header=False)
# メイン処理
if __name__ == "__main__":
# 入力ファイルと出力ファイル
IN_FILE = "C:/Users/ta_na/OneDrive/デスクトップ/kawa...
OUT_FILE_RANK = "C:/Users/ta_na/OneDrive/デスクトップ...
OUT_FILE_X = "C:/Users/ta_na/OneDrive/デスクトップ/sa...
# データの読み込み
NSec, A = read_input_data(IN_FILE)
# 最適化の実行
Xo, Rank = solve_triangulation(NSec, A)
# 結果を保存
write_output_data(OUT_FILE_RANK, Rank)
write_output_matrix(OUT_FILE_X, Xo)
print(f"Results saved to {OUT_FILE_RANK}")
print(f"Results saved to {OUT_FILE_X}")
目的関数は, Aij と Aji の値を比べて, 産業部門 i と産業部...
**jsonファイルの作成 [#c0352b1c]
3D Force-Directed Graphに産業部門間の関係の情報を送るため...
産業部門間の関係が格納されたcsvファイルをjsonファイルに変...
-3Dgraph_kihon.ipynb
import numpy as np
import pandas as pd
X = pd.read_csv("C:/Users/ta_na/OneDrive/デスクトップ/s...
X
import numpy as np
import pandas as pd
coefficient_matrix_kihon = pd.read_csv("C:/Users/ta_na/...
coefficient_matrix_kihon
# X の 1 の部分に対応する coefficient_matrix_kihon の値...
# X の 0 の部分は 0 のままにする
coefficient_matrix_kihon_2 = X * coefficient_matrix_kihon
# 出力結果
print(coefficient_matrix_kihon_2)
# 新しいデータフレームを作成
rows = []
for i, row_label in enumerate(coefficient_matrix_kihon_...
for j, col_label in enumerate(coefficient_matrix_ki...
if i != j and coefficient_matrix_kihon_2.iloc[i...
rows.append({'from': row_label, 'to': col_l...
# 新しいデータフレームを作成
result_df = pd.DataFrame(rows)
print(result_df)
# CSVファイルに保存
result_df.to_csv('csv/out_data/from_to_kihon.csv', inde...
# 'effect'列の値を100倍
result_df['effect'] = result_df['effect'] * 100
#全部
import pandas as pd
import csv
import json
# effectを削除
df_effect=result_df.drop(["effect"],axis=1)
#fromとtoの中の要素を一つのリストにする
count_id = df_effect.stack().drop_duplicates().tolist()
# links の形式にデータを変換する
links = []
for index, row in result_df.iterrows():
links.append({
"source": row['from'],
"target": row['to'],
"value": row['effect']
})
# データを指定された形式に変換
nodes = [{"id": item, "group": 1} for item in count_id]
# JSON形式に変換
result = {"nodes": nodes, "links": links}
# JSONファイルに保存
with open("static/json/output_toda_kihon_zenbu.json", "...
json.dump(result, f, indent=2)
作成するjsonファイルの形式(output_toda_kihon_zenbu.json)
{
"nodes": [
{
"id": "\u8fb2\u6797\u6f01\u696d",
"group": 1
},
{
"id": "\u98f2\u98df\u6599\u54c1",
"group": 1
},
~~~~~~~~~~省略~~~~~~~~~~
{
"id": "\u60c5\u5831\u901a\u4fe1",
"group": 1
},
{
"id": "\u5bfe\u4e8b\u696d\u6240\u30b5\u30fc\u...
"group": 1
}
],
"links": [
{
"source": "\u8fb2\u6797\u6f01\u696d",
"target": "\u98f2\u98df\u6599\u54c1",
"value": 19.05628066765477
},
{
"source": "\u8fb2\u6797\u6f01\u696d",
"target": "\u6559\u80b2\u30fb\u7814\u7a76",
"value": 0.13824726106617
},
~~~~~~~~~~省略~~~~~~~~~~
{
"source": "\u5206\u985e\u4e0d\u660e",
"target": "\u4ed6\u306b\u5206\u985e\u3055\u30...
"value": 1.2702003066174
},
{
"source": "\u5206\u985e\u4e0d\u660e",
"target": "\u5bfe\u500b\u4eba\u30b5\u30fc\u30...
"value": 0.43188001994264
}
]
}
-"nodes"にはグラフに表示される単語の定義を行う.~
--"id"はノードの単語.~
--"group"は色分けなどをしたいときにノードのグループを指定...
-"links"には産業部門間の関係を記述する.~
--"source"は供給元の単語.~
--"target"は供給先の単語.~
--"value"は結ぶ線の大きさを変更するときなどに利用される.~
**3Dグラフ [#b7b070fc]
3Dグラフの描画にはThree.jsのモジュール”3D Force-Directed ...
参考にしたサイト👉https://vasturiano.github.io/3d-force-g...
javascriptの買い方はサイトを参考にすれば様々な変更が可能.~
⚠モジュールのインポート方法はサイトのものでは行えなかった...
-index_0114.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>3D Graph with Rankings</title>
<style>
body {
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
height: 100vh;
}
#container {
display: flex;
flex: 1;
width: 100%;
}
#three {
flex: 1;
background-color: aliceblue;
height: 100%;
}
#info {
position: fixed; /* fixedに変更して、スクロールして...
top: 10px;
right: 10px;
background-color: #fff;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
width: 300px;
max-height: 900px;
overflow-y: auto;
z-index: 10;
}
#rankTable {
position: fixed; /* 左上に固定表示 */
top: 10px;
left: 10px;
background-color: #fff;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
width: 300px;
max-height: 900px;
overflow-y: auto;
z-index: 10;
font-size: 12px;
}
/* レスポンシブ対応 */
@media screen and (max-width: 768px) {
#container {
flex-direction: column;
}
#rankTable {
width: 100%;
}
#three {
width: 100%;
height: 400px;
}
}
</style>
</head>
<body>
<!-- 左上にランク表 -->
<div id="rankTable">
<table>
<thead>
<tr>
<th>産業部門名</th>
<th>順列</th>
</tr>
</thead>
<tbody>
<tr><td>生産用機械</td><td>1</td></tr>
<tr><td>医療・福祉</td><td>2</td></tr>
<tr><td>教育・研究</td><td>3</td></tr>
<tr><td>対個人サービス</td><td>4</td></tr>
<tr><td>飲食料品</td><td>5</td></tr>
<tr><td>農林漁業</td><td>6</td></tr>
<tr><td>水道</td><td>7</td></tr>
<tr><td>他に分類されない会員制団体</td><td>8</td></tr>
<tr><td>分類不明</td><td>9</td></tr>
<tr><td>公務</td><td>10</td></tr>
<tr><td>輸送機械</td><td>11</td></tr>
<tr><td>情報通信機器</td><td>12</td></tr>
<tr><td>事務用品</td><td>13</td></tr>
<tr><td>業務用機械</td><td>14</td></tr>
<tr><td>建設</td><td>15</td></tr>
<tr><td>はん用機械</td><td>16</td></tr>
<tr><td>電気機械</td><td>17</td></tr>
<tr><td>電子部品</td><td>18</td></tr>
<tr><td>窯業・土石製品</td><td>19</td></tr>
<tr><td>金属製品</td><td>20</td></tr>
<tr><td>鉄鋼</td><td>21</td></tr>
<tr><td>非鉄金属</td><td>22</td></tr>
<tr><td>廃棄物処理</td><td>23</td></tr>
<tr><td>繊維製品</td><td>24</td></tr>
<tr><td>その他の製造工業製品</td><td>25</td></tr>
<tr><td>パルプ・紙・木製品</td><td>26</td></tr>
<tr><td>プラスチック・ゴム製品</td><td>27</td></tr>
<tr><td>化学製品</td><td>28</td></tr>
<tr><td>電力・ガス・熱供給</td><td>29</td></tr>
<tr><td>石油・石炭製品</td><td>30</td></tr>
<tr><td>鉱業</td><td>31</td></tr>
<tr><td>商業</td><td>32</td></tr>
<tr><td>運輸・郵便</td><td>33</td></tr>
<tr><td>不動産</td><td>34</td></tr>
<tr><td>金融・保険</td><td>35</td></tr>
<tr><td>情報通信</td><td>36</td></tr>
<tr><td>対事業所サービス</td><td>37</td></tr>
</tbody>
</table>
</div>
<!-- 真ん中に3Dグラフ -->
<div id="three"></div>
<!-- 右上にノード情報 -->
<div id="info">
<!-- ノードの情報がここに表示されます -->
</div>
<!-- JavaScript ライブラリの読み込み -->
<script type="module"
src="https://unpkg.com/three@0.158.0/build/three.js" def...
<script type="module" src="https://unpkg.com/3d-force-...
<script type="module" src="https://unpkg.com/three-spri...
<script src="./static/main2_0114.js" charset="utf-8" de...
</body>
</html>
--<script type="module" src="https://unpkg.com/three@0.15...
three.jsのインポート
--<script type="module" src="https://unpkg.com/3d-force-g...
3D Force-Directed Graphのモジュールのインポート
--<script type="module" src="https://unpkg.com/three-spri...
テキストをノードにするときに必要なモジュールのインポート
--<script src="./static/main2_0114.js" charset="utf-8" de...
プログラムに使うjavascriptのファイルの指定
~
-main2_0114.js
const highlightLinks = new Set();
const highlightNodes = new Set();
let hoverNode = null;
const Graph = ForceGraph3D()
(document.getElementById("three"))
.jsonUrl('http://127.0.0.1:5000/static/json/output_...
.nodeColor('#ffffff')
.nodeLabel('id')
.nodeRelSize(20)
.nodeThreeObject(node => {
const sprite = new SpriteText(node.id);
sprite.material.depthWrite = false; // make spr...
sprite.color = node.color;
// // 特定のノード名の色を変更
// if (node.id === '農林漁業') {
// sprite.color = 'red'; // 特定ノードのテ...
// } else {
// sprite.color = node.color; // 他のノード...
// }
sprite.textHeight = 7.5;
return sprite;
})
.linkThreeObject(link => {
// extend link with text sprite
const sprite = new SpriteText(link.value.toFixe...
sprite.color = 'blue';
sprite.textHeight = 4.0;
return sprite;
})
.linkPositionUpdate((sprite, { start, end }) => {
const middlePos = Object.assign(...['x', 'y', '...
[c]: start[c] + (end[c] - start[c]) / 2 // ca...
})));
// Position sprite
Object.assign(sprite.position, middlePos);
})
.onNodeClick(node => {
// ノードクリック時に入出力リンクを表示
const outgoingLinks = Graph.graphData().links.f...
const incomingLinks = Graph.graphData().links.f...
// 左上に情報を表示
const displayArea = document.getElementById("in...
displayArea.innerHTML = `<h3>ノード: ${node.id}...
// 出ているリンク
//displayArea.innerHTML += `<h4>Outgoing Links<...
displayArea.innerHTML += `<h4>販売先</h4>`;
outgoingLinks.forEach(link => {
displayArea.innerHTML += `<p>${link.target....
});
// 向かってくるリンク
//displayArea.innerHTML += `<h4>Incoming Links<...
displayArea.innerHTML += `<h4>購入先</h4>`;
incomingLinks.forEach(link => {
displayArea.innerHTML += `<p>${link.source....
});
})
.onNodeHover(node => {
// ノードにホバーした時の処理
hoverNode = node ? node.id : null;
updateHoverText(); // テキストを更新する関数を...
})
.linkOpacity(0.25)
.linkDirectionalArrowLength(3)
.linkDirectionalArrowRelPos(1)
.linkCurvature(0.01)
//.linkDirectionalParticleWidth(2)
//.linkDirectionalParticles("value")
//.linkDirectionalParticleSpeed(d => d.value * 0.01)
.linkThreeObjectExtend(true)
.linkColor(() => 'red') // リンクの色を黒に設定
.linkWidth(1)
.backgroundColor("#f8f8f8");
// ノード間の力学的レイアウトを調整
Graph
.d3Force("link").distance(300) // リンクの長さを100...
.d3Force("charge").strength(300); // ノード間の反発...
function updateHoverText() {
// ホバー時のノードのテキストサイズを変更
Graph.nodeThreeObject(node => {
const sprite = new SpriteText(node.id);
sprite.material.depthWrite = false;
sprite.color = node.color;
sprite.textHeight = hoverNode === node.id ? 15 ...
return sprite;
});
}
-ここで産業部門間の関係を記述したjsonファイルを指定してい...
.jsonUrl('http://127.0.0.1:5000/static/json/output_toda_...
-実際に3Dグラフの描画の処理を行っている.~
ノードの色の変更の処理もここで行う.~
.nodeThreeObject
-初期設定だとグラフの回転軸が中央で固定になってしまうため...
.onNodeClick
-矢印の設定もろもろ
.linkOpacity(0.25)
.linkDirectionalArrowLength(3)
.linkDirectionalArrowRelPos(1)
.linkCurvature(0.01)
.linkDirectionalParticleWidth(2)
.linkDirectionalParticles("value")
.linkDirectionalParticleSpeed(d => d.value * 0.01)
.linkThreeObjectExtend(true)
.linkColor(() => '#708090')
.linkWidth(1)
--linkDirectionalParticlesはノードの矢印にアニメーション...
-初期設定では背景の色が黒色だが見にくいため白色に変更して...
.backgroundColor("#f8f8f8")
~
-app_0114.py
~
app_0114.pyを実行し、下の図のようなコマンドプロンプト内に...
#ref(実行.PNG,,40%)~
実際の出力結果
#ref(3Dgraph.png,,720x400)~
*データ収集 [#q47f7fcb]
**産業連関表の収集 [#u7cb95fe]
産業連関表は以下の総務省のリンク先からダウンロードする
~
https://www.soumu.go.jp/toukei_toukatsu/data/io/2020/io20...
#ref(総務省.png,,総務省 産業連関表,,720x400)
~
**スクレイピングによるデータ収集 [#ocdbc129]
-7to12_JPX401.ipynb
~
各企業のティッカーシンボル(株式会社で取引される企業を識...
#ここからスタート
#日本経済新聞のページからティッカーのみを取得する.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditi...
from webdriver_manager.chrome import ChromeDriverManager
from bs4 import BeautifulSoup
import time
# Chromeドライバーのセットアップ
service = Service("C:/Users/ta_na/OneDrive/デスクトップ...
driver = webdriver.Chrome(service=service)
# URLを指定
url = "https://www.nikkei.com/markets/kabu/nidxprice/?S...
driver.get(url)
# ページが完全に読み込まれるのを待つ
time.sleep(3)
# 繰り返し回数を指定
repeat_count = 10 # 例として3回繰り返す
# ティッカー情報を格納するリスト
tickers = []
# 繰り返し処理
for i in range(repeat_count):
print(f"Page {i+1} のティッカーを取得中...")
# BeautifulSoupを使ってページのHTMLを解析
soup = BeautifulSoup(driver.page_source, 'html.pars...
# ティッカー情報を格納
for row in soup.find_all('tr'): # テーブル行を取得
columns = row.find_all('td') # 行内の列を取得
if len(columns) > 1: # 必要な列が存在する場合...
ticker = columns[0].text.strip() # ティッ...
tickers.append(ticker)
# 次のページに移動するためのクリックアクション
try:
# XPathを使って次ページボタンをクリック
next_button = driver.find_element(By.XPATH, "//...
next_button.click() # クリックアクション
print(f"ページ {i+1} の次のページへ移動")
except Exception as e:
print(f"クリックアクションでエラーが発生しまし...
break # 次のページに移動できない場合、ループを...
# 次のページの読み込みを待機
time.sleep(3)
# 結果を出力
print("取得したティッカー一覧:")
print(tickers)
# 必要に応じてファイルに保存
with open("nikkei500_tickers_all.txt", "w") as file:
for ticker in tickers:
file.write(f"{ticker}\n")
# ブラウザを閉じる
driver.quit()
~
Pythonのライブラリであるyfinanceを用いてデータの収集を行う
import yfinance as yf
import pandas as pd
import os
output_dir = 'C:/Users/ta_na/OneDrive/デスクトップ/kabu...
# 業種ごとのデータを格納する辞書
industry_stock_data = {}
industry_averages = {}
# 1業種ずつ処理
for col, tickers in df_t1.items(): # df_tickers1 は辞...
tickers = [ticker for ticker in tickers if ticker i...
ticker_close_prices = [] # その業種のティッカーに...
for ticker in tickers:
if isinstance(ticker, str): # tickerが文字列で...
ticker_symbol = ticker + ".T" # ティッカー...
print(f"取得するティッカー: {ticker_symbol}")
try:
# yfinanceを使って指定期間の日足データ...
data = {yf.download}(ticker_symbol, int...
※''&color(red){yfinanceのバージョンを0.2.52};''に必ずする...
# データが取得できた場合、Closeの値だけ...
if not data.empty:
ticker_close_prices.append(data['Cl...
print(f"{ticker_symbol} の日足株価...
else:
print(f"{ticker_symbol} のデータが...
except Exception as e:
print(f"{ticker_symbol} の取得中にエラ...
else:
print(f"無効なティッカー: {ticker}(スキッ...
※「データが見つかりませんでした」と出るが問題ない
# データを統合して業種ごとのデータフレームを作成
if ticker_close_prices:
industry_df = pd.concat(ticker_close_prices, ax...
# 列数とティッカー数が一致しない場合、自動調整
if len(industry_df.columns) != len(tickers):
print(f"警告: 列数の不一致。業種: {col} の...
# 一致しない場合、列数に合わせてティッカー...
tickers = tickers[:len(industry_df.columns)]
# 列名にティッカー番号を設定
industry_df.columns = tickers
industry_df['Date'] = industry_df.index # 日付...
industry_df.set_index('Date', inplace=True) # ...
# NaNを削除(各ティッカーに対してNaNがある場合)
industry_df = industry_df.dropna(axis=1, how='a...
# 業種ごとの一日ごとの平均株価を計算
industry_df['Average'] = industry_df.mean(axis=1)
# 業種ごとの平均株価データを industry_averages ...
industry_averages[col] = industry_df['Average']
# 必要に応じてCSVファイルとして保存
file_path = os.path.join(output_dir, f"{col}_st...
industry_df.to_csv(file_path)
print(f"{col} のデータを '{file_path}' に保存し...
else:
print(f"{col} 業種のデータが存在しませんでした...
# 最終的な業種別平均株価データフレームを作成
df_heikin = pd.DataFrame(industry_averages)
# 結果の確認
print("業種別平均株価データフレーム:")
print(df_heikin)
# 必要に応じてCSVとして保存
df_heikin.to_csv(os.path.join(output_dir,
"industry_average_stock_prices.csv"), encoding="utf-8-s...
import yfinance as yf
import pandas as pd
為替のデータを取得する
# USD/JPYの為替データを取得
usd_jpy = yf.download("JPY=X", start="2024-07-01", end=...
# 終値を取得
usd_jpy_close = usd_jpy.iloc[:, 3]
usd_jpy_close = usd_jpy.reset_index()
~
※Yahoo Finance(YF)のAPIやウェブサービスを使用してUSD/JP...
→時間をおいて再度リクエストを試す~
※''&color(red){yfinanceのバージョンを0.2.52};''に必ずする...
*相関 [#u016835a]
-soukan_7to12_map_yfinance.ipynb
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
sangyou_df = pd.read_csv("C:/Users/ta_na/OneDrive/デス...
daily_change_rate = pd.read_csv("C:/Users/ta_na/OneDriv...
# Date列をdatetime型に変換
daily_change_rate['Date'] = pd.to_datetime(daily_change...
sangyou_df['Date'] = pd.to_datetime(sangyou_df['Date'])
# 共通のDateを抽出
common_dates = set(daily_change_rate['Date']).interse...
# 共通のDateでフィルタリング
filtered_daily_change_rate = daily_change_rate[daily_ch...
filtered_sangyou_df = sangyou_df[sangyou_df['Date'].isi...
# 必要に応じてDateでソート
filtered_kabuka_df = filtered_daily_change_rate.sort_va...
filtered_sangyou_df = filtered_sangyou_df.sort_values(b...
# 結果を表示
print(filtered_kabuka_df)
print(filtered_sangyou_df)
filtered_kabuka_df.to_csv("csv/out_data/final_kabuka_7...
filtered_sangyou_df.to_csv("csv/out_data/final_sangyou_...
ドル円為替レートと日経 500 種平均株価それぞれの取引市場の...
どの理由により, 取得できるデータの日付がドル円為替レート...
~
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
sangyou = pd.read_csv("C:/Users/ta_na/OneDrive/デスクト...
#kabuka = pd.read_csv("C:/Users/pi/Desktop/soukan/csv/o...
kawase = pd.read_csv("C:/Users/ta_na/OneDrive/デスクト...
# Date列をインデックスに設定
sangyou.set_index('Date', inplace=True)
# すべての列名に (産業) を追加
sangyou.columns = [f"{col}(産業)" for col in sangyou.co...
sangyou
# Date列をインデックスに設定
kawase.set_index('Date', inplace=True)
kawase
#Open, High, Low, Adj Close, Volume の列を削除
kawase = kawase.drop(columns=["('High', 'JPY=X')", "('L...
※Pythonのバージョンによって、データのコラム名が異なるため...
# すべての列名に (株価) を追加
kawase.columns = [f"{col}(株価)" for col in kawase.colu...
# Close を usdjpy に変更
kawase = kawase.rename(columns={"('Close', 'JPY=X')(株...
kawase.to_csv("csv/out_data/final_kabuka_usdjpy_7to12.c...
kawase
# 横に結合(列方向)
merge_df = pd.concat([sangyou, kawase], axis=1)
merge_df
データにコラム名を付ける.
~
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib import rcParams
# 日本語フォントを指定
rcParams['font.family'] = 'Meiryo' # Windowsの場合はMe...
# 相関行列を計算(merge_dfは既に存在する前提)
corr_matrix = merge_df.corr()
# 相関行列をヒートマップとして保存
def save_corr_as_image_with_values(corr_matrix, file_n...
plt.figure(figsize=(12, 10)) # 図のサイズを大きく...
# ヒートマップを作成
sns.heatmap(corr_matrix, cmap='Reds', annot=True, f...
# ラベルのフォーマット調整
plt.xticks(rotation=90, fontsize=8) # x軸ラベル
plt.yticks(fontsize=8) # y軸ラベル
# 余白調整と保存
plt.tight_layout()
plt.savefig(file_name, dpi=300, bbox_inches='tight'...
plt.close()
# 関数を実行
save_corr_as_image_with_values(corr_matrix, 'figure/co...
print("相関係数を表示した相関行列を画像として保存しまし...
相関を求めて、ヒートマップを作成.
soukan/figureフォルダ内にcorrelation_matrix_2_2.pngが保存...
実行結果
#ref(correlation_matrix_2_2.png,,500x500)
終了行:
[[由利恵]]
*目次 [#e890b3d5]
#CONTENTS
**目的 [#z78b3c7b]
近年,経営環境は大きく変化しており,いわゆるVUCA な時代を...
~
~
~
***使用するファイル全部 [#ta19c6d2]
|扱うデータ|用途|ファイル名|ファイルの場所|
|システムの内部処理|flaskを用いたシステムの記述|appli_2.p...
|ドライバーのファイル|自分の環境に合わせたChromeDriverの...
|staticファイル|javascriptや画像のファイルが入っている|st...
|↑の中身|3Dグラフを作成するときのjavascriptのファイル|mai...
|↑の中身|javascriptで読み込む用のjsonファイル|output.json...
|↑の中身|グラフのボタンを作成する用の画像|xy2.png/xyz2.pn...
|テキストデータ|集めてきたテキストデータの一時保存|text_d...
|ベクトル(数値)|2次元に圧縮したベクトル|vectors.pickle|...
|ベクトル(数値)|15次元に圧縮したベクトル|vectors_15.pic...
|シルエット係数|それぞれのクラス数におけるシルエット係数...
|クラスタリング結果|クラスタリングの結果のデータ|df_umap....
|simpson係数|simpson係数の値と単語の出現回数など|jaccard_...
|ユーザー辞書|各クラスターのユーザー辞書の保存|user_dic_{...
|共起語ネットワーク|2dの共起語ネットワークのhtmlファイル|...
~
*動かし方 [#ccda06db]
1.practiceの中のappli_2.pyを動かす.~
2.必要なモジュールをすべて入れる.(pip installなど)~
⚠umapとMeCabは少し名前が違うモジュールなので注意,そのほ...
-Sentence-BERTを動かすときに"fugashi"をインストールする必...
pip install umap-learn
pip install mecab-python3
2'.termextractはpipではインストールできないため別の入れ...
-詳しくは> [[termextract>#qbb8ab79]]
3.すべてのインストールが完了したらlocalhost:5000にアクセ...
⚠必ずlocalhost:5000にアクセス!~
-詳しくは>[[3Dグラフ>#gd773348]]~
*スクレピング処理 [#w90988e1]
***ChromeDriverのインストール [#j661bc61]
まず、ChromeDriverをインストールする.自身のGoogleChrome...
わからなかったらここを見て👇~
👉https://zenn.dev/ryo427/articles/7ff77a86a2d86a
~
**1.データ取得 [#c9661663]
***seleniumのインストール [#j661bc61]
seleniumをインストールする.バージョン3でもよいが,プログ...
<pythonのとき>
pip install selenium
<notebookのとき>
!python -m pip install selenium
***必要なモジュールをインポートする. [#h00fd477]
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
***driverのオプションを設定する. [#b380d497]
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
--headless ヘッドレスモード(バックグラウンドで起動)
--no-sandbox sandboxモードを解除する(クラッシュ回避)
--disable-dev-shm-usage パーティションが小さすぎることに...
***chromedriverのパスを設定する. [#b380d497]
インストールしたchromedriver.exeの場所を指定する.
driver_path = "chromedriver-win64/chromedriver.exe"
***driverを作成する. [#b380d497]
driver1 = webdriver.Chrome(service=ChromeService(driver_...
driver1.implicitly_wait(10)
--implicitly_wait(10) 指定した時間要素が見つかるまで待機.
⚠seleniumのバージョンによってコードの書き方が異なる場合が...
)
***urlの指定方法 [#uff6c3d3]
urlでユーザーからのキーワードと取得する年数を指定する.
url_1 = (
"https://patents.google.com/?q=("
+ str(keyword)
+ ")&before=priority:"
+ str(2000)
+ "1231&after=priority:"
+ str(2000)
+ "0101&sort=old"
)
--str(keyword):ここにユーザーから取得したキーワードを入...
--&before=priority:* + str(XXXX) + 1231&after=priority:...
➡priorityがXXXX年の0101(一月一日)から1231(十二月三十一...
***取得方法 [#c0fff484]
def W1(url):
driver1.get(url)
try:
results1 = driver1.find_element(
By.XPATH, '//*[@id="count"]/div[1]/span[1...
).text.replace(",", "")
if int(results1) <= 10:
p_n_1 = 1
else:
p_n_1 = int(results1) // 10
except Exception as e:
print("error")
for p1 in range(p_n_1 + 1):
driver1.get(url + "&page=" + str(p1))
link1 = driver1.find_elements(
By.XPATH,
'//*[@id="resultsContainer"]/section/sear...
)
for i1 in range(len(link1)):
try:
link_url1 = "https://patents.google.c...
"data-result"
)
patt1 = pat_text(link_url1)
patt1.get_soup()
# patt.get_title()
patt1.get_claims()
d_save1 = []
d_save1.append(patt1.get_description())
d_save1.append(link1[i1].get_attribut...
desc1.append(d_save1)
except Exception as e:
print(e)
1.urlから中身を取得する.~
2.find_elementで検索結果の数を取得する.~
3.{p_n_1}にページ数を渡す.(何ページあるのかを直接取得で...
--検索結果に表示された特許の数{results}が10以下ならp_n_1...
---resultsはGoogle Patantsに表示される「About ****** resu...
➡(結果の数値が4桁1,000などの場合は「,」があるとうまく処...
4.各ページの中から特許番号を取得する.~
--for文でページ分回す~
---driver1.get(url + "&page=" + str(p1))この部分でページ...
5.find_elementで特許番号(例:patent/JP5965646B2/ja)の部...
--link1にはそのページの取得した特許番号が含まれる要素がす...
---.get_attribute("data-results")の部分は実際の「patent/J...
6.取得した番号をもとにhtmlのurlを作成し,関数(pat_text)...
7.pat_textからの本文と特許番号をd_save1に渡す.~
👇実際の取得結果~
#ref(テキストフォーマット2.jpg)
~
~
**2.並列化 [#ad9614fa]
スクレイピングの高速化を試みた,今回はthreadsを用いて並列...
import threading
thr1 = threading.Thread(target=W1, args=(url_1,))
thr2 = threading.Thread(target=W2, args=(url_2,))
thr3 = threading.Thread(target=W3, args=(url_3,))
thr4 = threading.Thread(target=W4, args=(url_4,))
thr5 = threading.Thread(target=W5, args=(url_5,))
thr6 = threading.Thread(target=W6, args=(url_6,))
~~~~~省略~~~~~
thr24まで
~~~~~~~~~~~~
threadを一年ごとに設定する.~
それを6年ずつ実行する~
要素が混在しないように一年ごととそれぞれのスレッドごとにd...
desc01 = []
desc02 = []
desc03 = []
desc04 = []
if int(year) == 24:
#6年分
desc1 = []
desc2 = []
desc3 = []
desc4 = []
desc5 = []
desc6 = []
#各スレッドのスタート
thr1.start()
thr2.start()
thr3.start()
thr4.start()
thr5.start()
thr6.start()
#各スレッドの処理が終了するまで待機
thr1.join()
thr2.join()
thr3.join()
thr4.join()
thr5.join()
thr6.join()
desc01 = desc1 + desc2 + desc3 + desc4 + desc5 + ...
if int(year) == 18 or int(year) == 24:
~~~~~省略~~~~~
thr7からthr12まで
~~~~~~~~~~~~
desc02 = desc1 + desc2 + desc3 + desc4 + desc5 + ...
if int(year) == 12 or int(year) == 18 or int(year) ==...
~~~~~省略~~~~~
thr13からthr18まで
~~~~~~~~~~~~
desc03 = desc1 + desc2 + desc3 + desc4 + desc5 + ...
~~~~~省略~~~~~
thr19からthr24まで
~~~~~~~~~~~~
desc04 = desc1 + desc2 + desc3 + desc4 + desc5 + desc6
-選択された年数によって動かす処理の数を変えている.
最後に各スレッドのdescを合わせる
desc = desc01 + desc02 + desc03 + desc04
~
**3.保存の仕方と例外 [#c1eb3f9b]
ほかのルーティングでテキストデータを参照したい場合がある.~
csvに保存してもよいが,文字化けなどの可能性もあるため今回は
pickleモジュールを用いてpickle形式のファイルで保存する.~
-保存する場合
with open('text_data.pickle', mode='wb') as fo:
pickle.dump(desc,fo)
--保存される元のデータは{desc}
--保存先のpickleファイルは{text_data.pickle}
-呼びだしたい場合
with open('text_data.pickle', mode='br') as fi:
desc = pickle.load(fi)
--読み込むpickleファイルは{text_data.pickle}
--保存先の変数は{desc}
最後に,取得できたデータの要素数によって例外処理を追加す...
要素数が0の場合に正しく動作しないことや,要素数が少なすぎ...
desc_len = len(desc)
if desc_len < 30:
return redirect(url_for('start'))
-{desc}の要素数が30未満の時はredirectでstart(トップペー...
*Sentence-BERT [#u506e563]
事前学習モデルは”sonoisa/sentence-bert-base-ja-mean-token...
model = SentenceBertJapanese("sonoisa/sentence-bert-base...
-モデルの指定はここで行う.~
SentenceBertJapaneseの中身はここを参照👇~
👉https://huggingface.co/sonoisa/sentence-bert-base-ja-me...
~
~
*UMAP [#d75a68f0]
UMAPでSentence-BERTから得られたベクトルを2次元と15次元に...
-15次元のベクトルは後述するクラスタリングなどに用いる.
-2次元のベクトルは散布図のプロットに用いる.
**UMAPのパラメータ [#w17b6077]
-n neighbors>
n_neighbors パラメータは,各データポイントの埋め込みにお...
点の数を指定する.~
-min_dist>
min_distパラメータは,UMAP によって生成される低次元埋め込...
タ点間の最小距離を制御する.~
-n_components>
n_components パラメータは,UMAP によって生成される埋め込...
を指定する.~
-metric>
metricパラメータは,データ間の類似度や距離を算出するため...
ことができる.~
実際の値
sentence_vectors_umap_15 = umap.UMAP(n_components=15,
random_state=42,
n_neighbors = 25,
min_dist = 0.1,
metric = 'cosine')....
上記は15次元の場合,2次元にするときはn_componentsの値を2...
ベクトル化されたデータもpickleを用いて保存しておく.~
with open('vectors_15.pickle', mode='wb') as fo:
pickle.dump(sentence_vectors_umap_15, fo)
with open('vectors.pickle', mode='wb') as fo:
pickle.dump(sentence_vectors_umap_2, fo)
~
*シルエット分析 [#e6771c98]
K-medoidsでクラスタリングを行うために最適なクラスター数を...
シルエット分析はクラスタリング結果における凝縮度と乖離度...
クラスター数が3から19まで(20以上だと多すぎるかな?)のシ...
-プログラム
def show_silhouette(labels):
cluster_labels = np.unique(labels)
num_clusters = cluster_labels.shape[0]
silhouette_vals = silhouette_samples(data, labels) ...
# 可視化
y_ax_lower, y_ax_upper = 0, 0
y_ticks = []
for idx, cls in enumerate(cluster_labels):
cls_silhouette_vals = silhouette_vals[labels==cls]
cls_silhouette_vals.sort()
y_ax_upper += len(cls_silhouette_vals)
y_ticks.append((y_ax_lower + y_ax_upper) / 2.0)
y_ax_lower += len(cls_silhouette_vals)
silhouette_avg = np.mean(silhouette_vals)
silhouette_df.append(silhouette_avg)
-実際の結果
#ref(シルエット.png)
この場合は一番シルエット係数が高い15を最適なクラスター数...
~
*クラスタリング [#cda78d69]
クラスタリングにはk-medoidsを用いる.~
k-meansではデータの外れ値が大きい場合,クラスタリングの結...
-クラスタリングを行った結果はそれぞれのベクトルにクラスタ...
df_umap_2 = pd.DataFrame(data=sentence_vectors_umap_2, c...
df_umap_2["class"] = ["cluster"+str(x) for x in predicte...
df_umap_15 = pd.DataFrame(data=sentence_vectors_umap_15,...
df_umap_15["class"] = ["cluster"+str(x) for x in predict...
df_umap_2.to_pickle('df_umap.pkl')
~
**タイトルの提示 [#sd94bd78]
各データの重心とのユークリッド距離を計算する.~
centers = kmeans_model.cluster_centers_
df_umap_15["distance"] = np.nan
for j in range(class_n):
class_name = str("cluster" + str(j))
d = df_umap_15[df_umap_15["class"] == class_name]
for i in range(d.shape[0]):
v = d.iloc[i, :]
v = v[:-2]
distances = np.subtract(v, centers[j])
distances_squared = np.square(distances)
distance1 = np.sqrt(np.sum(distances_squared))
df_umap_15.at[d.index[i], "distance"] = distance1
-df_umap_15に新しくdistanceという列を追加する.
--最初に列を追加する理由は,後から入れると,最初はdistanc...
df_umap_15["distance"] = np.nan
-dfの横列にはベクトルにプラスして「クラス番号」と「distan...
そこで,vのサイズをcentersと合わせるために後ろの2つの要素...
v = v[:-2]
-求められた距離を求めたデータに対応付けて"distance"に代入...
df_umap_15.at[d.index[i], "distance"] = distance1
~
それぞれのクラスについて先ほど求めたdistanceを用いてタイ...
for a in tqdm.tqdm(range(class_n)):
vec_dis = df_umap_15[df_umap_15["class"] == "cluster...
vec_dis_sorted = vec_dis.sort_values('distance')
title_all = []
# #ランダム
# if text.shape[0] >= 10:
# random_n = 10
# else:
# random_n = text.shape[0]
# for i in tqdm.tqdm(random.sample(range(text.shape[...
for i in tqdm.tqdm(range(vec_dis_sorted.head(10).sha...
# target_text = text.iloc[i][0]
target_text = pd.DataFrame(df[0]).loc[vec_dis_so...
tagged_text = get_mecab_tagged(target_text)
terms = term_ext(tagged_text)
compound = remove_single_words(terms)
title_all.extend([termextract.core.modify_agglut...
set1 = sorted([k for k, v in collections.Counter(tit...
title.append("/".join(set1[0:3]))
+クラスに含まれる要素を取り出す.
+その要素を{distance}が小さい順に並べ替える.
+小さいものから10個取り出す.
➡それらが10個未満の場合はすべて取り出す.
+重要語を計算し,その中から重要度が高いものを取り出す.
title_all.extend([termextract.core.modify_agglutinative_...
↳それぞれの文章からトップ3を抜き出す.
set1 = sorted([k for k, v in collections.Counter(title_a...
↳それらを重要度が高い順に並べ替える.
title.append("/".join(set1[0:3]))
↳最後にトップ3を抜き出す.
**散布図グラフの描画 [#qe5ab135]
散布図の描画は2次元で行う.~
また,散布図の下には各クラスターの内容を表示する.~
散布図にはデータのプロットと,データのクラスリングの結果...
クラスタリング結果の見方は,データの色と点の形からクラス...
その番号とクラスターの内容を照らし合わせる.~
marker_styles = [
".",
",",
"o",
"v",
"^",
"<",
">",
"1",
"2",
"3",
"4",
"8",
"s",
"p",
"*",
"h",
"H",
"+",
"x",
"D",
"d",
]
-グラフに表示するときの点の形を事前に定義する.
**グラフの画像保存 [#h6adf354]
作成されたグラフは画像形式度保存してhtml上に出力する.
buf: BytesIO = BytesIO()
# figure.savefig(buf, format='png')
figure.savefig(buf, bbox_inches="tight")
with buf:
data = buf.getvalue()
img_data = base64.b64encode(data).decode("ascii")
img_src: str = "data:image/png;base64," + img_data
-matplotlibで作成したグラフを画像形式で保存する.保存した...
**htmlでの表示 [#xe6ab4e0]
<div style="height: 50%;">
<a href="{{ img_src }}" data-lightbox="group"><img s...
</div>
-上記のように表示する.~
~
-実際の結果
#ref(散布図.jpg)
~
*選択したクラスターとグラフの大きさ [#je205489]
**クラスターに含まれる特許 [#db28ac17]
選択したクラスターに含まれている特許の実際のGoogle Patent...
スクレイピングの時に取得した特許番号の部分を使ってurlを作...
詳しく知りたい場合はjinja2のfor文の書き方を調べるとよい.~
-select.html
<h1>特許一覧</h1>
{% for x in plat_index %}{%set plat_index_loop = loop %}
{% for y in plat_index2 %}{%if loop.index==plat_index_lo...
<ul>
<a href=https://patents.google.com/{{x}} target="_bl...
</ul>
{% endif %}
{% endfor %}
{% endfor %}
**グラフの大きさの選択 [#pee44f2c]
グラフの大きさを描画する共起関係の数をもとに設定する.
-select.html
<form action="/graph" method="POST">
<div class="flexbox">
<div class="flex-item">
<button type="submit" style="height: 250px;">
<img src="static/xyz2.png" alt="Button I...
</button>
</div>
<div style="font-size:large" class="flex-item">3...
<div class="yoko">
<label>
<input type="radio" name="3g_size" class...
</label>
<label>
<input type="radio" name="3g_size" class...
</label>
<label>
<input type="radio" name="3g_size" class...
</label>
</div>
</div>
</form>
*分かち書き [#ldc6d820]
**termextract [#qbb8ab79]
専門用語や複合語などを抽出するためのモジュール
***モジュールの入れ方 [#q35d9ead]
以下のサイトからtermextractをダウンロードする.~
~
👉http://gensen.dl.itc.u-tokyo.ac.jp/pytermextract/~
ダウンロードしたら,ダウンロード先のファイル(termextract...
コマンドプロンプトで,以下の操作を行う.~
pip install .
~
***core.pyの変更 [#pd0b1db6]
既存のcore.pyを用いるとエラーが起こる場合があるため変更す...
まず自身のパソコンのtermextractがインストールされているフ...
-保存場所の確認方法
import termextract
print(termextract.__path__)
このファイルの中のcore.pyを変更する.(今回はcore2.pyとし...
core2.pyにした時のモジュールの定義
import termextract.core2
~
変更箇所
from decimal import Decimal
~~~~~~~~~~~~~~~~~~~
84| importance = Decimal(importance) ** (1 / (2 * Decima...
~~~~~~~~~~~~~~~~~~~
エラーが起こる理由はおそらく重要度を計算するときに,計算...
~
**Janomeの辞書登録 [#c7686f71]
termextractの出力結果をもとにJanomeの辞書の登録を行う.~
csv形式で与えることでユーザー辞書を登録することができる.~
termextactはjanomeを用いる元のmecabを用いるものがあるが,...
-termextractの定義部分~
CHASEN_ARGS = r' -F "%m\t%f[7]\t%f[6]\t%F-[0,1,2,3]\t%f[...
CHASEN_ARGS += r' -U "%m\t%m\t%m\t%F-[0,1,2,3]\t\t\n"'
m = MeCab.Tagger(ipadic.MECAB_ARGS + CHASEN_ARGS)
m.parse('')
def get_mecab_tagged(text):
node = m.parseToNode(text)
buf = ''
while node:
if node.surface:
buf += node.surface + '\t' + node.feature + ...
node = node.next
return buf
def term_ext(tagged_text):
frequency = termextract.mecab.cmp_noun_dict(tagged_t...
lr = termextract.core2.score_lr(
frequency,
ignore_words=termextract.mecab.IGNORE_WORDS,
lr_mode=1, average_rate=1)
term_imp = termextract.core.term_importance(frequenc...
return Counter(term_imp)
def remove_single_words(terms):
c = Counter()
for cmp, value in terms.items():
if len(cmp.split(' ')) != 1:
c[termextract.core.modify_agglutinative_lang...
return c
-辞書作成部分
for i in tqdm.tqdm(range(text.shape[0])):
target_text = text.iloc[i][0]
tagged_text = get_mecab_tagged(target_text)
terms = term_ext(tagged_text)
compound = remove_single_words(terms)
for cmp_noun, value in compound.most_common(10):
# print(termextract.core.modify_agglutinative_la...
df_frequency.append(termextract.core.modify_aggl...
app_list = [-1, -1, 1000, '名詞', '固有名詞', '*', '...
app_list2 =['*', '*']
for i in range(len(df_frequency)):
df_append=[]
df_append.append(df_frequency[i])
df_append.extend(app_list)
df_append.append(df_frequency[i])
df_append.extend(app_list2)
df_csv_frequency.append(df_append)
df_dictio=pd.DataFrame(df_csv_frequency)
df_dictio.to_csv("user_dic_" + str(class_set) +".csv", s...
-実際のcsvファイル
#ref(ユーザー辞書2.png)
**分かち書き処理 [#pe2962a7]
sentences = []
sentences_2 = []
for i in tqdm.tqdm(range(text.shape[0])):
target_texts = text.iloc[i]
t = Tokenizer('user_dic_' + str(class_set) +'.csv', ...
texts = target_texts.str.split('。')
wakati_list = []
for s in texts[0]:
words = []
for token in t.tokenize(s):
s_token = token.part_of_speech.split(',')
# 一般名詞、自立動詞(「し」等の1文字の動詞...
if (s_token[0] == '名詞' and s_token[1] == '...
or (s_token[0] == '形容詞' and s_tok...
or (s_token[0] == '名詞' and s_token...
words.append(token.surface)
wakati_list.append(words)
sentences.append(wakati_list)
sentences_2.extend(wakati_list)
# combination_sentences = []
# for words in tqdm.tqdm(sentences_2):
combination_sentences = [list(itertools.combinations(wor...
combination_sentences = [[tuple(sorted(combi)) for combi...
tmp = []
for combinations in combination_sentences:
tmp.extend(combinations)
combination_sentences = tmp
touroku_list = []
for i in tqdm.tqdm(range(len(combination_sentences))):
if (combination_sentences[i][0] in df_frequency) or ...
touroku_list.append(combination_sentences[i])
-df_frequency[]~
それぞれの文章から最大10個重要度が高い順にdf_frequencyに...
for cmp_noun, value in compound.most_common(10):
df_frequency.append(termextract.core.modify_agglutin...
-combination_sentences~
分かち書きで抽出された単語同士の文章中での組み合わせを列...
例:[今日,私,学校,行った]➡[今日,私],[今日,学校],[...
combination_sentences = [list(itertools.combinations(wor...
combination_sentences = [[tuple(sorted(combi)) for combi...
tmp = []
for combinations in combination_sentences:
tmp.extend(combinations)
combination_sentences = tmp
-touroku_list[]~
分かち書きの結果をそのまま使うと,一般的な用語が多く含ま...
そのため,df_frequencyに登録されている重要語が高い用語が...
combination_sentencesの中に重要語が含まれていればそれをto...
for i in tqdm.tqdm(range(len(combination_sentences))):
if (combination_sentences[i][0] in df_frequency) or ...
touroku_list.append(combination_sentences[i])
*共起語ネットワーク [#raa586e3]
**共起関係の導出 [#z9e7882e]
Jaccard係数,Dice係数,Simpson係数の計算を行う.(実際に...
それぞれの係数の値は{jaccard_coef}に格納されている.(変...
-Simpson係数の計算
def make_overlap_coef_data(combination_sentences):
combi_count = collections.Counter(combination_senten...
word_associates = []
for key, value in combi_count.items():
word_associates.append([key[0], key[1], value])
word_associates = pd.DataFrame(word_associates, colu...
words = []
for combi in combination_sentences:
words.extend(combi)
word_count = collections.Counter(words)
word_count = [[key, value] for key, value in word_co...
word_count = pd.DataFrame(word_count, columns=['word...
word_associates = pd.merge(
word_associates,
word_count.rename(columns={'word': 'word1'}),
on='word1', how='left'
).rename(columns={'count': 'count1'}).merge(
word_count.rename(columns={'word': 'word2'}),
on='word2', how='left'
).rename(columns={'count': 'count2'}).assign(
union_count=lambda x: np.minimum(x.count1,x.coun...
).assign(
count_diff=lambda x: np.abs(x.count1 - x.count2)
).assign(jaccard_coef=lambda x: x.intersection_count...
['jaccard_coef', 'intersection_count'], ascendin...
)
--count_diff~
お互いの集合の要素差を求めている
--union_count~
count1とcount2の小さいほうを求める.
--jaccard_coef~
intersection_countをunion_countで割る
-Jaccard係数の計算
~~~~~~~~~~同文~~~~~~~~~~
word_associates = pd.merge(
word_associates,
word_count.rename(columns={'word': 'word1'}),
on='word1', how='left'
).rename(columns={'count': 'count1'}).merge(
word_count.rename(columns={'word': 'word2'}),
on='word2', how='left'
).rename(columns={'count': 'count2'}).assign(
union_count=lambda x: x.count1 + x.count2 - x.in...
).assign(jaccard_coef=lambda x: x.intersection_count...
['jaccard_coef', 'intersection_count'], ascendin...
)
--intersection_count~
要素の共通部分の数
--union_count~
count1とcount2の合計からintercsection_countを引くことで,...
--jaccard_coef~
intersection_countをunion_countで割る
-Dice係数の計算
~~~~~~~~~同文~~~~~~~~~~
word_associates = pd.merge(
word_associates,
word_count.rename(columns={'word': 'word1'}),
on='word1', how='left'
).rename(columns={'count': 'count1'}).merge(
word_count.rename(columns={'word': 'word2'}),
on='word2', how='left'
).rename(columns={'count': 'count2'}).assign(
union_count=lambda x: x.count1 + x.count2
).assign(jaccard_coef=lambda x: 2 * x.intersection_c...
['jaccard_coef', 'intersection_count'], ascendin...
)
--union_ount~
count1とcount2の合計
--jaccard_coef
intersection_countの2倍をunion_countで割る.
実際の出力結果
#ref(関係.jpg)
-intersection_countにはword1とword2が同時に出てくる回数.
-count1はword1の出現回数
-count2はword2の出現回数
-union_countはcount1とcount2の小さいほうの数
-count_diffはcount1とcount2の要素数の差
-jaccard_coefはsimpson係数の値
⚠カラムの名前が混在しているので注意!
***しきい値の設定 [#ydce4187]
より良い結果を得るためにしきい値を設定する.
具体的には
+Simpson係数が1未満のもの
+お互いの要素差が5000未満のもの
jaccard_coef_data = make_overlap_coef_data(touroku_list)
simpson = jaccard_coef_data['count_diff']
simpson2 = jaccard_coef_data['jaccard_coef']
filt = (simpson < 5000) & (simpson2 < 1)
jaccard_coef_data[filt].to_pickle('jaccard_coef.pkl')
**jsonファイルの作成 [#pe7fdb90]
3D Force-Directed Graphに共起関係の情報を送るためにjsonフ...
simpson係数の結果からjsonファイルに変換する
jaccard_coef_data = pd.read_pickle('jaccard_coef.pkl')
got_data = jaccard_coef_data.head(int(g_size))
sources = got_data['word1']#count
targets = got_data['word2']#first
edge_data = zip(sources, targets)
count_list_df = pd.DataFrame([{'first' : i[0], 'second' ...
count_id = count_list_df.stack().drop_duplicates().tolis...
word1 = got_data[['word1','count1']].rename(columns={ 'w...
word2 = got_data[['word2','count2']].rename(columns={ 'w...
df_word_count = pd.concat([word1, word2]).drop_duplicate...
def create_json(nodes, links):
json_data = {
"nodes": nodes,
"links": links
}
return json_data
edge_data = zip(sources, targets)
nodes = []
for _, row in df_word_count.iterrows():
node = {"id": row['word'], "group": 1}
if row['count'] > 3000:
node['group'] = 2
nodes.append(node)
links = [{"source": values[0], "target": values[1], "val...
json_data = create_json(nodes, links)
with open('static/output.json', 'w', encoding='utf-8') a...
json.dump(json_data, json_file, ensure_ascii=False, ...
作成するjsonファイルの形式(output.json)
{
"nodes": [
{
"id": "砂利",
"group": 1
},
{
"id": "実施形態",
"group": 2
},
~~~~~~~~~~省略~~~~~~~~~~
{
"id": "残雪",
"group": 1
},
{
"id": "上顎",
"group": 1
}
],
"links": [
{
"source": "砂利",
"target": "骨材",
"value": 1
},
{
"source": "咬合部",
"target": "歯列",
"value": 1
},
~~~~~~~~~~省略~~~~~~~~~~
{
"source": "ヒドロキシ",
"target": "紫外線吸収剤",
"value": 1
},
{
"source": "実施形態",
"target": "符号",
"value": 1
}
]
}
-"nodes"にはグラフに表示される単語の定義を行う.~
--"id"はノードの単語.~
--"group"は色分けなどをしたいときにノードのグループを指定...
-"links"には共起関係を記述する.~
--"source"は共起元の単語.~
--"target"は共起先の単語.~
--"value"は結ぶ線の大きさを変更するときなどに利用される.~
**3Dグラフ [#gd773348]
3Dグラフの描画にはThree.jsのモジュール”3D Force-Directed ...
参考にしたサイト👉https://vasturiano.github.io/3d-force-g...
javascriptの買い方はサイトを参考にすれば様々な変更が可能.~
⚠モジュールのインポート方法はサイトのものでは行えなかった...
-graph.html
<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<style>body{margin: 0px; padding: 0px;}</style>
</head>
<body>
<button type="button" onclick="history.back()">戻る</b...
<div id="three" style="background-color: aliceblue;"><...
<script type="module" src="https://unpkg.com/three@0.1...
<script type="module" src="https://unpkg.com/3d-force-...
<script type="module" src="https://unpkg.com/three-spr...
<script src="./static/main2.js" charset="utf-8" defer>...
</body>
</html>
--<script type="module" src="https://unpkg.com/three@0.15...
three.jsのインポート
--<script type="module" src="https://unpkg.com/3d-force-g...
3D Force-Directed Graphのモジュールのインポート
--<script type="module" src="https://unpkg.com/three-spri...
テキストをノードにするときに必要なモジュールのインポート
--<script src="./static/main2.js" charset="utf-8" defer><...
プログラムに使うjavascriptのファイルの指定
-main2.js
const highlightLinks = new Set();
const highlightNodes = new Set();
let hoverNode = null;
const Graph = ForceGraph3D()
(document.getElementById("three"))
.jsonUrl('http://localhost:5000/static/output.json')
.nodeLabel('id')
.nodeRelSize(20)
.nodeThreeObject(node => {
const sprite = new SpriteText(node.id);
const group = new SpriteText(node.group)
// const sprite = new SpriteText(`${link.source} ...
sprite.material.depthWrite = false; // make sprit...
if (node.group == '2') {
sprite.color = 'red';
} else {
sprite.color = 'black'
}
sprite.textHeight = 7.5;
return sprite;
})
.onNodeClick(node => {
const distance = 100;
const distRatio = 1 + distance/Math.hypot(node.x,...
const newPos = node.x || node.y || node.z
? { x:node.x * distRatio, y: node.y * distRatio, ...
: { x: 0, y: 0, z: distance};
Graph.cameraPosition(
newPos,
node,
100
)
})
// link
.linkOpacity(0.25)
.linkDirectionalArrowLength(3)
.linkDirectionalArrowRelPos(1)
.linkCurvature(0.01)
.linkDirectionalParticleWidth(2)
.linkDirectionalParticles("value")
.linkDirectionalParticleSpeed(d => d.value * 0.01)
.linkThreeObjectExtend(true)
.linkColor(() => '#708090')
.linkWidth(1)
.backgroundColor("#f8f8f8");
-ここで共起関係を記述したjsonファイルを指定している.~
⚠ここのパスにlocalhost:5000を指定しているため,ローカルで...
.jsonUrl('http://localhost:5000/static/output.json')
-実際に共起語の描画の処理を行っている.~
ノードの色の変更の処理もここで行う.~
.nodeThreeObject
-初期設定だとグラフの回転軸が中央で固定になってしまうため...
.onNodeClick
-矢印の設定もろもろ
.linkOpacity(0.25)
.linkDirectionalArrowLength(3)
.linkDirectionalArrowRelPos(1)
.linkCurvature(0.01)
.linkDirectionalParticleWidth(2)
.linkDirectionalParticles("value")
.linkDirectionalParticleSpeed(d => d.value * 0.01)
.linkThreeObjectExtend(true)
.linkColor(() => '#708090')
.linkWidth(1)
--linkDirectionalParticlesはノードの矢印にアニメーション...
-初期設定では背景の色が黒色だが見にくいため白色に変更して...
.backgroundColor("#f8f8f8")
htmlの
<div id="three" style="background-color: aliceblue;"></d...
javascritpの
<div id="three" style="background-color: aliceblue;"></d...
の部分のidが同じになっていないといけないので注意.
~
実際の出力結果
#ref(3d.jpg)
~
*その他 [#dd9fe27e]
**ロード画面 [#bcf8e2e2]
スクレイピングなどの処理を行っているとき画面がそのままだ...
<div id="loading">
<p>作成中...</p>
</div>
<script>
window.addEventListener('DOMContentLoaded', function...
// ページの表示状態が変わったときに実行
document.addEventListener("visibilitychange", fu...
console.log(document.visibilityState);
document.getElementById('loading').style.display...
});
});
function performSearch() {
var loadingScreen = document.getElementById('loa...
// ロード画面を表示
loadingScreen.style.display = 'flex';
}
</script>
-<div>タグの<p>の中身を変更すれば画面に表示される文字が変...
-ページをブラウザバックしたときにロード画面がそのままにな...
⚠別のタブに移動したときも消えるので注意!
**ブラウザバック [#dcb69e5a]
ブラウザバックをしたときにフォームなどのユーザからの入力...
-ページ遷移するときにそのまま処理の部分に飛ぶのではなく以...
@app.route('/post', methods=['POST'])
def post():
session["class"] = request.form.get("class_select")
return redirect(url_for('select'))
@app.route("/select", methods=["GET", "POST"])
def select():
if 'class' not in session:
return redirect(url_for('select'))
class_set = session["class"]
~~~~~~~~~~省略~~~~~~~~~~
[[技術資料]]
*目次 [#m8988ea1]
#CONTENTS
*目的 [#q895f5ba]
産業連関表を活用した為替変動による波及効果の分析, 金融経...
*使用するファイル [#pe64d1b6]
本研究で使用するファイルはすべてGoogleDriveにある.
&br;
user:iie.lab.tpu.2324@gmail.com
&br;
「マイドライブ」→「学生」→「24_r2戸田」→「保存期間5年」→...
&br;
すべてのzipをダウンロードする.~
&color(red){中山実行プログラム};
#ref(中山実行プログラム.zip)
|フォルダ名|用途|ファイル名|ファイルの場所|
|kawasehendou|為替変動の影響分析|''&color(red){7to12_Yfin...
|kabuka|株価データのデータ収集|''&color(red){7to12_JPX401...
|sankakuka_2|産業連関表の三角化|''&color(red){sankakuka_2...
|soukan|相関ヒートマップの作成|''&color(red){soukan_7to12...
|3Dgraph|jsonファイルの作成|''&color(red){3Dgraph_kihon.i...
|3Dgraph|3Dグラフを可視化するための実行ファイル|app_0114....
|3Dgraph|javascriptで読み込む用のjsonファイル|output_toda...
|3Dgraph|3Dグラフのデータの可視化|index_0114.html|3Dgraph...
|3Dgraph|3Dグラフを作成するときのjavascriptのファイル|mai...
~
***プログラムを修正する [#zb7feed2]
上記で''&color(red){あかで書かれているプログラム};''は,~
csvファイルを書きこんだり,読みこんだりするときに,絶対パ...
そのままでは,「''C:/Users/ta_na/''/...」になっているはず...
その「''C:/Users/ta_na/''」のところを,''すべてのプログラ...
上記でフォルダを置いた絶対パスに修正する必要がある.~
「Visual Studio Code」では,特定の文字列をすべて別の文字...
置換する機能があるので,それを利用しよう.~
***動作環境 [#x9020b74]
Pythonのバージョンは3.12.4を用いる
|ライブラリ名|バージョン|
|selenium|4.27.1|
|panads|1.3.5|
|numpy|1.26.4|
|yfinance|0.2.52|
|matplotlib|3.9.2|
|webdriver-manager|4.0.2|
|beautifulsoup4|4.12.3|
|seaborn|0.13.2|
|pulp|2.9.0|
|networkx|3.4.2|
|flask|3.0.3|
~
モジュールのインストールはコマンドプロンプトでpip install...
バージョンまで指定する場合はコマンドプロンプトでpip insta...
でインストールする
~
*** 各プログラムを実行する [#ce4e9821]
各プログラムを,以下のとおり,''&color(red){順番に};''実...
――――――――――――――~
''1. 7to12_Yfinance.ipynb''~
''2. sankakuka_2020.py''~
''3. 3Dgraph_kihon.ipynb''~
''4. app_0114.py''~
''5. 7to12_JPX401.ipynb''~
''6. soukan_7to12_map_yfinance.ipynb''~
――――――――――――――~
*産業連関分析 [#ea813e90]
**投入係数行列の作成 [#i8722536]
-7to12_Yfinance.ipynb
import numpy as np
import pandas as pd
#2020年国産表37部門
df_kokusan = pd.read_csv("C:/Users/ta_na/OneDrive/デス...
# 3行目以降(インデックス 2 以降)、3列目以降(インデッ...
subset_df_kokusan = df_kokusan.iloc[3:,2:]
# データ型を確認し、必要ならfloatに変換
subset_df_kokusan = subset_df_kokusan.astype(float)
# インデックスをリセットして1からの連番にする
subset_df_kokusan.reset_index(drop=True, inplace=True) ...
subset_df_kokusan.index = subset_df_kokusan.index + 1 ...
# 列名をリセットして1からの連番にする
subset_df_kokusan.columns = range(1, len(subset_df_koku...
#内生部門だけ抽出
# インデックスと列の39以降を削除(1始まりの場合)
subset_df_kokusan = subset_df_kokusan.loc[:37, :37]
print(subset_df_kokusan)
取得した産業連関表から内生部門(37×37の行列)を抜き出す.
~
#国内生産額の抽出
# インデックス48番の行を取得
row_48 = df_kihon.loc[48]
# NaN を含む行を削除
kokunaiseisan_row = row_48.dropna()
# 最初の2行と最後の1行を削除
kokunaiseisan_row = kokunaiseisan_row.iloc[2:-1]
# データ型を確認し、必要ならfloatに変換
kokunaiseisan_row = kokunaiseisan_row.astype(float)
# インデックスをリセットして1からの連番にする
kokunaiseisan_row.reset_index(drop=True, inplace=True) ...
kokunaiseisan_row.index = kokunaiseisan_row.index + 1 ...
print(kokunaiseisan_row)
産業連関表から国内生産額を抽出する.
#粗付加価値額の抽出
# インデックス47番の行を取得
row_47 = df_kihon.loc[47]
# NaN を含む行を削除
arahukakathi_row = row_47.dropna()
# 最初の2行と最後の1行を削除
arahukakathi_row = arahukakathi_row.iloc[2:-1]
# データ型を確認し、必要ならfloatに変換
arahukakathi_row = arahukakathi_row.astype(float)
# インデックスをリセットして1からの連番にする
arahukakathi_row.reset_index(drop=True, inplace=True) ...
arahukakathi_row.index = arahukakathi_row.index + 1 ...
print(arahukakathi_row)
産業連関表から粗付加価値額を抽出する.
# 国産品投入係数行列を計算
coefficient_matrix_kokusan = subset_df_kokusan.div(koku...
coefficient_matrix_kokusan
国産品投入係数行列を作成
# 粗付加価値率(国内生産額÷粗付加価値額)を計算
coefficient_matrix_arahukakathi = arahukakathi_row / ko...
coefficient_matrix_arahukakathi
#こっちのyfinanceのドル円レートを使う
import yfinance as yf
import pandas as pd
# USD/JPYの為替データを取得
usd_jpy = yf.download("JPY=X", start="2024-07-01", end=...
# 終値を取得(Series にする)/ここから、変更が必要にな...
usd_jpy = usd_jpy[['Close']].reset_index().set_index('D...
# 結果を表示
print(type(usd_jpy))
# 結果を表示
print(usd_jpy)
※DataframeがSeriesに変換されない場合、各々で調べてコード...
Seriesに変換されていない場合、この先でエラーが発生する.~
※Yahoo Finance(YF)のAPIやウェブサービスを使用してUSD/JP...
→時間をおいて再度リクエストを試す
※''&color(red){yfinanceのバージョンを0.2.52};''に必ずする...
# 一日の変動率を計算する(当日−前日)/前日
daily_change_rate = usd_jpy.pct_change() * 100
# 最初の1行を削除
daily_change_rate = daily_change_rate.iloc[1:]
# 結果を表示
print(daily_change_rate)
**輸入価格変動の影響 [#x8fea72e]
# 米ドル建て輸入比率を辞書形式で定義
import_ratio_data = {
"食料品・飼料": 56.2,
"繊維品": 36.8,
"金属・同製品": 79.6,
"木材・同製品": 77.1,
"石油・石炭・天然ガス": 97.3,
"化学製品": 28.1,
"はん用・生産用・業務用機器" : 39.3,
"電気・電子機器" : 68.5,
"輸送用機器" : 37.8,
"その他産品・製品" : 62.6,
"輸入計" : 64.4
}
# データをリストに変換
import_ratio_list = [{"カテゴリ": category, "比率": rat...
# 米ドル建て契約比率
R_yunyu = pd.Series([56.2, 79.6, 56.2, 36.8, 77.1, 28.1...
# 産業名リスト
industry_names = [
"農林漁業", "鉱業", "飲食料品", "繊維製品", "パルプ・...
"プラスチック・ゴム製品", "窯業・土石製品", "鉄鋼", "...
"生産用機械", "業務用機械", "電子部品", "電気機械", "...
"建設", "電力・ガス・熱供給", "水道", "廃棄物処理", "...
"情報通信", "公務", "教育・研究", "医療・福祉", "他に...
"対個人サービス", "事務用品", "分類不明"
]
輸入価格変動の影響を求める際に輸入品価格ベクトル Pim を,...
~
各産業の米ドル建て契約比率には日本銀行「輸出・輸入物価指...
2023 年 12 月の値を用いた
https://www.boj.or.jp/statistics/outline/exp/pi/cgpi_2020...
~
#輸入の影響
# 日付ごとの結果を格納する辞書
result_yunyu_dict = {}
# 各日付ごとに計算を実施
for date, delta_E in daily_change_rate.items():
#print(delta_E)
# Delta_P_im の計算
delta_P_im_yunyu = R_yunyu * (-delta_E) / 100 # 各...
# 一次波及の計算
# delta_P_im に一致するインデックスを coefficient_m...
common_indices =
coefficient_matrix_yunyu.index.intersection(delta_P_im_...
sub_matrix = coefficient_matrix_yunyu.loc[common_in...
delta_P_d_1 = sub_matrix.multiply(delta_P_im_yunyu[...
# 完全波及の計算
# 1. I - A_d^T を計算
I = np.eye(len(coefficient_matrix_kokusan)) # 単位...
I_minus_Ad_T = I - coefficient_matrix_kokusan.T.val...
# 2. 逆行列を計算
I_minus_Ad_T_inv = np.linalg.inv(I_minus_Ad_T)
# 3. A_mi^T を計算
A_mi_T = coefficient_matrix_yunyu.T.values
# 4. ΔP_d を計算
delta_P_d_2 = I_minus_Ad_T_inv @ (A_mi_T @ delta_P_...
# 結果を Pandas の Series として保存
delta_P_d_2 = pd.Series(delta_P_d_2, index=range(37))
# インデックスをリセットして1からの連番にする
delta_P_d_2.reset_index(drop=True, inplace=True) #...
delta_P_d_2.index = delta_P_d_2.index + 1 # ...
# 付加価値を分母にしたものに変換
result_yunyu = delta_P_d_2 / coefficient_matrix_ara...
# インデックスを産業名に置き換える
result_yunyu.index = industry_names
# 結果を辞書に保存
result_yunyu_dict[date] = result_yunyu
# 各日付の結果を表示(例)
for date, result in result_yunyu_dict.items():
print(f"=== {date} ===")
print(result)
print("\n")
#ref(nikkei2.png,,720x400)
以下のリンク先の資料の6,7ページ目の計算のプログラムコード
https://www.jcer.or.jp/jcer_download_log.php?post_id=5528...
# 産業・日付ごとのデータを DataFrame に変換
all_results_yunyu = []
for industry in industry_names:
for date, result in result_yunyu_dict.items():
value = result[industry]
all_results_yunyu.append({"日付": date, "産業":...
result_df_yunyu = pd.DataFrame(all_results_yunyu)
print(result_df_yunyu)
# CSV 保存
#result_df_yunyu.to_csv("csv/out_data/industry_date_yun...
index=False, encoding="utf-8-sig")
# 日付を統一形式に変換
result_df_yunyu['日付'] = pd.to_datetime(result_df_yuny...
format='%Y.%m.%d')
# ピボットテーブルで変換
reshaped_df_yunyu = result_df_yunyu.pivot(index='日付',...
# 列名をリセットし、日付を列として戻す
reshaped_df_yunyu.reset_index(inplace=True)
reshaped_df_yunyu.rename(columns={'日付': 'Date'}, inpl...
# 結果を表示
print(reshaped_df_yunyu)
# CSV 保存
reshaped_df_yunyu.to_csv("csv/out_data/industry_date_yu...
結果を見やすい形にしてcsvファイルに保存する.
**輸出価格変動の影響 [#k13ded11]
輸出価格変動の影響を求める際に輸出価格の変化率を「為替の...
輸入価格変動と同様に日本銀行「輸出・輸入物価指数の契約通...
2023 年 12 月の値を用いる.
# 日付を統一形式に変換
result_df_yusyutsu['日付'] = pd.to_datetime(result_df_y...
result_df_yunyu['日付'] = pd.to_datetime(result_df_yuny...
# 二つのデータフレームをマージ
merged_df = pd.merge(result_df_yusyutsu, result_df_yuny...
# 値を加算
merged_df['値_合計'] = merged_df['値_輸出'] + merged_df...
# 結果を表示
print(merged_df)
# 元の産業順序を取得
original_order = merged_df['産業'].drop_duplicates().to...
# ピボットテーブルで変換
reshaped_df_marge = merged_df.pivot(index='日付', colum...
# 列の順序を元の順序に並び替え
reshaped_df_marge = reshaped_df_marge[original_order]
# 列名をリセットし、日付を列として戻す
reshaped_df_marge.reset_index(inplace=True)
reshaped_df_marge.rename(columns={'日付': 'Date'}, inpl...
# 結果を表示
print(reshaped_df_marge)
# CSV 保存
#reshaped_df_marge.to_csv("csv/industry_date_marge_2015...
輸出・輸入の価格変動の影響の差し引きを求める.
# 指定した列を足し合わせて新しい列を作成
reshaped_df_marge['非鉄金属・金属製品'] = (
reshaped_df_marge['非鉄金属'] +
reshaped_df_marge['金属製品']
)
reshaped_df_marge['はん用機械・生産用機械・業務用機械']...
reshaped_df_marge['はん用機械'] +
reshaped_df_marge['生産用機械'] +
reshaped_df_marge['業務用機械']
)
reshaped_df_marge['電気機械・電子部品・情報通信機器'] = (
reshaped_df_marge['電気機械'] +
reshaped_df_marge['電子部品'] +
reshaped_df_marge['情報通信機器']
)
reshaped_df_marge['対事業所サービス・対個人サービス'] = (
reshaped_df_marge['対事業所サービス'] +
reshaped_df_marge['対個人サービス']
)
# 元の列を削除
reshaped_df_marge.drop(
['非鉄金属', '金属製品',
'はん用機械', '生産用機械', '業務用機械',
'電気機械', '電子部品', '情報通信機器',
'対事業所サービス', '対個人サービス',
'水道', '廃棄物処理', '公務', '教育・研究',
'他に分類されない会員制団体', '事務用品', '分類不明'],
axis=1,
inplace=True
)
# 結果を表示
print(reshaped_df_marge)
# CSV 保存
reshaped_df_marge.to_csv("csv/out_data/industry_date_ma...
産業連関表における部門の分け方と業種別株価における業種の...
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import rcParams
# 日本語フォントを指定
rcParams['font.family'] = 'Meiryo' # Windowsの場合はMe...
# 折れ線グラフのプロット
plt.figure(figsize=(15, 6))
for column in reshaped_df_marge.columns:
plt.plot(reshaped_df_marge.index, reshaped_df_marge...
# グラフの設定
plt.title('為替変動による各産業への影響値の推移(2024年7...
plt.xlabel('Date', fontsize=12)
plt.ylabel('付加価値比', fontsize=12)
# 凡例をグラフの外側に配置
plt.legend(title="産業", bbox_to_anchor=(1.05, 1), loc=...
plt.grid(True)
# グラフを表示
plt.tight_layout()
plt.show()
#ref(output_1.png,,実行結果,,720x400)
*3Dグラフの作成 [#eeca9a90]
産業連関表の三角化を行う.
#ref(sankakuka2.png,,720x400)
~
-sankakuka_2020.py
import numpy as np
import pandas as pd
from pulp import LpProblem, LpVariable, LpBinary, lpSum,...
import networkx as nx
import matplotlib.pyplot as plt
# 入力データの読み込み
def read_input_data(file_path):
# CSVファイルを読み込む
df_yunyu = pd.read_csv(file_path)
# セクター数を取得
#NSec = int(df.iloc[0, 1])
NSec = 37
# A行列を取得(2行目以降を数値行列として読み込む)
#A = df.iloc[2:, 2:].replace({',': ''}, regex=True)....
A = df_yunyu.replace({',': ''}, regex=True).values.a...
return NSec, A
# 最適化問題の定義と解決
def solve_triangulation(NSec, A):
problem = LpProblem("Triangulation", LpMaximize)
# セクターの範囲
SSec = range(NSec)
# 決定変数
X = [[LpVariable(f"X_{i}_{j}", cat=LpBinary) for j i...
# 制約条件
for i in SSec:
for j in SSec:
if i < j:
for k in SSec:
if j < k:
problem += X[i][j] + X[j][k] - X...
f"Transitivity1_{i}_{j}_{k}"
problem += X[i][j] + X[j][k] - X...
f"Transitivity2_{i}_{j}_{k}"
# 目的関数
LowSum = lpSum(
(A[i, j] - A[j, i]) * X[i][j] + A[j, i]
for i in SSec for j in SSec if i < j
)
problem += LowSum
# 問題を解く
problem.solve()
# 結果を取り出す
Xo = np.zeros((NSec, NSec))
Rank = np.zeros(NSec)
for i in SSec:
for j in SSec:
if i < j:
Xo[i, j] = value(X[i][j])
elif i > j:
Xo[i, j] = 1 - value(X[j][i])
Xo[i, i] = 1
Rank[i] = sum(Xo[i, :])
return Xo, Rank
# 結果(rank)をファイルに出力
def write_output_data(file_path, Rank):
df = pd.DataFrame({"Sector": np.arange(1, len(Rank) ...
# インデックスをリセットして1からの連番にする
df.reset_index(drop=True, inplace=True) # 現在のイ...
df.index = df.index + 1 # インデックスを1から...
# 産業名リスト
industry_names = [
"農林漁業", "鉱業", "飲食料品", "繊維製品", "パ...
"プラスチック・ゴム製品", "窯業・土石製品", "鉄鋼...
"生産用機械", "業務用機械", "電子部品", "電気機械...
"建設", "電力・ガス・熱供給", "水道", "廃棄物処理...
"情報通信", "公務", "教育・研究", "医療・福祉", "...
"対個人サービス", "事務用品", "分類不明"
]
# インデックスを産業名に置き換える
df.index = industry_names
df.to_csv(file_path, encoding="utf-8-sig")
# Rank 列を昇順でソート
df_rank_sorted = df.sort_values(by="Rank", ascending...
df_rank_sorted.to_csv("C:/Users/ta_na/OneDrive/デス...
# 結果(行列X)をファイルに出力
def write_output_matrix(file_path, matrix):
# 行列をデータフレームに変換して保存
df = pd.DataFrame(matrix)
df.to_csv(file_path, index=False, header=False)
# メイン処理
if __name__ == "__main__":
# 入力ファイルと出力ファイル
IN_FILE = "C:/Users/ta_na/OneDrive/デスクトップ/kawa...
OUT_FILE_RANK = "C:/Users/ta_na/OneDrive/デスクトップ...
OUT_FILE_X = "C:/Users/ta_na/OneDrive/デスクトップ/sa...
# データの読み込み
NSec, A = read_input_data(IN_FILE)
# 最適化の実行
Xo, Rank = solve_triangulation(NSec, A)
# 結果を保存
write_output_data(OUT_FILE_RANK, Rank)
write_output_matrix(OUT_FILE_X, Xo)
print(f"Results saved to {OUT_FILE_RANK}")
print(f"Results saved to {OUT_FILE_X}")
目的関数は, Aij と Aji の値を比べて, 産業部門 i と産業部...
**jsonファイルの作成 [#c0352b1c]
3D Force-Directed Graphに産業部門間の関係の情報を送るため...
産業部門間の関係が格納されたcsvファイルをjsonファイルに変...
-3Dgraph_kihon.ipynb
import numpy as np
import pandas as pd
X = pd.read_csv("C:/Users/ta_na/OneDrive/デスクトップ/s...
X
import numpy as np
import pandas as pd
coefficient_matrix_kihon = pd.read_csv("C:/Users/ta_na/...
coefficient_matrix_kihon
# X の 1 の部分に対応する coefficient_matrix_kihon の値...
# X の 0 の部分は 0 のままにする
coefficient_matrix_kihon_2 = X * coefficient_matrix_kihon
# 出力結果
print(coefficient_matrix_kihon_2)
# 新しいデータフレームを作成
rows = []
for i, row_label in enumerate(coefficient_matrix_kihon_...
for j, col_label in enumerate(coefficient_matrix_ki...
if i != j and coefficient_matrix_kihon_2.iloc[i...
rows.append({'from': row_label, 'to': col_l...
# 新しいデータフレームを作成
result_df = pd.DataFrame(rows)
print(result_df)
# CSVファイルに保存
result_df.to_csv('csv/out_data/from_to_kihon.csv', inde...
# 'effect'列の値を100倍
result_df['effect'] = result_df['effect'] * 100
#全部
import pandas as pd
import csv
import json
# effectを削除
df_effect=result_df.drop(["effect"],axis=1)
#fromとtoの中の要素を一つのリストにする
count_id = df_effect.stack().drop_duplicates().tolist()
# links の形式にデータを変換する
links = []
for index, row in result_df.iterrows():
links.append({
"source": row['from'],
"target": row['to'],
"value": row['effect']
})
# データを指定された形式に変換
nodes = [{"id": item, "group": 1} for item in count_id]
# JSON形式に変換
result = {"nodes": nodes, "links": links}
# JSONファイルに保存
with open("static/json/output_toda_kihon_zenbu.json", "...
json.dump(result, f, indent=2)
作成するjsonファイルの形式(output_toda_kihon_zenbu.json)
{
"nodes": [
{
"id": "\u8fb2\u6797\u6f01\u696d",
"group": 1
},
{
"id": "\u98f2\u98df\u6599\u54c1",
"group": 1
},
~~~~~~~~~~省略~~~~~~~~~~
{
"id": "\u60c5\u5831\u901a\u4fe1",
"group": 1
},
{
"id": "\u5bfe\u4e8b\u696d\u6240\u30b5\u30fc\u...
"group": 1
}
],
"links": [
{
"source": "\u8fb2\u6797\u6f01\u696d",
"target": "\u98f2\u98df\u6599\u54c1",
"value": 19.05628066765477
},
{
"source": "\u8fb2\u6797\u6f01\u696d",
"target": "\u6559\u80b2\u30fb\u7814\u7a76",
"value": 0.13824726106617
},
~~~~~~~~~~省略~~~~~~~~~~
{
"source": "\u5206\u985e\u4e0d\u660e",
"target": "\u4ed6\u306b\u5206\u985e\u3055\u30...
"value": 1.2702003066174
},
{
"source": "\u5206\u985e\u4e0d\u660e",
"target": "\u5bfe\u500b\u4eba\u30b5\u30fc\u30...
"value": 0.43188001994264
}
]
}
-"nodes"にはグラフに表示される単語の定義を行う.~
--"id"はノードの単語.~
--"group"は色分けなどをしたいときにノードのグループを指定...
-"links"には産業部門間の関係を記述する.~
--"source"は供給元の単語.~
--"target"は供給先の単語.~
--"value"は結ぶ線の大きさを変更するときなどに利用される.~
**3Dグラフ [#b7b070fc]
3Dグラフの描画にはThree.jsのモジュール”3D Force-Directed ...
参考にしたサイト👉https://vasturiano.github.io/3d-force-g...
javascriptの買い方はサイトを参考にすれば様々な変更が可能.~
⚠モジュールのインポート方法はサイトのものでは行えなかった...
-index_0114.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>3D Graph with Rankings</title>
<style>
body {
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
height: 100vh;
}
#container {
display: flex;
flex: 1;
width: 100%;
}
#three {
flex: 1;
background-color: aliceblue;
height: 100%;
}
#info {
position: fixed; /* fixedに変更して、スクロールして...
top: 10px;
right: 10px;
background-color: #fff;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
width: 300px;
max-height: 900px;
overflow-y: auto;
z-index: 10;
}
#rankTable {
position: fixed; /* 左上に固定表示 */
top: 10px;
left: 10px;
background-color: #fff;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
width: 300px;
max-height: 900px;
overflow-y: auto;
z-index: 10;
font-size: 12px;
}
/* レスポンシブ対応 */
@media screen and (max-width: 768px) {
#container {
flex-direction: column;
}
#rankTable {
width: 100%;
}
#three {
width: 100%;
height: 400px;
}
}
</style>
</head>
<body>
<!-- 左上にランク表 -->
<div id="rankTable">
<table>
<thead>
<tr>
<th>産業部門名</th>
<th>順列</th>
</tr>
</thead>
<tbody>
<tr><td>生産用機械</td><td>1</td></tr>
<tr><td>医療・福祉</td><td>2</td></tr>
<tr><td>教育・研究</td><td>3</td></tr>
<tr><td>対個人サービス</td><td>4</td></tr>
<tr><td>飲食料品</td><td>5</td></tr>
<tr><td>農林漁業</td><td>6</td></tr>
<tr><td>水道</td><td>7</td></tr>
<tr><td>他に分類されない会員制団体</td><td>8</td></tr>
<tr><td>分類不明</td><td>9</td></tr>
<tr><td>公務</td><td>10</td></tr>
<tr><td>輸送機械</td><td>11</td></tr>
<tr><td>情報通信機器</td><td>12</td></tr>
<tr><td>事務用品</td><td>13</td></tr>
<tr><td>業務用機械</td><td>14</td></tr>
<tr><td>建設</td><td>15</td></tr>
<tr><td>はん用機械</td><td>16</td></tr>
<tr><td>電気機械</td><td>17</td></tr>
<tr><td>電子部品</td><td>18</td></tr>
<tr><td>窯業・土石製品</td><td>19</td></tr>
<tr><td>金属製品</td><td>20</td></tr>
<tr><td>鉄鋼</td><td>21</td></tr>
<tr><td>非鉄金属</td><td>22</td></tr>
<tr><td>廃棄物処理</td><td>23</td></tr>
<tr><td>繊維製品</td><td>24</td></tr>
<tr><td>その他の製造工業製品</td><td>25</td></tr>
<tr><td>パルプ・紙・木製品</td><td>26</td></tr>
<tr><td>プラスチック・ゴム製品</td><td>27</td></tr>
<tr><td>化学製品</td><td>28</td></tr>
<tr><td>電力・ガス・熱供給</td><td>29</td></tr>
<tr><td>石油・石炭製品</td><td>30</td></tr>
<tr><td>鉱業</td><td>31</td></tr>
<tr><td>商業</td><td>32</td></tr>
<tr><td>運輸・郵便</td><td>33</td></tr>
<tr><td>不動産</td><td>34</td></tr>
<tr><td>金融・保険</td><td>35</td></tr>
<tr><td>情報通信</td><td>36</td></tr>
<tr><td>対事業所サービス</td><td>37</td></tr>
</tbody>
</table>
</div>
<!-- 真ん中に3Dグラフ -->
<div id="three"></div>
<!-- 右上にノード情報 -->
<div id="info">
<!-- ノードの情報がここに表示されます -->
</div>
<!-- JavaScript ライブラリの読み込み -->
<script type="module"
src="https://unpkg.com/three@0.158.0/build/three.js" def...
<script type="module" src="https://unpkg.com/3d-force-...
<script type="module" src="https://unpkg.com/three-spri...
<script src="./static/main2_0114.js" charset="utf-8" de...
</body>
</html>
--<script type="module" src="https://unpkg.com/three@0.15...
three.jsのインポート
--<script type="module" src="https://unpkg.com/3d-force-g...
3D Force-Directed Graphのモジュールのインポート
--<script type="module" src="https://unpkg.com/three-spri...
テキストをノードにするときに必要なモジュールのインポート
--<script src="./static/main2_0114.js" charset="utf-8" de...
プログラムに使うjavascriptのファイルの指定
~
-main2_0114.js
const highlightLinks = new Set();
const highlightNodes = new Set();
let hoverNode = null;
const Graph = ForceGraph3D()
(document.getElementById("three"))
.jsonUrl('http://127.0.0.1:5000/static/json/output_...
.nodeColor('#ffffff')
.nodeLabel('id')
.nodeRelSize(20)
.nodeThreeObject(node => {
const sprite = new SpriteText(node.id);
sprite.material.depthWrite = false; // make spr...
sprite.color = node.color;
// // 特定のノード名の色を変更
// if (node.id === '農林漁業') {
// sprite.color = 'red'; // 特定ノードのテ...
// } else {
// sprite.color = node.color; // 他のノード...
// }
sprite.textHeight = 7.5;
return sprite;
})
.linkThreeObject(link => {
// extend link with text sprite
const sprite = new SpriteText(link.value.toFixe...
sprite.color = 'blue';
sprite.textHeight = 4.0;
return sprite;
})
.linkPositionUpdate((sprite, { start, end }) => {
const middlePos = Object.assign(...['x', 'y', '...
[c]: start[c] + (end[c] - start[c]) / 2 // ca...
})));
// Position sprite
Object.assign(sprite.position, middlePos);
})
.onNodeClick(node => {
// ノードクリック時に入出力リンクを表示
const outgoingLinks = Graph.graphData().links.f...
const incomingLinks = Graph.graphData().links.f...
// 左上に情報を表示
const displayArea = document.getElementById("in...
displayArea.innerHTML = `<h3>ノード: ${node.id}...
// 出ているリンク
//displayArea.innerHTML += `<h4>Outgoing Links<...
displayArea.innerHTML += `<h4>販売先</h4>`;
outgoingLinks.forEach(link => {
displayArea.innerHTML += `<p>${link.target....
});
// 向かってくるリンク
//displayArea.innerHTML += `<h4>Incoming Links<...
displayArea.innerHTML += `<h4>購入先</h4>`;
incomingLinks.forEach(link => {
displayArea.innerHTML += `<p>${link.source....
});
})
.onNodeHover(node => {
// ノードにホバーした時の処理
hoverNode = node ? node.id : null;
updateHoverText(); // テキストを更新する関数を...
})
.linkOpacity(0.25)
.linkDirectionalArrowLength(3)
.linkDirectionalArrowRelPos(1)
.linkCurvature(0.01)
//.linkDirectionalParticleWidth(2)
//.linkDirectionalParticles("value")
//.linkDirectionalParticleSpeed(d => d.value * 0.01)
.linkThreeObjectExtend(true)
.linkColor(() => 'red') // リンクの色を黒に設定
.linkWidth(1)
.backgroundColor("#f8f8f8");
// ノード間の力学的レイアウトを調整
Graph
.d3Force("link").distance(300) // リンクの長さを100...
.d3Force("charge").strength(300); // ノード間の反発...
function updateHoverText() {
// ホバー時のノードのテキストサイズを変更
Graph.nodeThreeObject(node => {
const sprite = new SpriteText(node.id);
sprite.material.depthWrite = false;
sprite.color = node.color;
sprite.textHeight = hoverNode === node.id ? 15 ...
return sprite;
});
}
-ここで産業部門間の関係を記述したjsonファイルを指定してい...
.jsonUrl('http://127.0.0.1:5000/static/json/output_toda_...
-実際に3Dグラフの描画の処理を行っている.~
ノードの色の変更の処理もここで行う.~
.nodeThreeObject
-初期設定だとグラフの回転軸が中央で固定になってしまうため...
.onNodeClick
-矢印の設定もろもろ
.linkOpacity(0.25)
.linkDirectionalArrowLength(3)
.linkDirectionalArrowRelPos(1)
.linkCurvature(0.01)
.linkDirectionalParticleWidth(2)
.linkDirectionalParticles("value")
.linkDirectionalParticleSpeed(d => d.value * 0.01)
.linkThreeObjectExtend(true)
.linkColor(() => '#708090')
.linkWidth(1)
--linkDirectionalParticlesはノードの矢印にアニメーション...
-初期設定では背景の色が黒色だが見にくいため白色に変更して...
.backgroundColor("#f8f8f8")
~
-app_0114.py
~
app_0114.pyを実行し、下の図のようなコマンドプロンプト内に...
#ref(実行.PNG,,40%)~
実際の出力結果
#ref(3Dgraph.png,,720x400)~
*データ収集 [#q47f7fcb]
**産業連関表の収集 [#u7cb95fe]
産業連関表は以下の総務省のリンク先からダウンロードする
~
https://www.soumu.go.jp/toukei_toukatsu/data/io/2020/io20...
#ref(総務省.png,,総務省 産業連関表,,720x400)
~
**スクレイピングによるデータ収集 [#ocdbc129]
-7to12_JPX401.ipynb
~
各企業のティッカーシンボル(株式会社で取引される企業を識...
#ここからスタート
#日本経済新聞のページからティッカーのみを取得する.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditi...
from webdriver_manager.chrome import ChromeDriverManager
from bs4 import BeautifulSoup
import time
# Chromeドライバーのセットアップ
service = Service("C:/Users/ta_na/OneDrive/デスクトップ...
driver = webdriver.Chrome(service=service)
# URLを指定
url = "https://www.nikkei.com/markets/kabu/nidxprice/?S...
driver.get(url)
# ページが完全に読み込まれるのを待つ
time.sleep(3)
# 繰り返し回数を指定
repeat_count = 10 # 例として3回繰り返す
# ティッカー情報を格納するリスト
tickers = []
# 繰り返し処理
for i in range(repeat_count):
print(f"Page {i+1} のティッカーを取得中...")
# BeautifulSoupを使ってページのHTMLを解析
soup = BeautifulSoup(driver.page_source, 'html.pars...
# ティッカー情報を格納
for row in soup.find_all('tr'): # テーブル行を取得
columns = row.find_all('td') # 行内の列を取得
if len(columns) > 1: # 必要な列が存在する場合...
ticker = columns[0].text.strip() # ティッ...
tickers.append(ticker)
# 次のページに移動するためのクリックアクション
try:
# XPathを使って次ページボタンをクリック
next_button = driver.find_element(By.XPATH, "//...
next_button.click() # クリックアクション
print(f"ページ {i+1} の次のページへ移動")
except Exception as e:
print(f"クリックアクションでエラーが発生しまし...
break # 次のページに移動できない場合、ループを...
# 次のページの読み込みを待機
time.sleep(3)
# 結果を出力
print("取得したティッカー一覧:")
print(tickers)
# 必要に応じてファイルに保存
with open("nikkei500_tickers_all.txt", "w") as file:
for ticker in tickers:
file.write(f"{ticker}\n")
# ブラウザを閉じる
driver.quit()
~
Pythonのライブラリであるyfinanceを用いてデータの収集を行う
import yfinance as yf
import pandas as pd
import os
output_dir = 'C:/Users/ta_na/OneDrive/デスクトップ/kabu...
# 業種ごとのデータを格納する辞書
industry_stock_data = {}
industry_averages = {}
# 1業種ずつ処理
for col, tickers in df_t1.items(): # df_tickers1 は辞...
tickers = [ticker for ticker in tickers if ticker i...
ticker_close_prices = [] # その業種のティッカーに...
for ticker in tickers:
if isinstance(ticker, str): # tickerが文字列で...
ticker_symbol = ticker + ".T" # ティッカー...
print(f"取得するティッカー: {ticker_symbol}")
try:
# yfinanceを使って指定期間の日足データ...
data = {yf.download}(ticker_symbol, int...
※''&color(red){yfinanceのバージョンを0.2.52};''に必ずする...
# データが取得できた場合、Closeの値だけ...
if not data.empty:
ticker_close_prices.append(data['Cl...
print(f"{ticker_symbol} の日足株価...
else:
print(f"{ticker_symbol} のデータが...
except Exception as e:
print(f"{ticker_symbol} の取得中にエラ...
else:
print(f"無効なティッカー: {ticker}(スキッ...
※「データが見つかりませんでした」と出るが問題ない
# データを統合して業種ごとのデータフレームを作成
if ticker_close_prices:
industry_df = pd.concat(ticker_close_prices, ax...
# 列数とティッカー数が一致しない場合、自動調整
if len(industry_df.columns) != len(tickers):
print(f"警告: 列数の不一致。業種: {col} の...
# 一致しない場合、列数に合わせてティッカー...
tickers = tickers[:len(industry_df.columns)]
# 列名にティッカー番号を設定
industry_df.columns = tickers
industry_df['Date'] = industry_df.index # 日付...
industry_df.set_index('Date', inplace=True) # ...
# NaNを削除(各ティッカーに対してNaNがある場合)
industry_df = industry_df.dropna(axis=1, how='a...
# 業種ごとの一日ごとの平均株価を計算
industry_df['Average'] = industry_df.mean(axis=1)
# 業種ごとの平均株価データを industry_averages ...
industry_averages[col] = industry_df['Average']
# 必要に応じてCSVファイルとして保存
file_path = os.path.join(output_dir, f"{col}_st...
industry_df.to_csv(file_path)
print(f"{col} のデータを '{file_path}' に保存し...
else:
print(f"{col} 業種のデータが存在しませんでした...
# 最終的な業種別平均株価データフレームを作成
df_heikin = pd.DataFrame(industry_averages)
# 結果の確認
print("業種別平均株価データフレーム:")
print(df_heikin)
# 必要に応じてCSVとして保存
df_heikin.to_csv(os.path.join(output_dir,
"industry_average_stock_prices.csv"), encoding="utf-8-s...
import yfinance as yf
import pandas as pd
為替のデータを取得する
# USD/JPYの為替データを取得
usd_jpy = yf.download("JPY=X", start="2024-07-01", end=...
# 終値を取得
usd_jpy_close = usd_jpy.iloc[:, 3]
usd_jpy_close = usd_jpy.reset_index()
~
※Yahoo Finance(YF)のAPIやウェブサービスを使用してUSD/JP...
→時間をおいて再度リクエストを試す~
※''&color(red){yfinanceのバージョンを0.2.52};''に必ずする...
*相関 [#u016835a]
-soukan_7to12_map_yfinance.ipynb
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
sangyou_df = pd.read_csv("C:/Users/ta_na/OneDrive/デス...
daily_change_rate = pd.read_csv("C:/Users/ta_na/OneDriv...
# Date列をdatetime型に変換
daily_change_rate['Date'] = pd.to_datetime(daily_change...
sangyou_df['Date'] = pd.to_datetime(sangyou_df['Date'])
# 共通のDateを抽出
common_dates = set(daily_change_rate['Date']).interse...
# 共通のDateでフィルタリング
filtered_daily_change_rate = daily_change_rate[daily_ch...
filtered_sangyou_df = sangyou_df[sangyou_df['Date'].isi...
# 必要に応じてDateでソート
filtered_kabuka_df = filtered_daily_change_rate.sort_va...
filtered_sangyou_df = filtered_sangyou_df.sort_values(b...
# 結果を表示
print(filtered_kabuka_df)
print(filtered_sangyou_df)
filtered_kabuka_df.to_csv("csv/out_data/final_kabuka_7...
filtered_sangyou_df.to_csv("csv/out_data/final_sangyou_...
ドル円為替レートと日経 500 種平均株価それぞれの取引市場の...
どの理由により, 取得できるデータの日付がドル円為替レート...
~
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
sangyou = pd.read_csv("C:/Users/ta_na/OneDrive/デスクト...
#kabuka = pd.read_csv("C:/Users/pi/Desktop/soukan/csv/o...
kawase = pd.read_csv("C:/Users/ta_na/OneDrive/デスクト...
# Date列をインデックスに設定
sangyou.set_index('Date', inplace=True)
# すべての列名に (産業) を追加
sangyou.columns = [f"{col}(産業)" for col in sangyou.co...
sangyou
# Date列をインデックスに設定
kawase.set_index('Date', inplace=True)
kawase
#Open, High, Low, Adj Close, Volume の列を削除
kawase = kawase.drop(columns=["('High', 'JPY=X')", "('L...
※Pythonのバージョンによって、データのコラム名が異なるため...
# すべての列名に (株価) を追加
kawase.columns = [f"{col}(株価)" for col in kawase.colu...
# Close を usdjpy に変更
kawase = kawase.rename(columns={"('Close', 'JPY=X')(株...
kawase.to_csv("csv/out_data/final_kabuka_usdjpy_7to12.c...
kawase
# 横に結合(列方向)
merge_df = pd.concat([sangyou, kawase], axis=1)
merge_df
データにコラム名を付ける.
~
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib import rcParams
# 日本語フォントを指定
rcParams['font.family'] = 'Meiryo' # Windowsの場合はMe...
# 相関行列を計算(merge_dfは既に存在する前提)
corr_matrix = merge_df.corr()
# 相関行列をヒートマップとして保存
def save_corr_as_image_with_values(corr_matrix, file_n...
plt.figure(figsize=(12, 10)) # 図のサイズを大きく...
# ヒートマップを作成
sns.heatmap(corr_matrix, cmap='Reds', annot=True, f...
# ラベルのフォーマット調整
plt.xticks(rotation=90, fontsize=8) # x軸ラベル
plt.yticks(fontsize=8) # y軸ラベル
# 余白調整と保存
plt.tight_layout()
plt.savefig(file_name, dpi=300, bbox_inches='tight'...
plt.close()
# 関数を実行
save_corr_as_image_with_values(corr_matrix, 'figure/co...
print("相関係数を表示した相関行列を画像として保存しまし...
相関を求めて、ヒートマップを作成.
soukan/figureフォルダ内にcorrelation_matrix_2_2.pngが保存...
実行結果
#ref(correlation_matrix_2_2.png,,500x500)
ページ名: