2023 MCM-Wettbewerb C-Frage Wordle-Vorhersageproblemlösung!


2023 MCM-Wettbewerb C-Frage Wordle-Vorhersageproblemlösung!

Frage eins

  • Die Anzahl der gemeldeten Ergebnisse (Anzahl der gemeldeten Ergebnisse) ändert sich täglich.
    • ein Modell entwickeln, um diese Variation zu berücksichtigen ,
    • und verwenden Sie Ihr Modell, um ein zu erstellenVorhersageintervall
    • Beeinflussen irgendwelche Eigenschaften des Wortes den gemeldeten Prozentsatz der im Hardmode gespielten Punkte ? Wenn das so ist, wie? Wenn nicht, warum nicht?

Daten lesen

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

Fügen Sie hier eine Bildbeschreibung ein


Datenvorverarbeitung

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

Fügen Sie hier eine Bildbeschreibung ein

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

Fügen Sie hier eine Bildbeschreibung ein


Datenanalyse

Datentrends

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)

Fügen Sie hier eine Bildbeschreibung ein


Datenverteilung

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')  

Fügen Sie hier eine Bildbeschreibung ein

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()

Fügen Sie hier eine Bildbeschreibung ein


Datenstatistiken – Mittelwert, Varianz, Maxima und Minima ...

data.describe()

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein


Datenabhängigkeit

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

Fügen Sie hier eine Bildbeschreibung ein
Anzahl im harten Modus 0,922252
Wettbewerbsnummer 0,821787
1 Versuch 0,342183
4 Versuche 0,211693
2 Versuche 0,118527
6 Versuche
0,084180 5 Versuche 0,077308
3 Versuche 0,043624
7 oder mehr Versuche (X) 0,033079

Je größer der Absolutwert des Korrelationskoeffizienten ist, desto stärker ist die Korrelation. Je näher der Korrelationskoeffizient bei 1 oder -1 liegt, desto stärker ist die Korrelation. Je näher der Korrelationskoeffizient bei 0 liegt, desto schwächer ist die Korrelation.

  • Korrelationskoeffizient:
    • 0,8-1,0 Sehr starke Korrelation
    • 0,6–0,8 starke Korrelation
    • 0,4–0,6 Mäßige Korrelation
    • 0,2–0,4 schwache Korrelation
    • 0,0–0,2 Sehr schwache oder keine Korrelation

Die Pearson-Korrelation, auch Produkt-Differenz-Korrelation (oder Produkt-Moment-Korrelation) genannt, ist eine Methode zur Berechnung der linearen Korrelation, die im 20. Jahrhundert vom britischen Statistiker Pearson vorgeschlagen wurde. Die Stärke des Korrelationskoeffizienten reicht nicht aus, um nur die Größe des Koeffizienten zu betrachten.

Im Allgemeinen ist nach Ermittlung des Absolutwerts 0-0,09 keine Korrelation, 0,3-schwach, 0,1-0,3 eine schwache Korrelation, 0,3-0,5 eine mäßige Korrelation und 0,5-1,0 eine starke Korrelation. Allerdings müssen Sie häufig auch einen signifikanten Differenztest, also den T-Test, durchführen, um zu testen, ob die beiden Datensätze signifikant korrelieren, was in SPSS automatisch berechnet wird.

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

Fügen Sie hier eine Bildbeschreibung ein


Regressionsvorhersagemodell – XGBoost

Der früheste Prototyp von XGBoost erschien im Jahr 2014, als Chen Tianqi während seiner Doktorarbeit das Forschungsprojekt leitete. Nach Open Source entwickelte es sich allmählich zu einem ausgereiften Framework, das die Sprachen C++, Java, Python, R und Julia unterstützt. XGBoost ist ein Akronym für Extreme Gradient Boosting, wobei Gradient Boosting eigentlich ein Algorithmus zur Gradientenverstärkung ist.

