2023年MCMコンペC問題 Wordle予想問題の解答!


2023年MCMコンペC問題 Wordle予想問題の解答!

質問 1

  • 報告された結果の数(報告された結果の数)は毎日変化します。
    • この変動を考慮したモデルを開発し
    • モデルを使用予測間隔
    • 単語の何らかのプロパティは、ハードモードでプレイされたスコアの報告される割合に影響しますか? もしそうなら、どのようにして?そうでない場合は、なぜそうではないのでしょうか?

読み取りデータ

import pandas as pd
import numpy as np
from sklearn.metrics import mean_squared_error
from sklearn.preprocessing import LabelEncoder
import lightgbm as lgb
from datetime import date, timedelta

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
import seaborn as sns
%matplotlib inline
data=  pd.read_excel("./Problem_C_Data_Wordle.xlsx",header=1)
data

ここに画像の説明を挿入


データの前処理

data = data.drop(columns='Unnamed: 0')
data['Date'] = pd.to_datetime(data['Date'])
data

ここに画像の説明を挿入

data.set_index("Date", inplace=True)
data.sort_index(ascending=True,inplace=True)
data=data.reset_index()
data

ここに画像の説明を挿入


データ分析

データの傾向

plt.figure(figsize=(15,6))

data["Date"] =  pd.to_datetime(data["Date"])

plt.plot(data['Date'],data['Number of  reported results'],'r-o', markersize=3)

plt.legend(['Number of reported results'],fontsize=20)

plt.xlabel('Date',fontsize=14)
plt.ylabel('Number of reported results',fontsize=14)

ここに画像の説明を挿入


データ配信

plt.figure(figsize=(10,8))
kdeplo=data['Number of  reported results']

g=sns.kdeplot(kdeplo,legend=True,shade=True,color='b',label='Number of  reported results') 

plt.legend(loc='best', fontsize='large')  

ここに画像の説明を挿入

from scipy.stats import norm, skew
plt.figure(figsize=(10,8))
(mu, sigma) = norm.fit(data['Number of  reported results'])
print('\n mu = {:.2f} and sigma = {:.2f}\n'.format(mu, sigma))
g = sns.distplot(data['Number of  reported results'], fit=norm)
plt.legend(['Normal dist. ($\mu=$ {:.2f} and $\sigma=$ {:.2f} )'.format(mu, sigma)],
           loc='best')

g.set(ylabel='Frequency') 
g.set(title=' distribution')
plt.show()

ここに画像の説明を挿入


データ統計 - 平均、分散、最大値、最小値...

data.describe()

ここに画像の説明を挿入
ここに画像の説明を挿入


データの依存関係

corr = abs(data.corr())
corr['Number of  reported results'].sort_values(ascending=False)

ここに画像の説明を挿入
ハードモードの回数0.922252
コンテスト番号0.821787
1 トライ0.342183
4トライ0.211693
2 トライ0.118527
6 トライ 0.084180
5 トライ 0.077308
3 トライ 0.043624
7 トライ以上 (X) 0.033079

相関係数の絶対値が大きいほど相関が強く、相関係数が1または-1に近いほど相関が強く、相関係数が0に近いほど相関が弱くなります。

  • 相関係数:
    • 0.8-1.0 非常に強い相関
    • 0.6 ~ 0.8 の強い相関
    • 0.4-0.6 中程度の相関
    • 0.2~0.4の弱い相関
    • 0.0-0.2 相関が非常に弱い、または相関がない

ピアソン相関は、積差相関 (または積モーメント相関) としても知られ、20 世紀に英国の統計学者ピアソンによって提案された線形相関を計算する方法です。相関係数の強さは、係数の大きさだけを見るだけでは十分ではありません。

一般的に、絶対値をとった後、0 ~ 0.09 は無相関、0.3 ~ 弱い相関、0.1 ~ 0.3 は弱い相関、0.3 ~ 0.5 は中程度の相関、0.5 ~ 1.0 は強い相関となります。ただし、多くの場合、2 セットのデータに有意な相関があるかどうかをテストするために、有意差検定 (t 検定) も実行する必要があります。これは SPSS で自動的に計算されます。

