こんにちはニコ

 

kaggleのOptiver - Trading at the Closeで銅メダルゲット!!

これで5個目の銅メダルですチョキ

 

 

今回は、完全に宝くじに当たった銅メダルです。

たまには、このようなこともあるのだと思いますニコニコ

 

銀メダル以上のハードルは高く、

まだまだ、Kaggle Masterへの道のりは遠いです。

 

明日は、第3回教育データ分析コンテストの表彰式があり、

京都大学で予測解法のプレゼンをします。

 

他の入賞者の解法が聞けるのが良いですよねニコニコ

 

このコンテスト入賞が目的で機械学習の勉強を始めたようなものなので、

目的達成感があり、他のデータ分析コンペへのモチベーションが落ちつつあります。

 

一旦、仕切り直して、次の目標を設定しようと思います。

あくまで、教育関連の個別最適化関連で目標で考えてみようと思いますニコニコ

 

その他、データ分析コンペの状況です。

 

〇Kaggle 

   Home Credit   0.562 388位/946

 Enefit - Predict Energy Behavior of Prosumers 53.6380  682位/2731

 

 

こんにちはニコ

 

教育データ分析コンテストでの入賞の連絡が来ました!!

 

このコンテストは教育分野におけるデータ分析技術を競うもので、

私がこれまでに参加したコンペ中で最も重要なものでした。

 

最終順位(1位~3位)の発表は、

3月の学会で開催される表彰式で発表されるとのこと。

 

表彰式での分析解法のプレゼンがちょっと重たいですが、

このコンペ、本業の教育関連で、

私にとっては本命のコンペだったので、

入賞は本当に嬉しいですニコニコ

 

過去3、4年間に渡り機械学習を学び、

実務での分析経験を積み重ね、

様々なコンペに挑戦してきた努力の集大成ともいえるものですグッド!

 

この結果は、

今後の教育関連のデータ分析において、

新たな高みを目指す強いモチベーションとなりますニコニコ

 

今後も、スキルの維持と向上のため、

引き続き様々なコンペに参加はしますが、

これと言って、本気で取り組んでみたいことは、 

今のところなくなりましたので、

 

次のステップとしては、

これまでの実績とスキルを活かし、

実務で実践できる場所を見つけにいく、

または、開拓することですかね。

 

年齢に関係なく常に新たな挑戦を求め、

成長し続けることの大切さを、改めて感じていますグッド!

 

 

その他、データ分析コンペの状況です。金融データコンペは、何をやってもスコアUPせず、

手詰まり状態です。

 

〇Kaggle 

   Home Credit   0.574 44位/671

 Enefit - Predict Energy Behavior of Prosumers 63.72   569位/2731

 

〇Signate

  金融データ活用チャレンジ  0.6867922  150位/920チーム

 

こんばんはニコ

 

Kaggle LLMコンペ 銅メダルが確定しましたグッド!

しかし、銅メダルをいくら取っても称号UPはありません。

まずは、銀メダルを取得しなければ!

 

 

ランクも20位上昇して480位となりました。

 

 

次は、第三回教育データ分析コンテストです。まだ暫定3位にはいます。

 

 

残り、3日です。最終投稿ファイルをどれにしようか迷います。

この選択で、入賞できるかどうかが決まるかもしれません。

投稿後は、祈るだけです。

まあ、コンペはいつもそうですけどねニコニコ

 

その他、コンペの進捗状況:教育データ分析コンペが終わったらSignateに注力しよう!

 

〇Kaggle 

   LLM - Detect AI Generated Text  0.901892   342位/4358 銅メダル

 Enefit - Predict Energy Behavior of Prosumers 63.72   450位/2608

 SenNet + HOA                        0.86                        86位/993

 Signate 金融データ活用チャレンジ  0.6564  229位/555

 

こんばんはニコ

 

Signateの第2回 金融データ活用チャレンジ、今日も少し進捗はありました。

殆ど、特徴量エンジニアリングはせず、パラメータの調整しかしていません。

来週末は、色々と特徴量を考えてみようと思います。

スコア:0.4934193 → 0.4983560

順位:60位(何もしないとすぐに下がります)

 

 

このコンペでは、企業向けローンの返済可否を予測します。

テーブルデータなので比較的参加ハードルは低いため、

結構参加人数が多くなると予想されます。

 

まだ、3週間以上あるので、まだまだ、これからです。