Der Name Gradient Boosting besteht eigentlich aus zwei Teilen: Gradient Descent + Boosting. Zunächst müssen Sie herausfinden, was Boosting ist. Die Bedeutung von „Boosting“ ist genau wie die wörtliche Bedeutung von „Boosting“. Durch die Verbesserung des schwachen Lernenden ist der Prozess der Gewinnung eines starken Lernenden der Prozess des Boostens. Schwache Lernende sind sehr einfache Modelle mit geringer Komplexität, leicht zu trainieren und nicht anfällig für Überanpassung.
Diese Modelle sind oft besser als zufällige Schätzungen, beispielsweise Entscheidungsbäume mit nur einer Tiefenebene. Dann wird der ausgewählte schwache Lernende als Basislerner bezeichnet, und der verbesserte Lernende wird durch Kombination auf dieser Basis erhalten.
Fügen Sie hier eine Bildbeschreibung ein

Bewertungsindex

Es ist ein Bewertungsindex erforderlich. Bei Regressionsproblemen wird häufig der mittlere quadratische MSE-Fehler zur Bewertung ausgewählt. Die Formel lautet wie folgt:
Fügen Sie hier eine Bildbeschreibung ein
Berechnen Sie den Wert von MSE anhand der Formel:

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

XGBoost-Framework verwendet

Führen Sie zunächst den folgenden Befehl zur Installation aus.

pip install xgboost  # 安装 

Regression ruft die Schnittstelle XGBRegressor() auf.

Modelliert mit XGBoost. Die Klassifizierungsmethode von XGBoost ist XGBRegressor. Es gibt viele Parameter. Schauen wir uns die am häufigsten verwendeten an:

  • max_ Depth – Die maximale Baumtiefe des Basislerners.
  • learning_rate – Lernrate steigern.
  • n_estimators – Anzahl der Entscheidungsbäume.
  • Gamma – Der Straffaktor, der den minimalen Verlust der Verlustfunktion angibt, der für Knotenaufteilungen erforderlich ist.
  • booster – gibt den Boosting-Algorithmus an: gbtree, gblinear oder dart.
  • n_jobs – gibt die Anzahl des Multithreadings an.
  • reg_alpha – L1-Regularisierungsgewichte.
  • reg_lambda – L2-Regularisierungsgewichte.
  • scale_pos_weight – Positiver und negativer Gewichtsausgleich.
  • random_state – Zufallszahlen-Seed.

Initialisieren Sie das Modell mit Standardparametern.

  • Rufen Sie XGBRegressor() auf, um das Modell zu trainieren und auszuwerten.
import xgboost as xgb

model_r = xgb.XGBRegressor()

Teilen Sie den Datensatz in 80 % Trainingsdaten und 20 % Testdaten auf

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

Trainieren Sie mit Trainingsdaten

  • Trainieren Sie mit Trainingsdaten
  • Berechnen Sie die R^2-Bewertungsmetrik anhand der Testdaten
model_r.fit(X_train, y_train)  # 使用训练数据训练
model_r.score(X_test, y_test)  # 使用测试数据计算 R^2 评估指标

Parameter

Sowohl in XGBClassifier als auch in XGBRegressor gibt es ein Parameterziel.

  • Beim Lösen von Klassifizierungsproblemen ist „objective='binary:logistic'“ standardmäßig ausgewählt, und „objective=‘reg:linear‘“ ist standardmäßig für Regressionsprobleme ausgewählt.
  • Anhand der wörtlichen Bedeutung sollten Sie erkennen können, dass es sich hierbei um einen Parameter handelt, der angibt, welche Art von Aufgabe der Lernende erledigt. Dieser Parameter wird üblicherweise als Zielparameter bezeichnet.

Dann ist dieser Parameter im Allgemeinen reg:linear (wird umbenannt in: reg:squarederror) und reg:logistic, wenn Regressionsprobleme gelöst werden, was eine lineare Regression bzw. eine logistische Regression darstellt.


Zeichnen Sie einen Entscheidungsbaum

XGBoost stellt die Methode xgb.plot_tree bereit, mit der der Entscheidungsteilbaum nach dem Training des Modells gezeichnet werden kann.

  • Wenn Sie es verwenden, müssen Sie nur die Seriennummern des Modells und des Teilbaums eingeben und können dann zeichnen, was Sie möchten.

Installieren Sie das graphviz-Paket

# 安装 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)

Kreuzvalidierung

So verwenden Sie XGBoost für die Kreuzvalidierung.