plt.figure(figsize=(15,15))
g=sns.heatmap(data.corr(),cmap='RdYlGn',annot=True)
plt.show()

ここに画像の説明を挿入


回帰予測モデル - XGBoost

XGBoost の最初のプロトタイプは、Chen Tianqi が博士課程在学中に研究プロジェクトを担当していた 2014 年に登場しました。オープンソースの後、C++、Java、Python、R、Julia 言語をサポートする成熟したフレームワークに徐々に発展しました。XGBoost は Extreme Gradient Boosting の頭字語で、Gradient Boosting は実際には勾配ブースティング アルゴリズムです。

Gradient Boosting の名前は、実際には、Gradient Descent + Boosting の 2 つの部分で構成されています。まず第一に、ブースティングとは何かを理解する必要があります。Boostingの意味は、文字通り「ブーストする」という意味で、弱い学習器を改善することで、強い学習器を獲得する過程がブースティングの過程です。弱学習器は、複雑さが低く、トレーニングが容易で、過学習になりにくい非常にシンプルなモデルです。
これらのモデルは、深さが 1 レベルのみのデシジョン ツリーなどのランダムな推測よりも優れていることがよくあります。そして、選択された弱学習器を基本学習器と呼び、これをもとに組み合わせて改良学習器を得る。
ここに画像の説明を挿入

評価指標

評価指標が必要であり、回帰問題ではMSE平均二乗誤差が評価対象として選択されることが多いです。式は次のとおりです。
ここに画像の説明を挿入
次の式に基づいて MSE の値を計算します。

# 计算 MSE 值
np.square(np.subtract(y, y_)).mean()

XGBoost フレームワークは使用します

まず以下のコマンドを実行してインストールします。

pip install xgboost  # 安装 

回帰は XGBRegressor() インターフェイスを呼び出します。

XGBoost でモデリングされています。XGBoost の分類メソッドは XGBRegressor です。多くのパラメーターがあります。一般的に使用されるパラメーターを見てみましょう。

  • max_ Depth – 基本学習器のツリーの最大の深さ。
  • learning_rate – 学習率を向上させます。
  • n_estimators – デシジョン ツリーの数。
  • gamma – ノード分割に必要な最小損失関数ドロップを指定するペナルティ係数。
  • booster - ブースティング アルゴリズム (gbtree、gblinear、または dart) を指定します。
  • n_jobs – マルチスレッドの数を指定します。
  • reg_alpha – L1 正則化の重み。
  • reg_lambda – L2 正則化の重み。
  • scale_pos_weight – 正と負の重量バランス。
  • random_state – 乱数シード。

デフォルトのパラメーターを使用してモデルを初期化します。

  • XGBRegressor() を呼び出してモデルをトレーニングし、評価します。
import xgboost as xgb

model_r = xgb.XGBRegressor()

データセットを 80% のトレーニング データと 20% のテスト データに分割します

X = data.drop(labels='Number of  reported results', axis=1)
y = data['Number of  reported results']  # 目标值
from sklearn.model_selection import train_test_split

# 划分数据集,80% 训练数据和 20% 测试数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

X_train.shape, X_test.shape, y_train.shape, y_test.shape

訓練データを使用した訓練

  • 訓練データを使用した訓練
  • テストデータを使用して R^2 評価指標を計算します
model_r.fit(X_train, y_train)  # 使用训练数据训练
model_r.score(X_test, y_test)  # 使用测试数据计算 R^2 评估指标

パラメータ

XGBClassifier と XGBRegressor の両方にパラメータ目標があります。

  • 分類問題を解く場合は、デフォルトで object='binary:logistic' が選択され、回帰問題の場合はデフォルトで object='reg:linear' が選択されます。
  • 文字通りの意味から、これは学習者が完了するタスクの種類を指定するパラメーター (通常はターゲット パラメーターと呼ばれます) であることがわかるはずです。

そして、回帰問題を解くとき、このパラメータは通常 reg:linear (reg:squarederror に変更予定) と reg:logistic となり、それぞれ線形回帰とロジスティック回帰を表します。