100位以内目指して頑張ります!

 

第三回教育データ分析コンテストの方、まだ、入賞圏内の3位にはおりますが、

こちらもどうなるか分かりません。あと10日なので、

もうそろそろ最終投稿モデルを決める段階に来ています。

 

 

その他、コンペの進捗状況:

 

〇Kaggle 

   LLM - Detect AI Generated Text  0.963 458位/4414

 Enefit - Predict Energy Behavior of Prosumers 63.72   263位/2416

 

 

こんにちはニコ

 

KaggleのLinking Writing Processes to Writing Qualityコンペ、順位が確定し銅メダルゲット!

ランキングも、切りのいい数字の500位となりました。

世界で22万人のkaggerの中で500位とは、全体の0.23%の位置ですのでちょっと信じられませんが、一応そのようになっていますニコニコ 実際の実力は、22万人中2万位くらいではないかな~。10%以内には入っていたいグッド!

現在、参加中の第三回教育データ分析コンテスト、辛うじて1位キープ!!

しかし、もうこの辺が限界のような気もします。

 

 

Linking Writing Processes to Writing Qualityコンペの上位解法を参考に、さらにスコアアップできましたが、さすがにやれることもなくなってきました。

 

しかし、教育データといっても、eラーニングの操作ログ(OPEN,NEXT,ADD BOOKMARK, JUMP, CLOSEなどのイベントデータ)とせいぜい、コンテンツのアクセス頻度程度のデータで、100点満点のテストを誤差10点程度で予測できていること自体が凄いと思いますニコニコ

 

この予測モデルを、ぜひ、学習のパーソナライズ化の実装に応用してみたいと思いますグッド!

 

その他、コンペの進捗状況:

 

〇教育データ分析コンテスト → 今のところトップです!

 10.56984749551974 1位/15

 

〇Kaggle 

 LLM - Detect AI Generated Text 0.961    506位/4166

  Enefit - Predict Energy Behavior of Prosumers    65.37     156位/2092

  Prediction of spam  0.85841     8位/39

 

 

こんにちはニコ

 

現在、参加中の第三回教育データ分析コンテストでは、暫定トップ!!

このまま逃げ切りたい。

 

また、Kaggleでも久々に銅メダルをゲット。Kaggleでは、ようやく3個目です。

次は、銀メダルを狙いますニコニコ

 

その他、コンペの進捗状況:

 

〇教育データ分析コンテスト → 今のところトップです!

 10.56984749551974 1位/15

 

〇Kaggle 

   Linking Writing Processes to Writing Quality 0.568 158位/1937 銅メダル獲得

 LLM - Detect AI Generated Text 0.961    437位/4006

  Enefit - Predict Energy Behavior of Prosumers    69.27     854位/1930

  Prediction of spam  0.85841     8位/39

 

 

こんばんはニコ

 

前回の記事では、推奨テストの正解率を予測するプログラムの実装について触れました。今回は、機械学習の予測モデルを使用せず、より直感的で汎用的な方法で最適な教材の推奨方法について考察します。

 

eコマースの協調フィルタリング同様、学習の推奨でも習熟度が似ている受講者の学習パターンは類似するとの前提の下、以下のキーコンセプトをベースにアルゴリズムを構築します。

 

1 シンプル:直感的でわかりやすい

2 高速:予測モデルを使用しないため、計算が迅速

3 適度な精度:実際の正解率を用いるため、予測の不確実性が排除される

 

具体的なアルゴリズムのステップは以下の通りです:

  1. ユーザの学習活動の取得

    • レッスンごとの解説教材の視聴時間・回数、テストの実施回数
    • 各ユーザのテストの正解率
    • 各レッスンのユーザの平均正解率
  2. ユーザ間の学習活動の類似度の算出

  3. 最も類似度の高いユーザの抽出とそのテストの正解率の計算

  4. 既に受験済みのテストの除外

  5. 正解率が0.5~0.8のテストの推奨

  6. 該当するテストがない場合、未受験のテストの中でIDが最小のものを推奨

 

アルゴリズムのメリット:

  1. 豊富な特徴量:ユーザの活動やテストのパフォーマンスを示す特徴量を組み合わせて、ユーザ間の類似性を高精度に計算。
  2. 閾値に基づく推奨:テストの正解率の閾値を設定することで、適切な難易度のテストを推奨。
  3. フォールバックメカニズム:閾値に合致するテストがない場合のための、シンプルで直感的な推奨方法を採用。