Kreuzvalidierung ist eine wichtige Methode zur schnellen Bewertung von Modellen im maschinellen Lernen.

  • Sie können den Datensatz in N Teilmengen aufteilen, N-1 davon zum Trainieren des Modells verwenden und es schließlich anhand der verbleibenden Teilmenge auswerten.

Führen Sie nacheinander eine Umfrage durch und ermitteln Sie schließlich den durchschnittlichen Index der N-fachen Bewertung als endgültiges Bewertungsergebnis des Modells.

  • XGBoost stellt die Methode xgb.cv bereit, um den Kreuzvalidierungsprozess abzuschließen.

Daher ist bei der Kreuzvalidierung keine separate Aufteilung der Trainings- und Testsätze erforderlich, und es kann direkt der vollständige Datensatz verwendet werden.

# 依次传入特征和目标值

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

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

Unter den oben genannten Parametern sind

  • dtrain übergibt den Datensatz, params ist der benutzerdefinierte Parameter des Modells,
  • nfold sind N Teilmengen geteilt durch Kreuzvalidierung,
  • as_pandas gibt an, dass die endgültige Ausgabe im DataFrame-Stil erfolgen wird.

Standardmäßig führt XGBoost Boosting-Iterationen 10 Mal durch, sodass Sie 10 Ausgabezeilen sehen können.

  • Natürlich können Sie den Parameter num_boost_round ändern, um die maximale Anzahl von Iterationen anzupassen.

Frage zwei

  • Für ein gegebenes zukünftiges Lösungswort für ein zukünftiges Datum ,
    • Entwickeln Sie ein Modell, mit dem Sie die Verteilung der gemeldeten Ergebnisse vorhersagen können .
    • mit anderen Worten,Sagen Sie relative Prozentsätze für zukünftige Daten voraus (1, 2, 3, 4, 5, 6, X)
    • Welche Unsicherheiten sind mit Ihren Modellen und Prognosen verbunden?
    • Geben Sie ein konkretes Beispiel für Ihre Vorhersage für das Wort EERIE am 1. März 2023.
    • Wie sicher sind Sie in den Vorhersagen Ihres Modells ?

Es gibt fünf Vokale: a, e, i, o, u , und der Rest sind Konsonanten.

Die Konsonanten sind: 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))

Zeitliche Merkmalstransformation

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

Datenstandardisierung

Bei der Standardisierung von Daten werden die Originaldaten mithilfe einer bestimmten mathematischen Transformationsmethode gemäß einem bestimmten Verhältnis konvertiert, sodass sie in ein kleines spezifisches Intervall fallen, beispielsweise in das Intervall 0-1 oder -1-1

  • Eliminieren Sie die Unterschiede in charakteristischen Attributen wie Eigenschaften, Dimensionen und Größenordnungen zwischen verschiedenen Variablen und konvertieren Sie sie in einen dimensionslosen relativen Wert.
  • Das heißt, die Werte zu standardisieren, sodass die Werte jedes Indikators auf dem gleichen quantitativen Niveau liegen.
  • Dies ermöglicht eine umfassende Analyse und einen Vergleich von Indikatoren unterschiedlicher Einheiten oder Größenordnungen.
from sklearn.preprocessing import StandardScaler

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

Ensemble-Lernen – Random Forest

Beim Ensemble-Lernen werden mehrere einzelne Lernende (sogenannte Basislerner) aufgebaut und kombiniert, um Lernaufgaben zu erledigen. Als Beispiel. In der folgenden Tabelle bedeutet √, dass die Klassifizierung korrekt ist, und × bedeutet, dass die Klassifizierung falsch ist.
Fügen Sie hier eine Bildbeschreibung ein

zufälliger Wald

Random Forest ist ein auf Entscheidungsbäumen basierender Lernprozess. Die Attributauswahl ist jedoch nicht dasselbe wie Entscheidungsbäume.

  • In der Zufallsstruktur wählt der Basisentscheidungsbaum-Lerner zufällig eine Teilmenge mit K Attributen aus der Attributmenge des Knotens auf jedem Knoten aus und wählt dann das optimale Attribut aus der Teilmenge zur Aufteilung aus.
  • Damit ist die Bedingung „gut, aber anders“ erfüllt. Random Forest hat einen geringen Rechenaufwand und ist ein Algorithmus auf relativ hoher Ebene unter den Algorithmen für maschinelles Lernen.