決定木を描く

XGBoost は、モデルのトレーニング後に決定サブツリーを描画できる xgb.plot_tree メソッドを提供します。

  • 使用する場合は、モデルとサブツリーのシリアル番号を渡すだけで、必要な方を描画できます。

Graphviz パッケージをインストールする

# 安装 graphviz 包
!pip install graphviz
from matplotlib import pyplot as plt
from matplotlib.pylab import rcParams
%matplotlib inline

# 设置图像大小
rcParams['figure.figsize'] = [50, 10]

xgb.plot_tree(model_t, num_trees=1)

相互検証

相互検証に XGBoost を使用する方法。

相互検証は、機械学習でモデルを迅速に評価するための重要な方法です。

  • データセットを N 個のサブセットに分割し、そのうちの N-1 個を使用してモデルをトレーニングし、最後に残りの 1 個のサブセットで評価できます。

順番にポーリングし、最終的に N 回の評価の平均指標を求め、モデルの最終評価結果となります。

  • XGBoost は、相互検証プロセスを完了するための xgb.cv メソッドを提供します。

したがって、相互検証ではトレーニング セットとテスト セットを別々に分割する必要がなく、完全なデータ セットを直接使用できます。

# 依次传入特征和目标值

data_d = xgb.DMatrix(data=X, label=y)

xgb.cv(dtrain=data_d , params={
    
    'objective': 'reg:squarederror'}, nfold=5, as_pandas=True)

上記パラメータのうち、

  • dtrain はデータセットを渡します。params はモデルのカスタムパラメータです。
  • nfold は交差検証によって分割された N 個のサブセットです。
  • as_pandas は、最終出力が DataFrame スタイルになることを示します。

デフォルトでは、XGBoost はブースト反復を 10 回実行するため、10 行の出力が表示されます。

  • もちろん、num_boost_round パラメーターを変更して、最大反復回数をカスタマイズできます。

質問2

  • 将来の日付に対する特定の将来の解の単語については
    • 報告される結果の分布を予測できるモデルを開発します
    • 言い換えると、将来の日付 (1、2、3、4、5、6、X) の相対パーセンテージを予測します。
    • モデルと予測にはどのような不確実性が関連付けられていますか?
    • 2023 年 3 月 1 日に「EERIE」という単語が予測されるという具体的な例を挙げてください。
    • モデルの予測にどの程度自信がありますか?

母音はa、e、i、o、uの 5 つで、残りは子音です。

子音は、b、c、d、f、g、h、j、k、l、m、n、p、q、r、s、t、v、w、x、y、z です。

Vowel = ['a','e','i','o','u'] 
Consonant = list(set(small).difference(set(Vowel)))
def count_Vowel(s):
    c = 0
    for i in range(len(s)):
        if s[i] in Vowel:
            c+=1
    return c
def count_Consonant(s):
    c = 0
    for i in range(len(s)):
        if s[i] in Consonant:
            c+=1
    return c

df['Vowel_fre'] = df['Word'].apply(lambda x:count_Vowel(x)) 
df['Consonant_fre'] = df['Word'].apply(lambda x:count_Consonant(x))

時間的特徴変換

df["year"] = df.index.year

df["quarter"] = df.index.quarter

df["month"] = df.index.month

df["week"] = df.index.week

df["weekday"] = df.index.weekday

データの標準化

データの標準化とは、元のデータを特定の数学的変換方法を通じて特定の比率に従って変換し、0 ~ 1 または -1 ~ 1 の間隔などの小さな特定の間隔に収まるようにすることです。

  • 異なる変数間の性質、次元、桁数などの特性属性の違いを取り除き、無次元の相対値に変換し、
  • それは、各指標の値が定量的に同じレベルになるように値を標準化することです。
  • これにより、さまざまな単位または桁数の指標の包括的な分析と比較が容易になります。
from sklearn.preprocessing import StandardScaler

# 标准化
std = StandardScaler()
X1 = std .fit_transform(X)

アンサンブル学習 - ランダムフォレスト