全体として、このアルゴリズムは、とてもシンプルで、ユーザの過去の活動と他のユーザとの類似性を基に、高速に適切な次のテストを効果的に推奨することができると考えられます。

 

以下は、コードサンプルです:

欠損値の補完や、外れ値の除去などのデータ加工を実施します。

特徴量を作成し、ユーザ間の類似度を計算します。

video_lesson_counts = data_dropped.groupby(['user_id', 'lesson'])['video_id'].count().unstack().fillna(0)
test_lesson_counts = data_dropped.groupby(['user_id', 'lesson'])['test_id'].count().unstack().fillna(0)
# Create user-test matrix from the full dataset
user_test_matrix = data_dropped.pivot_table(index='user_id', columns='test_id', values='correct', aggfunc='mean').fillna(0)
user_lesson_correct_matrix = data_dropped.pivot_table(index='user_id', columns='lesson', values='correct', aggfunc='mean').fillna(0)
expanded_user_matrix = pd.concat([user_test_matrix,user_lesson_correct_matrix, video_lesson_counts, test_lesson_counts], axis=1).fillna(0)
#  ユーザー間の類似度を計算
user_similarity_expanded = cosine_similarity(expanded_user_matrix)
user_similarity_df_expanded = pd.DataFrame(user_similarity_expanded, index=expanded_user_matrix.index, columns=expanded_user_matrix.index)
 

def recommend_test_for_user_v6(user_id, data, expanded_user_matrix, user_similarity_df):
   
    # ターゲットユーザの最後のtest_idを取得
    last_test_id = data[data['user_id'] == user_id]['test_id'].max()
    
    # ユーザを類似度でソート
    similar_users = user_similarity_df[user_id].sort_values(ascending=False).drop(user_id).index.tolist()
    
    # 推奨テストと正解率を初期化
    recommended_test_id, correct_rate = None, None
    
    #高類似度のユーザの正解率の高いテストを抽出し閾値を適用し推奨テストを決定
    for sim_user in similar_users:
        # 高類似度ユーザのテストを正解率でランキング
        test_ranking = expanded_user_matrix.loc[sim_user].sort_values(ascending=False)
        
        # 既に実施済テストを除外
        user_tests = data[data['user_id'] == user_id]['test_id'].unique()
        recommended_tests = test_ranking[~test_ranking.index.isin(user_tests)]
        
        # 推奨すべきテストを選択
        for test_id in recommended_tests.index:
            if isinstance(test_id, int) and test_id <= last_test_id:
                continue
            test_data = data[data['test_id'] == test_id].iloc[0]
            correct_rate_temp = test_data['correct']
            
            if 0.5 <= correct_rate_temp <= 0.8:
                recommended_test_id = test_id
                correct_rate = correct_rate_temp
                break
        
        if recommended_test_id:
            break
    
    # 推奨すべきテストを選択されなかった場合の処理
    if not recommended_test_id:
        available_tests = data[~data['test_id'].isin(user_tests)]['test_id'].unique()
        if available_tests.size > 0:
            recommended_test_id = min(available_tests)
            correct_rate = data[data['test_id'] == recommended_test_id]['correct'].mean()
    
    return recommended_test_id, correct_rate

 

全体として、このアルゴリズムはシンプルかつ効果的に、ユーザの学習活動や他のユーザとの類似性に基づいて、適切な次のテストを推奨することができます。

 

次回は、学習のパーソナライズ化の現状やトレンド、そしてAIを活用した学習における倫理的な課題について調査、考察してみようと思います。

こんにちはニコ

 

前回は、コンテンツの類似度を基にした簡易的な推奨アルゴリズムの実装について検討しました。今回は、一歩進めて、推奨されたコンテンツに関連する確認テストの正解率を予測する方法を考えてみます。

 

次に学習すべき教材やその確認テストを選ぶ際、学習者の習熟度と教材の内容の類似度を計算することで、最も適切な教材を推奨するアルゴリズムを前回は実装しました。しかしながら、類似度が高いからといって、それが最も適切な教材であるとは限りません。あまりにも簡単すぎる、あるいは難しすぎる教材は、学習者にとって最適とは言えないでしょう。

 

例えば、推奨されたテストの正解率が極端に低い場合、それは学習者にとって難易度が高すぎる可能性があります。逆に、正解率が100%という結果になれば、それは易しすぎるということになります。

 