Sklearn-Parameteroptimierung

Fügen Sie hier eine Bildbeschreibung ein

Optimierung der Kreuzvalidierungsmethode

Wir passen zuerst an: n_estimators, max_ Depth.

  • Beobachten Sie zunächst die Anzahl der Features, die den Bereich von Parametern wie max_ Depth bestimmt.
  • Verwenden Sie dann die Kreuzvalidierungsmethode, um die Parameter abzustimmen.
    Holen Sie sich die optimalen Parameter 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')

Fügen Sie hier eine Bildbeschreibung ein

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')

Fügen Sie hier eine Bildbeschreibung ein


scikit-learn automatische Parameteranpassungsfunktion 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 绘制学习曲线

Fügen Sie hier eine Bildbeschreibung ein


Frage drei

  • Entwickeln und fassen Sie ein Modell zur Klassifizierung von Lösungswörtern nach Schwierigkeitsgrad zusammen .
    • Identifizieren Sie die Attribute eines bestimmten Wortes, das jeder Kategorie zugeordnet ist .
    • Wie schwer ist das Wort „Unheimlich“ nach Ihrem Modell ?
    • Besprechen Sie die Genauigkeit von Klassifizierungsmodellen .

Kmeans-Clustering-Algorithmus

Algorithmendenken

Ermitteln Sie den k-Wert durch kontinuierliche Iterationen, um eine Divisionsmethode zu bilden, sodass der Gesamtfehler am kleinsten ist, wenn der Mittelwert der k-Cluster zur Darstellung der entsprechenden Stichprobentypen verwendet wird.

  • Die Ähnlichkeit von Objekten im selben Cluster ist hoch, während die Ähnlichkeit von Objekten in verschiedenen Clustern gering ist.
  • Die Grundlage des k-means-Algorithmus ist das Kriterium der minimalen Fehlerquadratsumme, und seine Funktion ist:
    Fügen Sie hier eine Bildbeschreibung ein
    In der obigen Formel stellt μc(i) den Mittelwert des i-ten Clusters dar.
  • Je ähnlicher die in verschiedene Cluster unterteilten Stichproben sind, desto kleiner ist der quadratische Fehler zwischen ihnen und dem Mittelwert der Klasse.
  • Anschließend werden die für alle Klassen berechneten Fehlerquadrate akkumuliert und erneut summiert,
  • Das heißt, wir hoffen, dass es umso besser ist, je kleiner der Wert von J ist.

Schritte zur Algorithmusimplementierung

Der k-means-Algorithmus besteht darin, die Stichproben in k Clusterzentren zu gruppieren, wobei der k-Wert von uns angegeben wird, das heißt, wir möchten die Daten in mehrere Kategorien unterteilen.

Der spezifische Algorithmus wird wie folgt beschrieben:

  1. Wählen Sie für die zu gruppierenden Daten zufällig k Cluster-Schwerpunktpunkte aus.
  2. Ermitteln Sie den Abstand von jedem Punkt zum Cluster-Schwerpunkt, berechnen Sie die Klasse, zu der er gehören soll, und iterieren Sie, bis er einem bestimmten Wert entspricht.
# 导入 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-Means-Algorithmus: Erwartungsmaximierung

K-Means ist ein Algorithmus, der eine Erwartungsmaximierungsmethode verwendet, um zu einem Ergebnis zu gelangen. Die Erwartungsmaximierung kann in zwei Schritten erklärt werden und ihr Funktionsprinzip ist wie folgt:
1. Erraten Sie einige Clusterzentren.
2. Wiederholen Sie den Vorgang bis zur Konvergenz.

Erwartungsschritt (E-Schritt): Ordnen Sie den Punkt seinem nächstgelegenen Clustermittelpunkt zu.
Maximierungsschritt (M-Schritt): Legen Sie den Clustermittelpunkt als Durchschnitt aller Punktkoordinaten fest.

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')  # 绘制聚类结果

Supongo que te gusta

Origin blog.csdn.net/weixin_43338969/article/details/129115707
Recomendado
Clasificación