アンサンブル学習は、複数の個別の学習者 (ベース学習者と呼ばれます) を構築および組み合わせて、学習タスクを完了することです。例として。以下の表において、○は分類が正しいことを意味し、×は分類が間違っていることを意味します。
ここに画像の説明を挿入

ランダムフォレスト

ランダム フォレストは、決定木ベースの学習器です。ただし、属性の選択はデシジョン ツリーと同じではありません。

  • ランダムフォレストでは、基本決定木学習器が各ノードのノードの属性セットから K 個の属性を含むサブセットをランダムに選択し、そのサブセットから最適な属性を選択して分割します。
  • これは「良いが異なる」条件を満たします。ランダム フォレストは計算オーバーヘッドが低く、機械学習アルゴリズムの中でも比較的高度なアルゴリズムです。

sklearnパラメータの調整

ここに画像の説明を挿入

相互検証方法のチューニング

まず、n_estimators、max_ Depth を調整します。

  • まず、特徴の数を観察します。これにより、max_ Depth などのパラメーターの範囲が決まります。
  • 次に、相互検証方法を使用してパラメーターを調整します。
    最適なパラメータ n_estimators=100、max_ Depth=10 を取得します。
def para_tune(para, X, y): #
    clf = RandomForestClassifier(n_estimators=para) # n_estimators 设置为 para
    score = np.mean(cross_val_score(clf, X, y, scoring='accuracy'))
    return score

def accurate_curve(para_range, X, y, title):
    score = []
    for para in para_range:
        score.append(para_tune(para, X, y))
    plt.figure()
    plt.title(title)
    plt.xlabel('Paramters')
    plt.ylabel('Score')
    plt.grid()
    plt.plot(para_range, score, 'o-')
    return plt

g = accurate_curve([2, 10, 50, 100, 150], X, y, 'n_estimator tuning')

ここに画像の説明を挿入

def para_tune(para, X, y):
    clf = RandomForestClassifier(n_estimators=300, max_depth=para)
    score = np.mean(cross_val_score(clf, X, y, scoring='accuracy'))
    return score

def accurate_curve(para_range, X, y, title):
    score = []
    for para in para_range:
        score.append(para_tune(para, X, y))
    plt.figure()
    plt.title(title)
    plt.xlabel('Paramters')
    plt.ylabel('Score')
    plt.grid()
    plt.plot(para_range, score, 'o-')
    return plt

g = accurate_curve([2, 10, 20, 30, 40], X, y, 'max_depth tuning')

ここに画像の説明を挿入


scikit-learn自動パラメータチューニング機能 GridSearchCV

from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import learning_curve

def plot_learning_curve(estimator, title, X, y, cv=10,
                        train_sizes=np.linspace(.1, 1.0, 5)):
    plt.figure()
    plt.title(title) # 设置图的 title
    plt.xlabel('Training examples') # 横坐标
    plt.ylabel('Score') # 纵坐标
    train_sizes, train_scores, test_scores = learning_curve(estimator, X, y, cv=cv,
                                                            train_sizes=train_sizes) 
    train_scores_mean = np.mean(train_scores, axis=1) # 计算平均值
    train_scores_std = np.std(train_scores, axis=1) # 计算标准差
    test_scores_mean = np.mean(test_scores, axis=1)
    test_scores_std = np.std(test_scores, axis=1)
    plt.grid() # 设置背景的网格

    plt.fill_between(train_sizes, train_scores_mean - train_scores_std,
                     train_scores_mean + train_scores_std,
                     alpha=0.1, color='g') # 设置颜色
    plt.fill_between(train_sizes, test_scores_mean - test_scores_std,
                     test_scores_mean + test_scores_std,
                     alpha=0.1, color='r')
    plt.plot(train_sizes, train_scores_mean, 'o-', color='g',
             label='traning score') # 绘制训练精度曲线
    plt.plot(train_sizes, test_scores_mean, 'o-', color='r',
             label='testing score') # 绘制测试精度曲线
    plt.legend(loc='best')
    return plt

clf = RandomForestClassifier()
para_grid = {
    
    'max_depth': [10], 'n_estimators': [100], 'max_features': [1, 5, 10], 'criterion': ['gini', 'entropy'],
             'min_samples_split': [2, 5, 10], 'min_samples_leaf': [1, 5, 10]}#对以上参数进行网格搜索
