Некоторые исправления (спасибо моей Ритке :)
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": 2,
|
||||
"id": "a34b5583",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -84,7 +84,7 @@
|
||||
"4 11.59 1 1"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
@@ -135,7 +135,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": 3,
|
||||
"id": "31f5b8b6",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -185,7 +185,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": 4,
|
||||
"id": "7594c82a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -213,7 +213,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": 5,
|
||||
"id": "db397206",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -241,7 +241,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 6,
|
||||
"id": "ca70b1e2",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -303,7 +303,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": 7,
|
||||
"id": "382c3054",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -319,7 +319,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"execution_count": 8,
|
||||
"id": "c77e2e2e",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -360,7 +360,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"execution_count": 9,
|
||||
"id": "78ffd74b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -386,7 +386,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"execution_count": 10,
|
||||
"id": "87f134c2",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -431,7 +431,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"execution_count": 12,
|
||||
"id": "a3830347",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -439,22 +439,223 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Таблица ANOVA:\n",
|
||||
"\n",
|
||||
"Таблица ANOVA для полной модели:\n",
|
||||
" df sum_sq mean_sq F PR(>F)\n",
|
||||
"C(A) 1.0 478.108752 478.108752 631.694471 4.061068e-26\n",
|
||||
"C(B) 3.0 153.241356 51.080452 67.489330 1.051893e-15\n",
|
||||
"C(A):C(B) 3.0 178.558140 59.519380 78.639144 8.022881e-17\n",
|
||||
"Residual 40.0 30.274683 0.756867 NaN NaN\n",
|
||||
"\n",
|
||||
"Отсортированная таблица дисперсионного анализа:\n",
|
||||
" df sum_sq mean_sq F PR(>F)\n",
|
||||
"C(A) 1.0 478.108752 478.108752 631.694471 4.061068e-26\n",
|
||||
"C(A):C(B) 3.0 178.558140 59.519380 78.639144 8.022881e-17\n",
|
||||
"C(B) 3.0 153.241356 51.080452 67.489330 1.051893e-15\n",
|
||||
"Residual 40.0 30.274683 0.756867 NaN NaN\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from statsmodels.stats.anova import anova_lm\n",
|
||||
"import pandas as pd\n",
|
||||
"import statsmodels.api as sm\n",
|
||||
"from statsmodels.formula.api import ols\n",
|
||||
"\n",
|
||||
"# ANOVA с взаимодействием\n",
|
||||
"anova_table = anova_lm(model_full)\n",
|
||||
"print(\"Таблица ANOVA:\")\n",
|
||||
"print(anova_table)"
|
||||
"# Предположим, df - ваш DataFrame с колонками 'Y', 'A', 'B'\n",
|
||||
"# где A и B - категориальные факторы\n",
|
||||
"\n",
|
||||
"# 1. Построение моделей\n",
|
||||
"model_full = ols('Y ~ C(A) + C(B) + C(A):C(B)', data=df).fit()\n",
|
||||
"model_additive = ols('Y ~ C(A) + C(B)', data=df).fit()\n",
|
||||
"model_onlyA = ols('Y ~ C(A)', data=df).fit()\n",
|
||||
"model_onlyB = ols('Y ~ C(B)', data=df).fit()\n",
|
||||
"model_const = ols('Y ~ 1', data=df).fit()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"id": "4d18ccf9",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"C:\\Users\\margaery\\AppData\\Local\\Temp\\ipykernel_18780\\711296804.py:36: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n",
|
||||
" return pd.concat([df, pd.DataFrame([row])], ignore_index=True)\n",
|
||||
"C:\\Users\\margaery\\AppData\\Local\\Temp\\ipykernel_18780\\711296804.py:57: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n",
|
||||
" AOV = pd.concat([AOV, pd.DataFrame([error_row])], ignore_index=True)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>H</th>\n",
|
||||
" <th>RSS</th>\n",
|
||||
" <th>Df</th>\n",
|
||||
" <th>MRSS</th>\n",
|
||||
" <th>F</th>\n",
|
||||
" <th>x_alpha</th>\n",
|
||||
" <th>Pr(>F)</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>H_(12)</td>\n",
|
||||
" <td>208.832823</td>\n",
|
||||
" <td>3.0</td>\n",
|
||||
" <td>69.610941</td>\n",
|
||||
" <td>78.639144</td>\n",
|
||||
" <td>3.667421</td>\n",
|
||||
" <td>8.022881e-17</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>H_(1)</td>\n",
|
||||
" <td>362.074179</td>\n",
|
||||
" <td>6.0</td>\n",
|
||||
" <td>60.345697</td>\n",
|
||||
" <td>73.064237</td>\n",
|
||||
" <td>2.876587</td>\n",
|
||||
" <td>5.459874e-20</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>H_(2)</td>\n",
|
||||
" <td>686.941575</td>\n",
|
||||
" <td>4.0</td>\n",
|
||||
" <td>171.735394</td>\n",
|
||||
" <td>216.902976</td>\n",
|
||||
" <td>3.295372</td>\n",
|
||||
" <td>1.537422e-26</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>H_(0)</td>\n",
|
||||
" <td>840.182931</td>\n",
|
||||
" <td>7.0</td>\n",
|
||||
" <td>120.026133</td>\n",
|
||||
" <td>152.868556</td>\n",
|
||||
" <td>2.744837</td>\n",
|
||||
" <td>8.275092e-27</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>Err</td>\n",
|
||||
" <td>30.274683</td>\n",
|
||||
" <td>40.0</td>\n",
|
||||
" <td>0.756867</td>\n",
|
||||
" <td>NaN</td>\n",
|
||||
" <td>NaN</td>\n",
|
||||
" <td>None</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" H RSS Df MRSS F x_alpha Pr(>F)\n",
|
||||
"0 H_(12) 208.832823 3.0 69.610941 78.639144 3.667421 8.022881e-17\n",
|
||||
"1 H_(1) 362.074179 6.0 60.345697 73.064237 2.876587 5.459874e-20\n",
|
||||
"2 H_(2) 686.941575 4.0 171.735394 216.902976 3.295372 1.537422e-26\n",
|
||||
"3 H_(0) 840.182931 7.0 120.026133 152.868556 2.744837 8.275092e-27\n",
|
||||
"4 Err 30.274683 40.0 0.756867 NaN NaN None"
|
||||
]
|
||||
},
|
||||
"execution_count": 21,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"\n",
|
||||
"from scipy.stats import f\n",
|
||||
"\n",
|
||||
"# Функция для сравнения моделей и извлечения нужных данных\n",
|
||||
"def compare_models(reduced_model, full_model):\n",
|
||||
" anova_result = sm.stats.anova_lm(reduced_model, full_model)\n",
|
||||
" return {\n",
|
||||
" 'df_diff': anova_result['df_diff'].iloc[1], # Разница степеней свободы\n",
|
||||
" 'ss_diff': anova_result['ss_diff'].iloc[1], # Разница в RSS\n",
|
||||
" 'rss_reduced': reduced_model.ssr, # RSS редуцированной модели\n",
|
||||
" 'rss_full': full_model.ssr, # RSS полной модели\n",
|
||||
" 'F': anova_result['F'].iloc[1], # F-статистика\n",
|
||||
" 'p_value': anova_result['Pr(>F)'].iloc[1] # P-значение\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"# Сравнение моделей\n",
|
||||
"anova_additive = compare_models(model_additive, model_full)\n",
|
||||
"anova_A = compare_models(model_onlyA, model_full)\n",
|
||||
"anova_B = compare_models(model_onlyB, model_full)\n",
|
||||
"anova_null = compare_models(model_const, model_full)\n",
|
||||
"\n",
|
||||
"# Создание DataFrame для результатов\n",
|
||||
"columns = ['H', 'RSS', 'Df', 'Sum of Sq', 'F', 'x_alpha', 'Pr(>F)']\n",
|
||||
"AOV = pd.DataFrame(columns=columns)\n",
|
||||
"\n",
|
||||
"# Функция для добавления строк в AOV\n",
|
||||
"def add_aov_row(df, name, anova_result, rdf, alpha):\n",
|
||||
" row = {\n",
|
||||
" 'H': name,\n",
|
||||
" 'RSS': anova_result['rss_reduced'], # Теперь берём RSS редуцированной модели\n",
|
||||
" 'Df': anova_result['df_diff'],\n",
|
||||
" 'Sum of Sq': anova_result['ss_diff'],\n",
|
||||
" 'F': anova_result['F'],\n",
|
||||
" 'x_alpha': f.ppf(1 - alpha, anova_result['df_diff'], rdf),\n",
|
||||
" 'Pr(>F)': f\"{anova_result['p_value']:.7g}\", \n",
|
||||
" }\n",
|
||||
" return pd.concat([df, pd.DataFrame([row])], ignore_index=True)\n",
|
||||
"\n",
|
||||
"# Получение residual degrees of freedom из полной модели\n",
|
||||
"rdf = model_full.df_resid\n",
|
||||
"\n",
|
||||
"# Добавление строк в AOV\n",
|
||||
"AOV = add_aov_row(AOV, 'H_(12)', anova_additive, rdf, alpha)\n",
|
||||
"AOV = add_aov_row(AOV, 'H_(1)', anova_A, rdf, alpha)\n",
|
||||
"AOV = add_aov_row(AOV, 'H_(2)', anova_B, rdf, alpha)\n",
|
||||
"AOV = add_aov_row(AOV, 'H_(0)', anova_null, rdf, alpha)\n",
|
||||
"\n",
|
||||
"# Добавление строки ошибок (RSS полной модели)\n",
|
||||
"error_row = {\n",
|
||||
" 'H': 'Err',\n",
|
||||
" 'RSS': model_full.ssr,\n",
|
||||
" 'Df': rdf,\n",
|
||||
" 'Sum of Sq': None,\n",
|
||||
" 'F': None,\n",
|
||||
" 'x_alpha': None,\n",
|
||||
" 'Pr(>F)': None\n",
|
||||
"}\n",
|
||||
"AOV = pd.concat([AOV, pd.DataFrame([error_row])], ignore_index=True)\n",
|
||||
"\n",
|
||||
"# Вычисление MRSS (Mean Residual Sum of Squares)\n",
|
||||
"AOV['MRSS'] = AOV['RSS'] / AOV['Df']\n",
|
||||
"\n",
|
||||
"# Финальная обработка AOV (перестановка столбцов)\n",
|
||||
"AOV1 = AOV[['H', 'RSS', 'Df', 'MRSS', 'F', 'x_alpha', 'Pr(>F)']]\n",
|
||||
"\n",
|
||||
"# Вывод результатов\n",
|
||||
"AOV1\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -480,7 +681,7 @@
|
||||
" $$\n",
|
||||
"\n",
|
||||
"- **Вывод:**\n",
|
||||
" На уровне значимости $\\alpha=0.02$ все факторы (A, B) и их взаимодействие **значимо** ($p < 0.02$). Это означает, что влияние фактора A на Y зависит от уровня фактора B, и наоборот."
|
||||
" На уровне значимости $\\alpha=0.02$ все факторы (A, B) и их взаимодействие **значимо**. Это означает, что влияние фактора A на Y зависит от уровня фактора B, и наоборот."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -493,20 +694,32 @@
|
||||
"- AIC оценивает баланс между качеством подгонки модели и её сложностью, накладывая штраф за избыточное количество параметров.\n",
|
||||
"- BIC работает аналогично AIC, но применяет более строгий штраф за сложность, особенно при больших объемах данных.\n",
|
||||
"\n",
|
||||
"Сравниваем две модели:\n",
|
||||
"Сравниваем модели:\n",
|
||||
"1. **Полная модель** (с взаимодействием): \n",
|
||||
" $$\n",
|
||||
" Y \\sim A + b + A : B.\n",
|
||||
" Y \\sim A + B + AB.\n",
|
||||
" $$\n",
|
||||
"2. **Аддитивная модель** (без взаимодействия):\n",
|
||||
" $$\n",
|
||||
" Y \\sim A + B.\n",
|
||||
" $$\n",
|
||||
"3. **Только А**:\n",
|
||||
" $$\n",
|
||||
" Y \\sim A\n",
|
||||
" $$\n",
|
||||
"4. **Только В**:\n",
|
||||
" $$\n",
|
||||
" Y \\sim B\n",
|
||||
" $$\n",
|
||||
"5. **Константная**:\n",
|
||||
" $$\n",
|
||||
" Y \\sim 1\n",
|
||||
" $$"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"execution_count": 12,
|
||||
"id": "2db6d2ce",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
@@ -514,23 +727,39 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Модель\t\tAIC\tBIC\n",
|
||||
"Полная \t130.10\t145.07\n",
|
||||
"Аддитивная \t216.79\t226.15\n"
|
||||
"\n",
|
||||
"Сравнение моделей по AIC и BIC:\n",
|
||||
" Модель AIC BIC\n",
|
||||
"0 Полная 130.095418 145.065027\n",
|
||||
"1 Аддитивная 216.794085 226.150090\n",
|
||||
"2 Только A 237.209208 240.951610\n",
|
||||
"3 Только B 271.948414 279.433218\n",
|
||||
"4 Константная 275.614194 277.485395\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Список моделей\n",
|
||||
"\n",
|
||||
"# 3. Таблица AIC/BIC для всех моделей (как во втором изображении)\n",
|
||||
"models = {\n",
|
||||
" \"Полная\": model_full,\n",
|
||||
" \"Аддитивная\": model_additive\n",
|
||||
" 'Полная': model_full,\n",
|
||||
" 'Аддитивная': model_additive,\n",
|
||||
" 'Только A': model_onlyA,\n",
|
||||
" 'Только B': model_onlyB,\n",
|
||||
" 'Константная': model_const\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"# Вывод AIC и BIC\n",
|
||||
"print(\"Модель\\t\\tAIC\\tBIC\")\n",
|
||||
"results = []\n",
|
||||
"for name, model in models.items():\n",
|
||||
" print(f\"{name} \\t{model.aic:.2f}\\t{model.bic:.2f}\")"
|
||||
" results.append({\n",
|
||||
" 'Модель': name,\n",
|
||||
" 'AIC': model.aic,\n",
|
||||
" 'BIC': model.bic\n",
|
||||
" })\n",
|
||||
"\n",
|
||||
"aic_bic_table = pd.DataFrame(results)\n",
|
||||
"print(\"\\nСравнение моделей по AIC и BIC:\")\n",
|
||||
"print(aic_bic_table)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -541,66 +770,11 @@
|
||||
"### Вывод о сравнении моделей\n",
|
||||
"\n",
|
||||
"- **Результаты AIC и BIC:**\n",
|
||||
" - **AIC:** Полная модель имеет AIC = 130.10, в то время как аддитивная модель имеет AIC = 216.79. Это указывает на значительное преимущество полной модели.\n",
|
||||
" - **BIC:** Полная модель также имеет BIC = 145.07, а аддитивная модель — BIC = 226.15. Разница подтверждает выбор полной модели.\n",
|
||||
" - **AIC:** Минимален у полной модели (не меньше чем на 86.7 меньше, чем у остальных).\n",
|
||||
" - **BIC:** Минимален у полной модели (не меньше чем на 81.08 меньше, чем у остальных).\n",
|
||||
"\n",
|
||||
"- **Заключение:**\n",
|
||||
" - Полная модель **предпочтительнее**, так как она лучше соответствует данным, что подтверждается меньшими значениями AIC и BIC.\n",
|
||||
" - Аддитивная модель не учитывает взаимодействие факторов."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6dff2300",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Пункт f)\n",
|
||||
"### 1. Основные эффекты факторов A и B\n",
|
||||
"- **Фактор A:** \n",
|
||||
" Оказал **сильное статистически значимое влияние** на $Y$ ($F=631.69, p<0.001$). \n",
|
||||
"\n",
|
||||
"\n",
|
||||
"- **Фактор B:** \n",
|
||||
" Также **значимо влияет** на $Y$ ($F=67.49, p<0.001$). \n",
|
||||
"\n",
|
||||
"### 2. Взаимодействие факторов $A \\times B$\n",
|
||||
"- **Статистическая значимость:** \n",
|
||||
" Взаимодействие **значимо** ($F=78.64, p<0.001$).\n",
|
||||
" \n",
|
||||
"- **Визуальное подтверждение:** \n",
|
||||
" График зависимости $Y$ от $A$ при фиксированных $B$ показывает пересечение линий (особенно для $B=4$), что указывает на **неаддитивность эффектов**.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"### 3. Выбор оптимальной модели\n",
|
||||
"- **AIC/BIC:** \n",
|
||||
" | Модель | AIC | BIC |\n",
|
||||
" |-----------------|--------|--------|\n",
|
||||
" | Полная (с взаимодействием) | 130.10 | 145.07 |\n",
|
||||
" | Аддитивная | 216.79 | 226.15 |\n",
|
||||
"\n",
|
||||
" - Разница $\\Delta AIC = 86.69$ и $\\Delta BIC = 81.08$ **явно указывает на преимущество полной модели**. \n",
|
||||
" - Аддитивная модель не учитывает взаимодействие, что приводит к потере информации.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"### 4. Нормальность остатков\n",
|
||||
"- **Тест Шапиро-Уилка:** \n",
|
||||
" $$p\\text{-value} = 0.949 \\implies \\text{гипотеза о нормальности остатков не отвергается}.$$\n",
|
||||
"- **Графическая проверка:** \n",
|
||||
" - Гистограмма остатков близка к нормальной форме. \n",
|
||||
" - Q-Q график показывает совпадение точек с линией $y = x$.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"- **Рекомендации:** \n",
|
||||
" Для прогнозирования $Y$ **необходимо учитывать взаимодействие** $A \\times B$, так как его игнорирование приведет к систематической ошибке.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"## Итоговый вывод\n",
|
||||
"1. **Полная модель с взаимодействием** предпочтительна по критериям AIC/BIC и объясняет данные лучше аддитивной. \n",
|
||||
"2. **Нормальность остатков** подтверждена тестами и графиками.\n",
|
||||
"\n",
|
||||
"**Рекомендации:** \n",
|
||||
"- Проверить данные на наличие выбросов для уровня $B=4$. \n",
|
||||
"- Использовать полную модель для прогнозирования и анализа эффектов."
|
||||
" - Полная модель **предпочтительнее**, так как она лучше соответствует данным, что подтверждается меньшими значениями AIC и BIC."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user