自分のブログをベクトルにして分布をみた(4)
これまで以下の通りブログ記事をベクトル化して分布を見るという試みをしてみました。
自分のブログをベクトルにして分布をみた(1)Wikipedia分散表現(1)
自分のブログをベクトルにして分布をみた(2)Wikipedia分散表現(2)
自分のブログをベクトルにして分布をみた(3)TF-IDF+LSI
今回はLDAを使ってみます。
LDAを使うのですがそのトピックス数を推定してみます。
このWeb Siteを参考にしました。ありがとうございます。
TopicModelを使って,livedoorニュースコーパスを解析してみた:京都アプリエンジニアブログ
1.HDPモデルを使ったトピック数推定
import numpy as np
import pandas as pd
from gensim.models import HdpModel
from gensim.corpora import Dictionary
from gensim.corpora import MmCorpus
corpus = corpora.MmCorpus('corpus_4.mm')
dictionary = corpora.Dictionary.load_from_text('dict_4.txt')
# 推定トピック数の最大値を100に設定する
hdp = models.hdpmodel.HdpModel(corpus, id2word=dictionary, alpha=1, T=100)
show_topics = hdp.show_topics(num_topics=100, formatted=False)
topics_nos = [x[0] for x in show_topics]
weights = [sum([item[1] for item in show_topics[topicN][1]]) for topicN in topics_nos]
df = pd.DataFrame({'topic_id': topics_nos, 'weight': weights})
df.to_csv('hdp_5.tsv', sep='\t')
import matplotlib
import matplotlib.pyplot as plt
plt.figure(figsize=(20,5))
plt.bar(df["topic_id"], df["weight"], tick_label=df["topic_id"])
plt.show()
次のコードでPNGファイルを保存できます。
matplotlib.use('Agg')
plt.figure(figsize=(20,5))
plt.bar(df["topic_id"], df["weight"], tick_label=df["topic_id"])
plt.savefig('hdp_01.png')
・・・ほぼ平坦ですね。残念ながら、素材にしたブログ記事からはHDPモデルを使ったトピック数推定はうまくできませんでした。
2.LDAモデルを使ってトピック分析
トピック数を40としてLDAモデルを使って分析してみましょう。
import os
from gensim.models import LdaModel
from gensim.corpora import Dictionary
from gensim.corpora import MmCorpus
dictionary = Dictionary.load_from_text('dict_4.txt')
corpus = MmCorpus('corpus_4.mm')
#トピック数の設定
zk=40
os.makedirs('LdaModel', exist_ok=True)
#モデルの学習
model = LdaModel(corpus, \
num_topics=zk, \
id2word=dictionary, \
random_state=2020 \
)
model.save('LdaModel/lda_3_40.model')
各トピックへの所属確率を算出します。
import numpy as np
import pandas as pd
from gensim.models import LdaModel
from gensim.corpora import MmCorpus
lda_model = LdaModel.load('LdaModel/lda_3_40.model')
corpus = MmCorpus('corpus_4.mm')
#各トピックへの所属確率の算出。(文献数×トピック数)のnumpy
Prob_papers = np.array(lda_model.get_document_topics(corpus,minimum_probability=0))[:,:,1]
#DataFrameに収納
zk = lda_model.num_topics
L = [z for z in range(0,zk)]
col_name = list(map(lambda x: "Prob_" + str(x),L))
df_prob = pd.DataFrame(Prob_papers)
df_prob.columns = col_name
#所属確率最大のトピック番号も算出
df_prob["Max"] = df_prob.idxmax(axis=1)
def del_Prob(x):
return int(x.split("_")[1])
df_prob["Max"] = df_prob["Max"].apply(lambda x : del_Prob(x))
#各トピックの出現確率の算出。文献のトピックへの所属確率を全文献で足して、全トピックで1になるように正規化
df_topic = pd.DataFrame(df_prob.drop("Max",axis=1).sum()/df_prob.drop("Max",axis=1).sum().sum())
df_topic.columns = ["Prob"]
df_topic["Topic"] = [z for z in range(0,zk)]
文献のトピックへの所属確率を可視化します。
import matplotlib
import matplotlib.pyplot as plt
plt.figure(figsize=(20,5))
plt.bar(df_topic["Topic"], df_topic["Prob"], tick_label=df_topic["Topic"])
plt.show()
PNGファイルに保存するコードは次のとおり。
matplotlib.use('Agg')
plt.figure(figsize=(20,5))
plt.bar(df_topic["Topic"], df_topic["Prob"], tick_label=df_topic["Topic"])
plt.savefig('lda_topic_and_probability_01.png')
3.Word Cloud表示
import os
from gensim.models import LdaModel
import matplotlib
import matplotlib.pyplot as plt
from wordcloud import WordCloud
lda_model = LdaModel.load('LdaModel/lda_3_40.model')
FONT = 'font/IPAexfont00401/ipaexg.ttf'
plt.figure(figsize=(20, 16))
os.makedirs('topics_WordCloud_image_9', exist_ok=True)
for z in range(lda_model.num_topics):
plt.subplot(8, 5, z + 1)
x = dict(lda_model.show_topic(z, 100))
wc = WordCloud(font_path=FONT, background_color="white")
im = wc.generate_from_frequencies(x)
wc.to_file('topics_WordCloud_image_9/wordCloud_' + str(z) + '.png')
plt.imshow(im)
plt.axis("off")
plt.title("Topic #" + str(z))
4.次元圧縮して可視化
40トピックを40次元のベクトルとみてTruncated SVDを使って2次元に圧縮して可視化してみます。
import os
import numpy as np
from gensim.models import LdaModel
from gensim.corpora import Dictionary
from gensim.corpora import MmCorpus
from sklearn.decomposition import TruncatedSVD
dictionary = Dictionary.load_from_text('dict_4.txt')
corpus = MmCorpus('corpus_4.mm')
lda_model = LdaModel.load('LdaModel/lda_3_40.model')
zk = 40
v = lda_model[corpus]
vector = []
for x in v:
y = [0.] * zk
for z in x:
y[z[0]] = z[1]
vector.append(y)
vector = np.array(vector)
topicID = []
for x in vector:
topicID.append(x.argmax())
topicID = np.array(topicID)
# 次元圧縮 (グラフ表示のため2次元に次元削減)
svd = TruncatedSVD(n_components=2, n_iter=10, random_state=2020)
compressed_vector = svd.fit_transform(vector)
title = []
with open('cocolog/cocolog_corpus_3.txt') as fin:
for line in fin:
items = line.rstrip('\n').split('\t')
if len(items[1]) > 0:
title.append(items[1])
from sklearn.cluster import KMeans
n_clusters = 9
km = KMeans(n_clusters=n_clusters, init='k-means++', n_init=10, max_iter=300, tol=1e-04, random_state=2020)
y_km = km.fit_predict(compressed_vector)
import matplotlib
import matplotlib.pyplot as plt
from matplotlib import cm
# 可視化
clusterID = y_km
n_cluster = len(np.unique(clusterID))
resolution = 0.2
plt.figure()
markers = ('o')
x_min, x_max = compressed_vector[:, 0].min() - 0.01, compressed_vector[:, 0].max() + 0.01
y_min, y_max = compressed_vector[:, 1].min() - 0.01, compressed_vector[:, 1].max() + 0.01
# グリッドポイントの生成
xx, yy = np.meshgrid(np.arange(x_min, x_max, resolution),
np.arange(y_min, y_max, resolution))
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
for idx in np.unique(clusterID):
color = cm.hsv(idx / n_cluster)
plt.scatter(x=compressed_vector[clusterID == idx, 0], y=compressed_vector[clusterID == idx, 1],
alpha=0.9, color=color, marker=markers[0], label=idx)
for i, p in enumerate(zip(topicID, clusterID, title, compressed_vector)):
print(i, p[0], p[1], p[2], p[3])
plt.title('tonop\'s blog text clustering and mapping 11')
plt.xlabel('x')
plt.ylabel('y')
plt.grid()
plt.legend(loc='upper right')
plt.show()
出力結果
0 35 0 落ち着き先が決まるまで [0.00048486 0.00074655]
1 23 0 聖火リレーを見に行って来ました [0.00302027 0.00296796]
2 2 5 デジタルカメラ購入 [0.06295664 0.03188554]
3 9 0 通勤 [ 0.02305396 -0.00097494]
4 29 0 ロンドン博物館巡り [ 0.02514394 -0.00112553]
・・・(中略)・・・
215 3 5 Shell ScriptとPOSIXコマンドで実践する簡単データ処理(その1) [0.04060926 0.03614512]
216 24 5 macOS Catalinaにアップデートしてみた結果 [0.02066268 0.04631335]
217 22 0 WSLでJupyter Labを使う&ショートカット・アイコンから実行する [0.02731678 0.02805075]
218 28 5 ScrapBook及びSave Page WEで保存したWebページをApache Solrで検索できるようにしてみた(その1) [0.07531047 0.09225206]
219 28 5 ScrapBook及びSave Page WEで保存したWebページをApache Solrで検索できるようにしてみた(その2) [0.06746864 0.08258954]
PNGファイルを保存
matplotlib.use('Agg')
for idx in np.unique(clusterID):
color = cm.hsv(idx / n_cluster)
plt.scatter(x=compressed_vector[clusterID == idx, 0], y=compressed_vector[clusterID == idx, 1],
alpha=0.9, color=color, marker=markers[0], label=idx)
plt.title('tonop\'s blog text clustering and mapping 11')
plt.xlabel('x')
plt.ylabel('y')
plt.grid()
plt.legend(loc='upper right')
plt.show()
plt.savefig('text_clustering_and_mapping_11.png')
多くの記事がクラスタ0に含まれていて、あまり分離度が良くない感じです。外れ値は、例えばクラスタ1には「WSL及びUbuntuのインストール手順を再整理しておく(2018年版)」が入っていますし、クラスタ2には「Hadrian's Wall」が入っていたりします。うーん、解釈が難しすぎます。この手法は各トピックの重要単語からどんな話題が含まれているかを推定する程度の使い方がいいのかも。
5.重要単語
トピックごとの重要単語は次のとおりです。
lda_model.print_topics(num_topics=40,num_words=10)
[(0, '0.017*"人" + 0.009*"家" + 0.007*"年" + 0.007*"G" + 0.006*"使い" + 0.005*"SIM" + 0.005*"大家" + 0.005*"機能" + 0.005*"もの" + 0.005*"選択"'),
(1, '0.022*"Windows" + 0.013*"記事" + 0.011*"起動" + 0.010*"Instapaper" + 0.010*"Ubuntu" + 0.008*"Mac" + 0.008*"ADM" + 0.008*"アプリ" + 0.007*"Kindle" + 0.007*"サービス"'),
(2, '0.009*"容量" + 0.008*"回線" + 0.008*"G" + 0.007*"Kindle" + 0.007*"購入" + 0.006*"記事" + 0.006*"日本" + 0.006*"分" + 0.005*"HDL" + 0.005*"的"'),
(3, '0.016*"データ" + 0.007*"処理" + 0.006*"W" + 0.006*"記事" + 0.006*"簡単" + 0.006*"入力" + 0.005*"実践" + 0.005*"Windows" + 0.005*"選択" + 0.005*"通信"'),
(4, '0.012*"G" + 0.010*"HDL" + 0.009*"netatalk" + 0.008*"support" + 0.008*"Windows" + 0.007*"Kindle" + 0.006*"usr" + 0.006*"適用" + 0.006*"local" + 0.006*"Fusion"'),
(5, '0.014*"SIM" + 0.011*"W" + 0.008*"起動" + 0.008*"機能" + 0.008*"メール" + 0.008*"IMAP" + 0.008*"Mac" + 0.006*"通信" + 0.006*"データ" + 0.006*"ZERO"'),
(6, '0.012*"Lion" + 0.008*"円" + 0.007*"フォント" + 0.007*"実行" + 0.007*"AS" + 0.007*"Mountain" + 0.007*"アップデート" + 0.006*"Mac" + 0.006*"NAS" + 0.006*"v"'),
(7, '0.017*"Windows" + 0.012*"Mac" + 0.011*"フォント" + 0.008*"ポイント" + 0.008*"通信" + 0.006*"もの" + 0.006*"mineo" + 0.006*"X" + 0.006*"芯" + 0.005*"選択"'),
(8, '0.010*"Windows" + 0.008*"記事" + 0.007*"保存" + 0.007*"作成" + 0.006*"フォント" + 0.006*"Instapaper" + 0.005*"登録" + 0.005*"容量" + 0.005*"パケット" + 0.005*"Mac"'),
(9, '0.017*"アップデート" + 0.013*"Windows" + 0.011*"接続" + 0.010*"Bluetooth" + 0.009*"Mac" + 0.008*"起動" + 0.008*"テザリング" + 0.007*"アクセス" + 0.006*"iTunes" + 0.006*"NAS"'),
(10, '0.024*"iTunes" + 0.013*"フォルダ" + 0.011*"NAS" + 0.009*"追記" + 0.009*"購入" + 0.008*"Kindle" + 0.008*"G" + 0.007*"リフィル" + 0.006*"HDL" + 0.006*"マウント"'),
(11, '0.029*"netatalk" + 0.021*"HDL" + 0.020*"G" + 0.017*"バックアップ" + 0.012*"作成" + 0.012*"Time" + 0.011*"ディスク" + 0.010*"容量" + 0.010*"Mac" + 0.009*"Machine"'),
(12, '0.017*"Windows" + 0.014*"フォント" + 0.013*"ポイント" + 0.012*"テザリング" + 0.011*"Bluetooth" + 0.007*"接続" + 0.007*"launchpad" + 0.006*"ディスク" + 0.006*"netatalk" + 0.006*"G"'),
(13, '0.013*"日本語" + 0.012*"Windows" + 0.012*"HDL" + 0.010*"netatalk" + 0.009*"G" + 0.009*"ssh" + 0.009*"X" + 0.008*"ログイン" + 0.008*"入力" + 0.007*"試し"'),
(14, '0.022*"Ubuntu" + 0.021*"Windows" + 0.010*"WSL" + 0.009*"Bash" + 0.007*"実行" + 0.007*"起動" + 0.006*"用" + 0.006*"作成" + 0.006*"日" + 0.006*"試し"'),
(15, '0.018*"Kindle" + 0.010*"日本語" + 0.008*"購入" + 0.007*"適用" + 0.007*"Amazon" + 0.006*"R" + 0.006*"Let" + 0.006*"ディスク" + 0.006*"Mac" + 0.005*"行っ"'),
(16, '0.035*"Windows" + 0.017*"Ubuntu" + 0.015*"X" + 0.015*"Bash" + 0.012*"追記" + 0.010*"日本語" + 0.009*"入力" + 0.008*"接続" + 0.008*"Window" + 0.007*"手順"'),
(17, '0.010*"フォント" + 0.009*"製品" + 0.007*"Mac" + 0.006*"通信" + 0.006*"後" + 0.005*"機" + 0.005*"街" + 0.005*"NAS" + 0.004*"フォルダ" + 0.004*"日本語"'),
(18, '0.011*"Mac" + 0.009*"対応" + 0.009*"行" + 0.007*"指定" + 0.007*"作成" + 0.007*"円" + 0.006*"フォント" + 0.006*"ポイント" + 0.006*"サービス" + 0.006*"データ"'),
(19, '0.016*"Mac" + 0.013*"Windows" + 0.012*"起動" + 0.009*"OS" + 0.007*"導入" + 0.006*"機種" + 0.006*"接続" + 0.006*"HDD" + 0.006*"G" + 0.006*"X"'),
(20, '0.010*"メモリ" + 0.009*"メール" + 0.009*"カレッジ" + 0.008*"機能" + 0.007*"Mac" + 0.007*"通知" + 0.006*"分" + 0.006*"Windows" + 0.006*"ない" + 0.006*"予約"'),
(21, '0.010*"G" + 0.010*"Mac" + 0.010*"HDL" + 0.009*"OS" + 0.008*"X" + 0.008*"追記" + 0.007*"PC" + 0.006*"Kindle" + 0.006*"ダウンロード" + 0.006*"Google"'),
(22, '0.021*"Windows" + 0.021*"フォント" + 0.010*"OS" + 0.010*"Jupyter" + 0.009*"Mac" + 0.009*"ポイント" + 0.009*"VMware" + 0.007*"機能" + 0.007*"作成" + 0.007*"ttf"'),
(23, '0.012*"Kindle" + 0.009*"版" + 0.008*"Mac" + 0.006*"追記" + 0.006*"人" + 0.005*"行っ" + 0.005*"Send" + 0.005*"分" + 0.005*"設置" + 0.005*"Windows"'),
(24, '0.015*"iTunes" + 0.009*"サービス" + 0.009*"Kindle" + 0.009*"mineo" + 0.008*"Bluetooth" + 0.008*"NAS" + 0.008*"分" + 0.007*"通話" + 0.007*"かけ" + 0.007*"れる"'),
(25, '0.013*"ボタン" + 0.011*"選択" + 0.010*"電源" + 0.008*"フォルダ" + 0.007*"Windows" + 0.006*"化" + 0.006*"netatalk" + 0.006*"復活" + 0.006*"画面" + 0.006*"実行"'),
(26, '0.016*"メモリ" + 0.009*"Windows" + 0.009*"記事" + 0.008*"OS" + 0.008*"SD" + 0.007*"Player" + 0.006*"Ubuntu" + 0.006*"mineo" + 0.006*"ダウンロード" + 0.006*"Pi"'),
(27, '0.008*"R" + 0.008*"mineo" + 0.007*"SSD" + 0.007*"SIM" + 0.006*"移行" + 0.006*"Windows" + 0.006*"Feedly" + 0.006*"円" + 0.005*"PC" + 0.005*"電話"'),
(28, '0.026*"Apple" + 0.023*"TV" + 0.010*"検索" + 0.009*"iPad" + 0.009*"Web" + 0.008*"iOS" + 0.008*"Hulu" + 0.007*"タイトル" + 0.007*"Apache" + 0.007*"入力"'),
(29, '0.054*"Windows" + 0.022*"Ubuntu" + 0.013*"Bash" + 0.010*"アップ" + 0.009*"グレード" + 0.008*"動作" + 0.007*"Pro" + 0.007*"Insider" + 0.006*"Build" + 0.006*"人"'),
(30, '0.030*"円" + 0.017*"support" + 0.015*"通話" + 0.014*"料" + 0.014*"サービス" + 0.012*"local" + 0.011*"usr" + 0.010*"netatalk" + 0.010*"分" + 0.010*"mineo"'),
(31, '0.043*"フォント" + 0.025*"ttf" + 0.016*"Italic" + 0.013*"軸" + 0.012*"Helvetica" + 0.010*"Bold" + 0.010*"Mac" + 0.008*"使う" + 0.008*"芯" + 0.008*"Kindle"'),
(32, '0.026*"フォント" + 0.021*"Windows" + 0.013*"Mac" + 0.011*"Ricty" + 0.010*"ポイント" + 0.008*"G" + 0.008*"HDL" + 0.007*"apt" + 0.007*"用" + 0.006*"起動"'),
(33, '0.015*"Windows" + 0.010*"HDD" + 0.009*"OS" + 0.008*"Mac" + 0.007*"サービス" + 0.007*"SSD" + 0.006*"Kindle" + 0.006*"分" + 0.006*"パーティション" + 0.005*"X"'),
(34, '0.019*"netatalk" + 0.014*"G" + 0.011*"Kindle" + 0.010*"NAS" + 0.008*"HDL" + 0.007*"作成" + 0.007*"フォルダ" + 0.005*"追記" + 0.005*"出" + 0.005*"Flash"'),
(35, '0.022*"芯" + 0.011*"色" + 0.010*"替" + 0.009*"購入" + 0.008*"先" + 0.007*"国内" + 0.006*"年" + 0.006*"ノック" + 0.006*"物件" + 0.006*"軸"'),
(36, '0.010*"製品" + 0.010*"Mac" + 0.008*"G" + 0.008*"通信" + 0.006*"追記" + 0.006*"X" + 0.006*"HDL" + 0.006*"OS" + 0.006*"Yosemite" + 0.006*"購入"'),
(37, '0.016*"Mac" + 0.010*"NAS" + 0.009*"iTunes" + 0.009*"Windows" + 0.008*"mini" + 0.006*"起動" + 0.006*"SSD" + 0.006*"購入" + 0.006*"G" + 0.005*"方法"'),
(38, '0.020*"Windows" + 0.017*"サービス" + 0.015*"分" + 0.014*"mineo" + 0.011*"かけ" + 0.011*"通話" + 0.010*"放題" + 0.009*"Mac" + 0.008*"電話" + 0.007*"アプリ"'),
(39, '0.015*"通信" + 0.014*"ゴム" + 0.010*"Kindle" + 0.009*"選択" + 0.008*"足" + 0.007*"アプリ" + 0.007*"データ" + 0.006*"LTE" + 0.006*"バンド" + 0.005*"機能"')]
6.おまけ
LDAモデルのトピック数を2にして2次元化して可視化してみました。
import os
import pandas as pd
from gensim.models import LdaModel
from gensim.corpora import Dictionary
from gensim.corpora import MmCorpus
dictionary = Dictionary.load_from_text('dict_4.txt')
corpus = MmCorpus('corpus_4.mm')
#トピック数の設定
zk=2
os.makedirs('LdaModel', exist_ok=True)
#モデルの学習
model = LdaModel(corpus, \
num_topics=zk, \
id2word=dictionary, \
random_state=2020 \
)
model.save('LdaModel/lda_3_2.model')
import os
import numpy as np
from gensim.models import LdaModel
from gensim.corpora import Dictionary
from gensim.corpora import MmCorpus
dictionary = Dictionary.load_from_text('dict_4.txt')
corpus = MmCorpus('corpus_4.mm')
lda_model = LdaModel.load('LdaModel/lda_3_2.model')
v = lda_model[corpus]
vector = []
for x in v:
y = [0., 0.]
for z in x:
y[z[0]] = z[1]
vector.append(y)
vector = np.array(vector)
title = []
with open('cocolog/cocolog_corpus_3.txt') as fin:
for line in fin:
items = line.rstrip('\n').split('\t')
if len(items[1]) > 0:
title.append(items[1])
from sklearn.cluster import KMeans
n_clusters = 9
km = KMeans(n_clusters=n_clusters, init='k-means++', n_init=10, max_iter=300, tol=1e-04, random_state=2020)
y_km = km.fit_predict(vector)
import matplotlib
import matplotlib.pyplot as plt
from matplotlib import cm
# 可視化
clusterID = y_km
n_cluster = len(np.unique(clusterID))
resolution = 0.2
plt.figure()
markers = ('o')
x_min, x_max = vector[:, 0].min() - 0.01, vector[:, 0].max() + 0.01
y_min, y_max = vector[:, 1].min() - 0.01, vector[:, 1].max() + 0.01
# グリッドポイントの生成
xx, yy = np.meshgrid(np.arange(x_min, x_max, resolution),
np.arange(y_min, y_max, resolution))
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
for idx in np.unique(clusterID):
color = cm.hsv(idx / n_cluster)
plt.scatter(x=vector[clusterID == idx, 0], y=vector[clusterID == idx, 1],
alpha=0.9, color=color, marker=markers[0], label=idx)
for i, p in enumerate(zip(clusterID, title, vector)):
print(i, p[0], p[1], p[2])
plt.title('tonop\'s blog text clustering and mapping 10')
plt.xlabel('x')
plt.ylabel('y')
plt.grid()
plt.legend(loc='upper right')
plt.show()
0 0 落ち着き先が決まるまで [0.98423517 0.01576489]
1 0 聖火リレーを見に行って来ました [0.98888463 0.01111535]
2 5 デジタルカメラ購入 [0.67790121 0.32209876]
3 1 通勤 [0.04852767 0.95147234]
4 0 ロンドン博物館巡り [0.99202293 0. ]
・・・(中略)・・・
215 8 Shell ScriptとPOSIXコマンドで実践する簡単データ処理(その1) [0.0104943 0.98950565]
216 8 macOS Catalinaにアップデートしてみた結果 [0.03441308 0.9655869 ]
217 6 WSLでJupyter Labを使う&ショートカット・アイコンから実行する [0.9095127 0.09048728]
218 8 ScrapBook及びSave Page WEで保存したWebページをApache Solrで検索できるようにしてみた(その1) [0. 0.9931584]
219 8 ScrapBook及びSave Page WEで保存したWebページをApache Solrで検索できるようにしてみた(その2) [0. 0.99315149]
今回のモデルはトピックごとの出現確率の和が1になるようで、1直線のグラフになってしまいました。
| 固定リンク
「パソコン・インターネット」カテゴリの記事
- 実家のAmazon Echo Show 5に別アカウントのAmazon Alexaアプリから呼びかけするためのAlexaアプリによる設定(2025.01.02)
- Intel Mac で ELYZA-japanese-Llama-2-13b 及び phi-2 とllama.cppで戯れてみた(2024.01.14)
- 分離型キーボードで親指シフト(NICOLA配列)を試す(Majestouch Xacro M10SP JIS配列)(2024.01.06)
- Microsoft Office Word のショートカットキーの一部をEmacs風のキーバインドにしてみた(2023.12.18)
- Intel Mac上でllama.cppのサーバ機能を使って日本語LLMを使ってみる(2023.11.12)
コメント