地平線まで行ってくる。

記録あるいは忘備録。時には検討事項。

ArXivから論文を参照してLLMをColabでファインチューニングしてみる。

LLMをファインチューニングするためのデータセットをLLM準備をしたところ、結構使えそうな印象がありました。面白いので、もう少しほかのデータで試したくなりました。

 

bwgift.hatenadiary.jp

 

 

前提

LLMを使ったことによるデータセット作成では、間違いや不正確な表現・情報の類の歪は一定量あると考えられます。しかし、個人で大量のデータを準備するには敷居が高い。そこで、ある程度の間違いや不正確な表現は許すという前提で進めます。使ったLLMは上記の記事と同様で割愛します。

 

論文を入手する手段としてArXiv*1を利用します。ArXivには数々の論文がアップロードされており、分野に偏りはあるもののAPIまで用意されていて手軽に利用できます。専門分野によって投稿される雑誌も異なり、個別の購入や購読契約が必要で個人での利用は敷居が高い。研究開発業務で契約しているか、大学が出版社と契約しているような学生身分でないと、なかなか個人で多くの論文にあたることはできない分野もあります。学生になりたい・・・。

 

データセットの利用

アブストラクトをLLMで解析した結果に含まれる文章が著者らの主張と一致しない可能性は、生成AIで作成する以上避けられない。仮に論文自体のライセンスをクリアしていたとしても、著作人格権から好ましくないのは明らか。作成したデータセットは個人的な利用が無難ですね。原文確認しやすいようにデータセット自体に論文へのリファレンスも加えておきました。

 

データセットの対象

というわけで・・・。APIを使って検索し、アブストラクトをローカルLLMで解析して、研究の目的と結果と手段に分離させます。題材は「time series machine learning」で検索を行った関連性の高い1000件としました。

 

対象の論文を読み込む

ArXivのありがたいAPIを使って論文を読み込みます。

import arxiv
import pandas as pd

# Arxiv APIを使用して論文を検索します。
# 検索クエリを設定します。ここでは例として "machine learning" を使用します。
query = "time series machine learning"

# arxiv.Clientをインスタンス化します。
client = arxiv.Client()

# 検索条件を設定します。
search = arxiv.Search(
    query=query,
    max_results=1000,  # 取得する論文の最大件数を指定します。
    sort_by=arxiv.SortCriterion.Relevance #関連度順でダウンロード
    # sort_by=arxiv.SortCriterion.SubmittedDate #日付でダウンロード
)

# 検索を実行し、結果を取得します。
results = []
for result in client.results(search): # client.results()を使用
    results.append({
        "title": result.title,
        "abstract": result.summary,
        #Bibtexを生成するために必要な情報を追加
        'authors': result.authors,
        'published': result.published,
        'journal_ref': result.journal_ref,
        'entry_id': result.entry_id
    })


# BibTeX形式の引用を生成する関数
def generate_bibtex(result):
    authors = " and ".join([author.name for author in result['authors']])
    title = result['title']
    year = result['published'].year
    if result['journal_ref'] is not None:
        journal = result['journal_ref']
    else:
        journal = result['entry_id']
    bibtex = f"""@article{{{result['entry_id']}}},
    author = {{{authors}}},
    title = {{{title}}},
    journal = {{{journal}}},
    year = {{{year}}}
}}"""
    return bibtex


# BibTeX形式の引用を結果に追加します。
for result in results:
    result["bibtex"] = generate_bibtex(result)

# データフレームに変換します。
df = pd.DataFrame(results)

# title, abstract, bibtexだけのDataFrameを作成します。
df = df"title", "abstract", "bibtex"

# CSVファイルとして保存します。
df.to_csv("arxiv_papers.csv", index=False)

 

例として、以下のようなAbstractを解析します。

abstract:This paper presents a time series forecasting framework which combines
standard forecasting methods and a machine learning model. The inputs to the
machine learning model are not lagged values or regular time series features,
but instead forecasts produced by standard methods. The machine learning model
can be either a convolutional neural network model or a recurrent neural
network model. The intuition behind this approach is that forecasts of a time
series are themselves good features characterizing the series, especially when
the modelling purpose is forecasting. It can also be viewed as a weighted
ensemble method. Tested on the M4 competition dataset, this approach
outperforms all submissions for quarterly series, and is more accurate than all
but the winning algorithm for monthly series.

Ref:  [2001.04601] For2For: Learning to forecast from forecasts*2

 

これをローカルLLMを使ってJSONに仕立てます。日本語に訳してさらに内容を解析させています。そこそこ出来ているので、実験としては十分だと判断しました。