そこで、この正解率を計算し、適切な正解率(例: 60%)の範囲でコンテンツを推奨するようなアプローチを取ることが考えられます。

 

前回のコードで、user_2の受講者へvideo_id 102を推奨するという結果となりました。

この結果を受けて、その教材に関連するテストを受験してどの程度の正解率となるのかを計算するコードを考えてみました。

 

ダミーデータは以下のように、10章から構成される教材の3章までの確認テスト結果があるという前提です。

 

data = {
    'user_id': [1]*30 + [2]*30 + [3]*30,
    'video_id': [101]*10 + [102]*10 + [103]*10 + [101]*10 + [102]*10 + [103]*10 + [101]*10 + [102]*10 + [103]*10,
    'question_id': list(range(1, 31)) * 3,
    'chapter': [1]*10 + [2]*10 + [3]*10 + [1]*10 + [2]*10 + [3]*10 + [1]*10 + [2]*10 + [3]*10,
    'correct': [1, 0, 1, 0, 1, 1, 1, 0, 1, 0,  # 受験者1, 章1
               1, 1, 1, 1, 1, 1,1, 1, 1, 1,  # 受験者1, 章2
               1, 0, 1, 0, 1, 1, 1, 0, 1, 0,  # 受験者1, 章3
               1, 0, 1, 1, 0, 0, 1, 1, 0, 1,  # 受験者2, 章1
               0, 0, 0, 1, 0, 0, 1, 1, 0, 0,  # 受験者2, 章2
               1, 0, 0, 0, 1, 0, 1, 1, 0, 1,  # 受験者2, 章3
               0, 1, 0, 0, 0, 1, 0, 1, 1, 0,  # 受験者3, 章1
               0, 0, 0, 0, 0, 1, 0, 0, 1, 1,  # 受験者3, 章2
               1, 0, 1, 1, 1, 0, 1, 0, 1, 0]  # 受験者3, 章3
}

df = pd.DataFrame(data)

 

このデータを元に、以下の手順でモデルを訓練しました:

  1. 特徴量としてuser_id, video_id, question_id, chapterを使用します。
  2. 目的変数としてcorrectを使用します。
  3. このデータを訓練データとテストデータに分割します。
  4. XGBoostなどの分類モデルを使用してモデルを訓練します。
  5. 訓練したモデルを使用して、user_id 2がvideo_id 102の関連テストを受験した際の正解確率を予測します。

モデルは、XGBoostでハイパーパラメータはデフォルトです。

 

# 特徴量と目的変数を指定
X = df[['user_id', 'video_id', 'question_id', 'chapter']]
y = df['correct']

# データを訓練データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# XGBoostのモデルの初期化
model = xgb.XGBClassifier(objective='binary:logistic', use_label_encoder=False, eval_metric='logloss')

# モデルの訓練
model.fit(X_train, y_train)

# 予測
y_pred = model.predict(X_test)

# 精度の計算
accuracy = accuracy_score(y_test, y_pred)

# user_id 2がvideo_id 102の関連テストを受験した際の正解確率を予測
user_2_video_102 = X[(X['user_id'] == 2) & (X['video_id'] == 102)]
predicted_probabilities = model.predict_proba(user_2_video_102)

# 正解する確率 (クラス 1) の予測値を取得
predicted_accuracy_for_user_2_video_102 = predicted_probabilities[:, 1].mean()

accuracy, predicted_accuracy_for_user_2_video_102

 

output:

(0.3333333333333333, 0.37165847)

結果として、テストデータに対するモデルの正解率は約33.3%、user_id 2がvideo_id 102の関連テストを受験した場合の予測される正解確率は約37.2%でした。この予測精度はダミーデータを使用しているため低いですが、実際の大量のログデータを使用すれば、モデルの性能は向上することが期待されます。

 

今回は、推奨されたテストに対する受講者の正解確率を予測するモデルの実装に関して考えてみました。この正解確率の閾値を調整して、類似度による推奨コンテンツと正解確率との組み合わせで最も最適な教材を推奨するという仕組みの実装も可能です。

 

次回は、このテーマを更に深掘りするか、日本や世界の学習のパーソナライズ化のトレンドや、AIを活用した学習における倫理的課題など、新しいトピックにも触れてみたいと思います。

 

こんにちはニコ

 