gs = GridSearchCV(clf, param_grid=para_grid, cv=3, scoring='accuracy')
gs.fit(X, y)
gs_best = gs.best_estimator_ #选择出最优的学习器
gs.best_score_ #最优学习器的精度

g = plot_learning_curve(gs_best, 'RFC', X, y)#调用实验2中定义的 plot_learning_curve 绘制学习曲线

ここに画像の説明を挿入


質問3

  • 解決策の単語を難易度別に分類するモデルを開発して要約します
    • 各カテゴリに関連付けられた特定の単語の属性を特定します
    • あなたのモデルを使用して、「EERIE」という単語はどのくらい難しいですか?
    • 分類モデルの精度について議論します

Kmeans クラスタリング アルゴリズム

アルゴリズム思考

連続反復を通じて k 値を見つけて除算法を形成し、k クラスターの平均値を使用して対応する種類のサンプルを表すときに得られる全体の誤差が最小になるようにします。

  • 同じクラスター内のオブジェクトの類似性は高くなりますが、異なるクラスター内のオブジェクトの類似性は低くなります。
  • K 平均法アルゴリズムの基礎は最小誤差二乗和基準であり、その機能は次のとおりです。
    ここに画像の説明を挿入
    上の式で、μc(i) は i 番目のクラスターの平均値を表します。
  • さまざまなクラスターに分割されたサンプルが類似しているほど、それらのクラスターとクラスの平均との間の二乗誤差は小さくなります。
  • 次に、すべてのクラスに対して計算された誤差二乗が累積され、再度合計されます。
  • つまり、J の値は小さいほど良いと考えられます。

アルゴリズムの実装手順

k 平均法アルゴリズムは、サンプルを k 個のクラスター中心にクラスター化するもので、k 値は私たちが指定します。つまり、データをいくつかのカテゴリーに分割します。

具体的なアルゴリズムは次のように説明されます。

  1. クラスター化する必要があるデータについては、k 個のクラスター重心点をランダムに選択します。
  2. 各点からクラスター重心点までの距離を求め、それが属するクラスを計算し、特定の値に収束するまで繰り返します。
# 导入 KMeans 估计器
from sklearn.cluster import KMeans
est = KMeans(n_clusters=4)  # 选择聚为 4 类
est.fit(X)
y_kmeans = est.predict(X)  # 预测类别,输出为含0、1、2、3数字的数组

# 为预测结果上色并可视化
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis')
centers = est.cluster_centers_  # 找出中心
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.5)  # 绘制中心点

K 平均法アルゴリズム: 期待値の最大化

K-Means は、期待値最大化法を使用して結果を得るアルゴリズムです。期待値の最大化は 2 つのステップで説明でき、その動作原理は次のとおりです。
1. クラスターの中心をいくつか推測します。
2. 収束するまで繰り返します。

期待ステップ (E ステップ): 点を最も近いクラスターの中心点に割り当てます。
最大化ステップ (M ステップ): クラスターの中心点をすべての点座標の平均として設定します。

from sklearn.metrics import pairwise_distances_argmin  # 最小距离函数
import numpy as np


def find_clusters(X, n_clusters, rseed=2):
    # 1.随机选择簇中心点
    rng = np.random.RandomState(rseed)
    i = rng.permutation(X.shape[0])[:n_clusters]
    centers = X[i]
    while True:
        # 2a.基于最近的中心指定标签
        labels = pairwise_distances_argmin(X, centers)
        # 2b.根据点的平均值找到新的中心
        new_centers = np.array([X[labels == i].mean(0)
                                for i in range(n_clusters)])
        # 2c.确认收敛
        if np.all(centers == new_centers):
            break
        centers = new_centers
    return centers, labels


centers, labels = find_clusters(X, 4)
plt.scatter(X[:, 0], X[:, 1], c=labels,
            s=50, cmap='viridis')  # 绘制聚类结果

おすすめ

転載: blog.csdn.net/weixin_43338969/article/details/129115707