{'question': '従来の予測手法だけでは、時系列データの複雑なパターンを十分に捉えきれない場合がある。そこで、標準的な予測手法で得られた予測値自体を新たな特徴量として活用し、より精度の高い予測モデルを構築できないか?',
 'method': '標準的な時系列予測手法を用いて予測値を生成する。そして、これらの予測値を機械学習モデル(畳み込みニューラルネットワークまたは再帰ニューラルネットワーク)の入力として用いる。',
 'reason': '予測値は、時系列データの特徴を反映した重要な情報を含んでいる。特に、予測の目的である将来の値を予測する場合、過去の予測値が将来の値を理解する上で有効な特徴量となるためである。'}

questionは研究の狙い、methodは、研究を達成するための手法、reasonは手法を選択したのかの理由。それぞれをLLMで分析させて分割させました。

 

エラー処理とJSON周りの後処理を試行錯誤し、JSON形式に整えるルーチンを加え、最終的に4/1000件のパースエラーのレベルとなりました。結果として、1000件の論文から996件のデータセットになりました。

 

学習

LoRAで1000Stepの学習を実施しました。以下のコードを流用しています。Colab T4環境で30分程度です。プロンプトが直接回答の質にも影響しました。

bwgift.hatenadiary.jp

 

 

返答例

売り上げの時系列予測をするためにはどんな手法をとるのがベストか?

1. 時系列データの前処理を行い、特にトレンドや季節性を抑える。
2. 多様な時系列データから学習するモデルを採用する。
3. 複数のモデルを組み合わせることでより精度の高い予測を実現する。
4. 予測結果を解釈し、不確実性を考慮した上で提供する。
5. 顧客の行動パターンを理解し、予測を改善する。
6. 顧客の年齢、性別、地理的位置情報などの追加的な特徴量も考慮する。
7. 顧客の過去の購入履歴や関連する商品との購買関係を分析する

時系列データを勉強した答えのように思えます。優等生っぽい答えですね。

 

株価を正確に予測するために必要な解析は?
1. 時系列データの整理と特徴量抽出
2. 決定木回帰やLASSO回帰などの機械学習アルゴリズムを用いた予測モデル構築
3. クロスバリデーションによるモデル性能評価
4. 推論のための予測手法の選択


具体的には、株価データから重要な特徴量を抽出し、それらを基に機械学習アルゴリズムを用いて予測モデルを構築する。そして、そのモデルの精度を評価し、将来的な株価予測に活用できる環境を構築する。

なかなか、それらしい答えです。もっと具体性が欲しいところですが、データセットの中身を考えると贅沢かも・・・。

 

時系列予測、タイムシリーズのデータをランダムフォレストを用いた時系列データのモデリングにおいて分類体系について考察してください。
時系列予測とタイムシリーズデータのランダムフォレストモデリングにおける分類体系を提案します。具体的には、ランダムフォレストを用いた時系列予測とタイムシリーズデータのモデリングを体系的に整理し、それぞれの特性や適用範囲を明確化します。また、これらの分類体系を支援する理由や将来的な展望についても議論します。

この分類体系は、時系列予測とタイムシリーズデータモデリングにおけるランダムフォレストの適用範囲を明確化し、研究者や開発者が適切なモデルを選択するための指針を提供することを目的としています。

時系列予測においても、様々な手法を選択して、目的・タスクに沿ったモデリングが重要です。分類体系について謎な回答になってしましましたが、英語を日本語に翻訳したデータセットということもあり、わかりにくい答えになっている気がします。

 

タイムシリーズのデータの特徴と分析手法を考えています。トレンドの解析にはどのような手法を用いますか?
タイムシリーズのトレンド解析には、以下の手法が用いられます。

* 平均移動平均MMA)を用いる
* 自己相関関数(ACF)を用いる
* ラジアル自己回帰(AR)モデルを用いる
* espertiモデルを用いる

これらの手法はそれぞれ異なる特徴を持ち、特定のデータセットに最適な手法を選択することで、より精度の高いトレンド解析が可能になります。

espertiモデルは、正体不明ですが、それらしい答えにはなっています。

 

まとめ

ローカルLLMを使った論文のアブストラクト解析を用い、データセットを作成し、LoRAによるLLMのファインチューニングを試みました。味見程度の実験でしたが、データセットの内容が入り込んだ回答が得られました。今回はデータセットも少なく、ファインチューニングのStep数も決して多くもありません。しかしながら、単純に学習を多く行えばよいわけではないでしょう。データセットに過剰に適合させずにバランスも重要だろうと予測できます。

 

よりデータセットの精度を上げる場合は、もっと強力なLLMを使ったり、Reflexion技法を入れ込む、とリソース次第な側面はあります。いつか、がっつりやってみたい・・・。


# 誤字訂正

*1:https://arxiv.org/

*2:@misc{zhao2020for2forlearningforecastforecasts,
      title={For2For: Learning to forecast from forecasts}, 
      author={Shi Zhao and Ying Feng},
      year={2020},
      eprint={2001.04601},
      archivePrefix={arXiv},
      primaryClass={stat.ML},
      url={https://arxiv.org/abs/2001.04601}, 
}