前回は、AIによる教材推奨(レコメンド)に関してLightFMライブラリーでの実装を試みましたがエラーを解決できませんでした。

Windowsベースのjupyter notebookの開発環境ではエラーへの対応に時間がかかりそうなので、今回は単純な類似度による推奨方法を考えてみます。

 

前回のおさらい:

目的は、人が家庭教師として行うようなカスタマイズされた学習体験を、AIの力を借りて提供することです。具体的には学習者の過去の学習ログを基に、最適な教材を自動で推薦するシステムを考えています。

 

・学習ログの加工

・最適な教材の選択

・正解率の予測

・最適な教材の提示

・フィードバックループによるアルゴリズムの更新

上記「最適な教材の選択」を、受講者の学習の状況や能力を示す特徴量と教材の特徴量との間の類似度を計算し、その類似度に基づいて教材を推奨する方法を考えます。

 

必要なのは以下の3つのライブラリです。

import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.preprocessing import StandardScaler

 

取り合えず、学習ログとしてサンプルデータを以下のようにしてみます。

 

# データサンプル
data = {
    'user_id': [1, 1, 2, 2],
    'video_概要':['python実行環境設定','データの読み込み','python実行環境設定','データの読み込み'],
    'question_概要':['仮想環境','read_csv','仮想環境','read_csv'],
    'video_id': [101, 102, 101, 103],
    '視聴時間': [5, 10, 5, 20],#動画視聴開始時間ー動画視聴終了時間
    'question_id': [201, 202, 201, 203],
    'ビデオ教材のレベル': [1, 2, 1, 3],#5段階レベル
    '各テストのレベル': [1, 2, 1, 3],#5段階レベル
    '回答結果': [1, 0, 1, 0],#1: 正解, 0: 不正解
    '正解率': [0.8, 0.5, 0.8, 0.4],
    'テストのトライアル回数': [1, 2, 1, 3],
    'テスト実施時間': [10, 15, 10, 25],#テスト開始日時-テスト終了日時
    '学習進捗率': [0.3, 0.35, 0.3, 0.4]
}

# データフレームの作成
all_data = pd.DataFrame(data)

 

通常、推奨対象となる教材はテキストだったり、動画だったり、あるいは確認テストだったりすると思いますが、ここではビデオ教材(video_id)を想定して考えてみます。

 

  1. 特徴量の準備

    • 受講者の学習の状況や能力を示す特徴量(各テストのレベル, 正解率, 学習進捗率,習熟レベルなど)と教材のテキスト情報(video_概要question_概要、教材レベル、テストレベル)を用意します。
    • 教材のテキスト情報はTF-IDFベクトル化を使用して数値化します。(将来的に考えたい)
  2. 特徴量の正規化

    • 特徴量のスケールが異なる場合、類似度の計算に影響を与える可能性があります。そのため、StandardScalerを使用して特徴量を正規化します。
  3. 類似度の計算

    • cosine_similarity関数を使用して、受講者のプロファイルと各教材の特徴量との間のコサイン類似度を計算します。この類似度は、受講者の学習の状況や能力と教材の内容やレベルとの間のマッチング度を示します。
  4. 教材のランキング

    • 計算された類似度のスコアに基づいて、教材をランキング付けします。類似度のスコアが高い教材が、受講者にとって最も適切な教材と考えられます。
  5. 推奨の出力

    • 上記のランキングに基づいて、最も類似度の高い教材(または複数の教材)を推奨として出力します。
考慮すべきこと:類似度計算に当たって、受講者が学習済、修了済の教材は推奨すべきではないため予め排除します。
上記のサンプルデータall_dataに関してこのアルゴリズムを適用したコードは以下の通りです。このコードを実行すると、user_id 2に関して、video_id 102が推奨されるという結果となりました。

# User 2の既視聴・既回答の教材とテストを取得
watched_videos = all_data[all_data['user_id'] == 2]['video_id'].tolist()
answered_questions = all_data[all_data['user_id'] == 2]['question_id'].tolist()

# 既視聴・既回答の教材とテストを排除
filtered_data = all_data[~all_data['video_id'].isin(watched_videos)]
filtered_data = filtered_data[~filtered_data['question_id'].isin(answered_questions)]

# 特徴量の選択
features = ['ビデオ教材のレベル', '各テストのレベル', '正解率', '学習進捗率', '学習者の習熟度']

# データの正規化
scaler = StandardScaler()
filtered_data_scaled = scaler.fit_transform(filtered_data[features])
user_data_scaled = scaler.transform(all_data[all_data['user_id'] == 2][features])

# 類似度の計算
similarity = cosine_similarity(user_data_scaled, filtered_data_scaled)

# 類似度の高い順に教材をランキング付け
recommended_indices = similarity.argsort(axis=1)[:, -3:]

# 推奨される教材のvideo_idを取得
unique_recommended_videos = filtered_data.iloc[recommended_indices.flatten()]['video_id'].unique()

print(f"user_id 2に推奨する教材のvideo_idは: {unique_recommended_videos}")

今回は、類似度を基にした簡単な推奨アルゴリズムの実装までを考えてみました。次回は、推奨された教材がテストである場合、そのテストに対する受講者の正解確率を予測するモデルについて考察します。

 

こんにちはニコ

 

前回までは、AIによる教材推奨(レコメンド)最適化のフローを考えてきました。今回は、このアイディアをPythonで実際に実装してみることにします。

 

前回のおさらい:

 

目的は、人の家庭教師が行うような、学習者の習熟度に合わせた教育をAIを利用して実現することです。具体的には、学習者の過去の学習ログを基に、最適な教材を自動で推薦するシステムを考えています。

 

・学習ログの加工

・最適な教材の選択

・正解率の予測

・最適な教材の提示

・フィードバックループによるアルゴリズムの更新

さて、どのようなライブラリを使用すればこのフローを実現できるでしょうか。調査の結果、SurpriseやImplicit、Fastaiといったライブラリがありました。しかし、今回私が特に注目したのは、協調フィルタリングとコンテンツベースの推薦を組み合わせたハイブリッドな推薦が可能な「LightFM」です。


LightFMとは? 

 

LightFMは、ユーザーとアイテム間のインタラクションを基に、推奨を生成するためのPythonライブラリです。具体的な流れとしては、インタラクション行列の作成、モデルのトレーニング、そして推奨の生成となります。

 

今回、このLightFMを使って、ダミーデータをもとに実際の実装に挑戦しました。しかし、残念ながら、「Kernel dead」というエラーに遭遇し、問題の解決にはかなりの時間を要しそうです。

なかなか、上手くいかないものですね。

 

トライしてみた実装:

!pip install lightfm

 

import numpy as np
from lightfm import LightFM
from lightfm.data import Dataset


#ダミーデータの準備
data = {
    'user_id': [1, 1, 2, 2],
    'video_id': [101, 102, 101, 103],
    '視聴時間': [5, 10, 5, 20],
    'test_id': [201, 202, 201, 203],
    '各テストのレベル': [1, 2, 1, 3],
    '回答結果': [1, 0, 1, 0],  # 1: 正解, 0: 不正解
    '正解率': [0.8, 0.5, 0.8, 0.4],
    'テストのトライアル回数': [1, 2, 1, 3],
    'テスト実施時間': [10, 15, 10, 25],
    '学習進捗率': [0.3, 0.35, 0.3, 0.4]
}

df1 = pd.DataFrame(data)

# 1. データの前処理

users = list(df1['user_id'].unique())
videos = list(df1['video_id'].unique())
tests = list(df1['test_id'].unique())

# LightFMのデータセットを初期化
dataset = Dataset()
dataset.fit(users, videos + tests)  # アイテムのIDとして、ビデオとテストの両方を組み合わせて使用

# 2. インタラクション行列の作成
(interactions, weights) = dataset.build_interactions([(row['user_id'], row['video_id'], row['視聴時間']) for _, row in df1.iterrows()] +
                                                     [(row['user_id'], row['test_id'], row['正解率']) for _, row in df1.iterrows()])

# 3. モデルのトレーニング
model = LightFM(loss='warp')  # WARP損失関数を使用
model.fit(interactions, epochs=30)

# 4. user_id 1の受講者への推奨
user_id = 1
n_items = len(videos + tests)
scores = model.predict(user_id, np.arange(n_items))
top_items = [videos + tests[i] for i in np.argsort(-scores)]  # スコアが高い順にアイテムを並べ替え

print(f"Recommended items for user {user_id}: {top_items}")

 

とはいえ、この手の実装には失敗はつきものですので、すぐに頭を切り替えて次回は新たなアプローチで、類似度を基にした推奨アルゴリズムの実装に挑戦してみたいと思います。