Программа для оценки успеваемости студентов на основе нечеткой кластеризации
Алгоритмы предобработки данных. Методы, модели кластеризации и ее метрики. Постановка задачи оценки выбора методов успеваемости студентов. Сравнение регрессионных алгоритмов. Интерфейс программного продукта. Обоснование выбора среды программирования.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 01.09.2018 |
Размер файла | 4,1 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
В первую очередь необходимо загрузить данные, проверить их на полноту и заполнить пропуски в случае наличия таковых. Для этого выполним следующий скрипт:
import pandas as pd
data = pd.read_csv('edudat.csv')
sum(pd.isnull(data)[pd.isnull(data)==True].count())
В результате оказалось, что изучаемый датасет не имеет признаки и мы можем перейти к предобработке данных. Как уже писалось в теоретических аспектах предобработки, необходимо найти все признаки, значения которых имеют текстовый тип и преобразовать их в численный:
data['gender']=data['gender'].replace(['Female','Male'],[0,1])
data['singlepa']=data['singlepa'].replace(['no','yes'],[0,1])
data['fsm']=data['fsm'].replace(['no','yes'],[0,1])
data['parasp']=data['parasp'].replace(['No','Yes'],[0,1])
data['computer']=data['computer'].replace(['No','Yes'],[0,1])
data['tuition']=data['tuition'].replace(['No','Yes'],[0,1])
data['pupasp']=data['pupasp'].replace(['No','Yes'],[0,1])
data['sen']=data['sen'].replace(['No','Yes'],[0,1])
data['truancy']=data['truancy'].replace(['No','Yes'],[0,1])
data['absent']=data['absent'].replace(['No','Yes'],[0,1])
data['house']=data['house'].replace(['rented','owned'],[0,1])
data['hiquamum']=data['hiquamum'].replace(['Degree or equivalent','GCE A Level or equivalent','GCSE grades A-C or equiv','HE below degree level','No qualification','Other qualifications'],[0,1,2,3,4,5])
data['sec']=data['sec'].replace(['Intermediate','Managerial.Professional','Semi.Routine.Unemployed','Small.Self.employed'],[0,1,2,3])
data['asc']=data['asc'].replace(['high', 'low', 'very high', 'very low'],[3,2,4,1])
Ввиду того, что большинство алгоритмов машинного обучения не могут работать с категориальными признаками, которые не являются бинарными, найдём все такие и выполним кодировку методом one-hot, который в библиотеке pandas имеет название get_dummies. Предварительно выделим такие признаки:
features_cat = ['ethnic','asc','sec','hiquamum','fsmband']
data = pd.get_dummies(data, columns=features_cat, prefix=features_cat)
На этом предобработку данных можно считать законченной, и мы можем переходить к регрессионному анализу вновь полученной таблицы с данными.
3.2 Сравнение регрессионных алгоритмов
Начать регрессионный анализ следует с разделения всей выборки на тренировочную и обучающую. Для наибольшей эффективности принято брать разбиение 70% на 30% в пользу обучающей. Для того, чтобы избежать возможных тенденций в связи с особой сортировкой таблиц, сгенерируем псевдослучайные натуральные числа от 1 до размера всей выборки (в нашем случае 8273) в количестве округлённого до целого произведения 0.3 на 8273. И, уже исходя из полученных значений, сгенерируем соответствующие выборки:
import numpy as np
np.random.seed(20)
indices = np.random.choice(data.shape[0], (data.shape[0] // 10)*3, replace=False)
train_data = data.drop(indices)
test_data = data.iloc[indices]
train_answers=train_data['ks4score']
test_labels=test_data['ks4score']
del train_data['ks4score']
del test_data['ks4score']
Получив необходимые выборки, следует указать, что в качестве метрики полученных в будущем моделей, будем использовать абсолютную ошибку регрессии. Начнём обучение с наиболее простых моделей, которые затрачивают на это минимальное время. К таким моделям можно отнести линейную регрессию и все модификации таковой. Обучим линейную регрессию со всеми имеющимися признаками. Для этого необходимо использовать библиотеку sklearn:
LR = lm.LinearRegression()
LR.fit(train_data, train_answers)
y_pred_lr = LR.predict(test_data)
print(np.sum(np.abs((y_pred_lr) test_labels))/y_pred_lr.shape[0])
Время на обучение можно считать близким к нулю ввиду простоты модели. Абсолютная ошибка модели составила 66,062. Также для линейных моделей принято использовать метрику. В данном случае она составила 0,603. Также для выделения важных признаков можно сделать обзор текущей модели.
Для этого используем библиотеку statsmodels:
import statsmodels.api as sm
X2 = sm.add_constant(test_data)
est = sm.OLS(test_labels, X2)
est2 = est.fit()
print(est2.summary())
Результаты получились следующие (Рис 15):
Рис 15. Статистика линейной регрессии.
Исходя из p-value по каждому признаку, выделим те признаки, которые удовлетворяют 95% доверительному интервалу. Переопределим сгенерированные выборки исходя из нового списка переменных:
features3=['ks3score','homework','asc','sen','truancy',
'gender','singlepa','pupasp','absent','house']
x_train3=data[features3].drop(indices)
y_train3=data['ks4score'].drop(indices)
x_test3=data[features3].iloc[indices]
y_test3=data['ks4score'].iloc[indices]
Вновь создадим линейную регрессию и проведём обзор модели (Рис 16).
Рис 16. Статистика второй линейной регрессии.
получился высоким - 0.954, абсолютная ошибка модели выросла до 66,488. Проверим на новых признаках модифицированные линейные модели - Ridge и Lasso. После подбора соответствующих параметров получаем модель, близкую к оптимальной:
Ridge_best = lm.Ridge(alpha=60, fit_intercept=True,max_iter=1000,solver ='auto')
Ridge_best.fit(x_train3, y_train3)
pred_rb=Ridge_best.predict(x_test3)
print (np.sum(np.abs(pred_rb - y_test3))/pred_rb.shape[0] )
Для ridge регрессии абсолютная ошибка оказалась - 66
Lasso_best = lm.Lasso(alpha=50, fit_intercept=True,max_iter=1200,solver ='auto')
Lasso_best.fit(x_train3, y_train3)
pred_rb=Lasso_best.predict(x_test3)
print (np.sum(np.abs(pred_rb - y_test3))/pred_rb.shape[0] )
Для lasso регрессии абсолютная ошибка оказалась - 66,51.
В итоге делаем вывод, что из самых простых моделей самая лучшая оказалась Ridge регрессия с соответствующими признаками.
Далее, попробуем обучить полином. Ввиду того, что данные более-менее однородные, нет смысл обучать модель степени выше 3. Плюс ко всему, время, затраченное на обучение, будет несравнимо выше с линейными моделями. Применяя библиотеку sklearn.preprocessing получаем:
import sklearn.preprocessing as pp
poly=pp.PolynomialFeatures(2)
X_new_2= poly.fit_transform(train_data)
LR2 = lm.LinearRegression()
LR2.fit(X_new_2, train_answers)
y_pred2=LR2.predict(X_new_2)
print (np.sum(np.abs((yp) - test_labels))/yp.shape[0])
Абсолютная ошибка модели составила 67, 92.
После этого попробуем построить регрессионную модель опорных векторов. Перебора параметров SVM дал следующие результаты:
from sklearn import svm
sv = svm.SVR(C=45.0,degree=7)
sv.fit(train_data,train_answers)
predict_svr=sv.predict(test_data)
print(np.sum(np.abs((predict_svr)test_labels))/predict_svr.shape[0])
Абсолютная ошибка модели на тестовой выборке составили 66,49.
Далее, из списка теоретически описанных регрессоров шёл решающий лес. Поскольку в этой модели также имеется большое количество параметров, здесь я представлю самый близкий к оптимальному из всех перебранных. Самым точным стало дерево с максимальной глубиной в 5 листьев:
from sklearn.tree import DecisionTreeRegressor
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_2.fit(train_data,train_answers)
predict_dt2=regr_2.predict(test_data)
print(np.sum(np.abs((predict_dt2)-test_labels))/predict_dt2.shape[0] )
По выбранной метрике ошибка составила 68,72.
Перейдём к самым современным библиотекам анализа данных. Xgboost и Catboost требует очень тщательного подбора параметров. В связи с этим также проводился постоянный перебор свойств будущих моделей для создания идеальной. В результате, наиболее точной моделью экстремального градиентного бустинга от Google стала модель с параметрами max_depth=6, learning_rate=0.13, n_estimators=100:
import xgboost as xgb
xr = xgb.XGBRegressor(max_depth=12, learning_rate=0.11, n_estimators=150)
xr.fit(train_data,train_answers)
predict_xgb=xr.predict(test_data)
print (np.sum(np.abs((predict_xgb) - test_labels))/predict_xgb.shape[0])
Для схожей модели от Яндекса был выполнен следующий скрипт:
from catboost import Pool, CatBoostRegressor
train_pool = Pool(x_train2, y_train2)
test_pool = Pool(x_test2)
cbr = CatBoostRegressor(iterations=450,
learning_rate=0.025,
depth=4,
l2_leaf_reg=2)
cbr.fit(train_pool)
pred_cbr=cbr.predict(test_pool)
print (np.sum(np.abs(pred_cbr - y_test2))/pred_cbr.shape[0] )
Вообще говоря, оказалось, что catboost оказался гораздо более чувствителен к параметрам своей модели, чем xgboost, поэтому несмотря на долгий и аналитический перебор, получить модель лучше, чем модель от Google не получилось. Ошибки модели оказались следующие:
· XGBoost - 65,1
· CatBoost - 66,01
В итоге, получилось, что модель XGBoost с точки зрения выбранной метрики выглядит самой привлекательной. Однако время, использованное для обучения несравнимо больше. Мы решили точнее измерить скорость формирования модели с оптимальными параметрами:
import time
start_time = time.clock()
xr = xgb.XGBRegressor(max_depth=12, learning_rate=0.11, n_estimators=150)
xr.fit(train_data,train_answers)
predict_xgb=xr.predict(test_data)
print ((time.clock() - start_time)/60, "min")
Получилось, что процесс занял чуть более половины минуты по сравнению с мгновенным у линейной регрессии. Разница колоссальная, учитывая, что пользователь может для обучения использовать данные в гораздо больших масштабах, чем в этом исследовании. По меркам больших данных восемь тысяч объектов - маленькая величина. Поэтому решили узнать, может в данной модели есть незначительные признаки, которые возможно удалить ради экономии времени:
from matplotlib import pyplot
from xgboost import plot_importance
plot_importance(xr)
pyplot.show()
Получили график важности каждого признака (Рис 17):
Рис 17. График важности признаков модели XGBoost.
Как можно видеть, никаких скачков в важности тех признаков, что имеют низкий F score, нет. Поэтому, удаление переменных приведёт к серьёзному ухудшению модели.
Исходя из всего регрессионного анализа, можно сделать вывод о том, что наименьшую ошибку показала модель экстремального градиентного бустинга, но она была не на столько меньше, чем у линейной модели, чтобы игнорировать разницу во времени обучения на пару порядков. Поэтому для дальнейшего выделения вектора весов было принято использовать линейную модель с регуляризацией L2 (Ridge).
3.3 Построение модели кластеризации
Как уже было сказано в главе «Постановка задачи с выбранными методами», для дальнейшего процесса кластеризации нам необходим вектор весов. В предыдущей главе мы выяснили, что самой релевантной моделью регрессии для изучаемого датасета стала линейная регрессия с Ridge регуляризацией. Вспомнив, что лучшая модель имела не все исходные признаки, получим вектор весов из этой модели и сделаем его нормировку в пределах от -1 до 1:
weight=Ridge_best3.coef_
max=abs(weight).max()
min=abs(weight).min()
weight_norm=np.sign(weight)*(np.sqrt(np.power(weight,2)-np.power(min,2)))/(np.sqrt(np.power(max,2)-np.power(min,2)))
Далее, необходимо применить норму весов для каждого признака. Для непрерывных это будет простое умножение на соответствующее значение. Для категориальных - норма весов разделить на 2, для бинарных - норма весов разделить на корень квадратный из 2. Производя такие действия, мы делаем предположение о том, что два бинарных признака отличаются сильнее, чем два категориальных.
data_cl = pd.read_csv('edudat.csv')
x_cluster=x_train3.append(x_test3)
x_cluster['asc_veryhigh']=data_cl['asc'].replace(['very low','low','high','very high'],[0,0,0,weight_norm[2]/2])
x_cluster['asc_high']=data_cl['asc'].replace(['very low','low','high','very high'],[0,0,weight_norm[2]/2,0])
x_cluster['asc_low']=data_cl['asc'].replace(['very low','low','high','very high'],[0,weight_norm[2]/2,0,0])
x_cluster['asc_verylow']=data_cl['asc'].replace(['very low','low','high','very high'],[weight_norm[2]/2,0,0,0])
del x_cluster['asc']
x_cluster['ks3score']=(data_cl['ks3score']-data_cl['ks3score'].min())/(data_cl['ks3score'].max()-data_cl['ks3score'].min())*weight_norm[0]
x_cluster['homework']=data_cl['homework']
x_cluster['homework_0']=data_cl['homework'].replace([0,1,2,3,4,5],[weight_norm[1]/2,0,0,0,0,0])
x_cluster['homework_1']=data_cl['homework'].replace([0,1,2,3,4,5],[0,weight_norm[1]/2,0,0,0,0])
x_cluster['homework_2']=data_cl['homework'].replace([0,1,2,3,4,5],[0,0,weight_norm[1]/2,0,0,0])
x_cluster['homework_3']=data_cl['homework'].replace([0,1,2,3,4,5],[0,0,0,weight_norm[1]/2,0,0])
x_cluster['homework_4']=data_cl['homework'].replace([0,1,2,3,4,5],[0,0,0,0,weight_norm[1]/2,0])
x_cluster['homework_5']=data_cl['homework'].replace([0,1,2,3,4,5],[0,0,0,0,0,weight_norm[1]/2])
del x_cluster['homework']
x_cluster['gender']=data_cl['gender'].replace(['Female','Male'],[0,weight_norm[5]/np.sqrt(2)])
x_cluster['singlepa']=data_cl['singlepa'].replace(['no','yes'],[0,weight_norm[6]/np.sqrt(2)])
x_cluster['pupasp']=data_cl['pupasp'].replace(['No','Yes'],[0,weight_norm[7]/np.sqrt(2)])
x_cluster['sen']=data_cl['sen'].replace(['No','Yes'],[0,weight_norm[3]/np.sqrt(2)])
x_cluster['truancy']=data_cl['truancy'].replace(['No','Yes'],[0,weight_norm[4]/np.sqrt(2)])
x_cluster['absent']=data_cl['absent'].replace(['No','Yes'],[0,weight_norm[8]/np.sqrt(2)])
x_cluster['house']=data_cl['house'].replace(['rented','owned'],[0,weight_norm[9]/np.sqrt(2)])
После приведения данных в вид, где значение каждого признака лежит на промежутке от 1 до -1, необходимо для наглядности визуализировать данные. Разумеется, мы не может построить N-мерный график, если количество признаков выше 3. В данном случае с учётом выделения бинарных из категориальных признаков, всего их 18. Применяя метод выделения главных компонент, построим график всех объектов в двухмерном пространстве.
from sklearn.decomposition import PCA
reduced_data = PCA(n_components=2).fit_transform(x_cluster)
xpts = reduced_data[:, 0]
ypts = reduced_data[:, 1]
fig0, ax0 = plt.subplots()
for label in range(16):
ax0.plot(xpts,ypts, '.')
Получаем следующую визуализацию объектов (Рис 18):
Рис 18. Графическое отображение нормированных объектов.
Далее, когда увидели, как весь массив объектов выглядит на графике, можно переходить к процессу кластеризации. Визуально кажется, что оптимальным количеством кластеров будет являться 8. Выполним кластеризацию методом K-means для понимания расположения кластеров:
h=0.2
x_min, x_max = reduced_data[:, 0].min() - 1, reduced_data[:, 0].max() + 1
y_min, y_max = reduced_data[:, 1].min() - 1, reduced_data[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
Z = kmeans.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.figure(1)
plt.clf()
plt.imshow(Z, interpolation='nearest',
extent=(xx.min(), xx.max(), yy.min(), yy.max()),
cmap=plt.cm.Paired,
aspect='auto', origin='lower')
plt.plot(reduced_data[:, 0], reduced_data[:, 1], 'k.', markersize=2)
centroids = kmeans.cluster_centers_
plt.scatter(centroids[:, 0], centroids[:, 1],
marker='x', s=100, linewidths=3,
color='white', zorder=5)
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.xticks(())
plt.yticks(())
plt.show()
Получили следующий график (Рис 19):
Рис 19. Графическое отображение объектов покластерно.
Центры кластеров оказались не совсем там, где можно было предположить изначально. Плюс ко всему, библиотека, в которой реализован метод K-means, не имеет никаких особых метрик, описывающих оптимальное количество кластеров для изучаемых данных. Поэтому следует обратиться к нечётким алгоритмам, точнее к C-means. Самый точный находится в библиотеке skfuzzy, написанной специально для нечёткой кластеризации. Главная метрика этого алгоритма в данной библиотеке - FPC (The fuzzy partition coefficient). В документации к этой библиотеке сказано, что этот коэффициент определяет насколько точно описывается конкретная модель, что находится в диапазоне от 0 до 1, где 1 - идеальный случай. Соответственно, опираясь на эту метрику и графическое отображение объектов, построим некоторые модели кластеризации. В качестве пробы решено было взять с 4, 8, 16 и 32 кластерами:
import skfuzzy as fuzz
colors = ['b', 'orange', 'g', 'r', 'c', 'm', 'y', 'k', 'Brown', 'ForestGreen',
'tab:olive', 'tab:cyan', 'tab:orange', 'tab:green', 'tab:pink', 'tab:gray']
fig1, axes1 = plt.subplots(2, 2, figsize=(8, 8))
alldata = np.vstack((xpts, ypts))
fpcs = []
i=(axes1.reshape(-1))
counter=1
for ncenters, ax in enumerate(axes1.reshape(-1), 4):
cntr, u, u0, d, jm, p, fpc = fuzz.cluster.cmeans(
alldata, (len(i))*counter, 2, error=0.005, maxiter=1000, init=None)
clstrs=(len(i))*counter
counter=counter*2
fpcs.append(fpc)
point in training set
cluster_membership = np.argmax(u, axis=0)
for j in range(clstrs):
ax.plot(xpts[cluster_membership == j],
ypts[cluster_membership == j], '.', color=colors[j])
for pt in cntr:
ax.plot(pt[0], pt[1], 'rs')
ax.set_title('Clusters = {0}; FPC = {1:.2f}'.format(clstrs, fpc))
ax.axis('off')
fig1.tight_layout()
Результат получается следующим (Рис 20):
Рис 20. Графическое отображение объектов для 4,8,16 и 32 кластеров.
Чёткой картины это вновь не дало, поэтому стоит найти оптимальное количество кластеров. Для этого обучим модель несколько раз с разным количеством центров. Было решено, что перебор моделей начнётся с 5 кластеров, так как меньшее количество малоинформативное, и закончится 20 центрами, ввиду отсутствия большого количества значимых признаков:
xpts = reduced_data[:, 0]
ypts = reduced_data[:, 1]
alldata = np.vstack((xpts, ypts))
fpcs_all = []
clust_num = []
for ncenters in range (5,20):
cntr, u, u0, d, jm, p, fpc = fuzz.cluster.cmeans(
alldata, ncenters, 2, error=0.005, maxiter=1000, init=None)
fpcs_all.append(fpc)
clust_num.append(ncenters)
После этого можно наглядно посмотреть, как зависит коэффициент FPC от количества кластеров (Рис 21):
fig2, ax2 = plt.subplots()
ax2.plot(np.r_[5:20], fpcs_all)
ax2.set_xlabel("Number of centers")
ax2.set_ylabel("Fuzzy partition coefficient")
Рис 21. График точностей нечёткой кластеризации.
Отсюда хорошо видно, что оптимальное количество центров для исследуемого массива данных - 6. При этом модель имеет коэффициент точности - 0.875
Создание модели нечёткой кластеризации решает одну важную задачу: перед построением итогового графика мы можем отсеять все те объекты, максимальная принадлежность к кластеру которого менее 60%. Иными словами, мы утверждаем, что объект не может наверняка быть принадлежными к какому-либо кластеру. Для этого следует взять матрицу принадлежности U, которая была получена в результате работы соответствующего алгоритма выбранной библиотеки, и пометить все те объекты, которые не подходят под вышеописанное условие. Помимо этого, обозначим все такие объекты в исходной матрице как не имеющие кластер:
cl = np.transpose(u)
mass = []
bads=[]
for i in range(cl.shape[0]):
max0 = cl[i].max()
if max0>=0.60:
for j in range(cl.shape[1]):
if cl[i][j] == max0:
mass.append(j+1)
else:
mass.append("No cluster")
bads.append(i)
Теперь можем обучить модель с оптимальным количеством кластеров (в данном случае, 6) и вывести её график с учётом условия, описанного выше. Например, пометим «плохие» объекты серым цветом (Рис 22):
cluster_membership = np.argmax(u, axis=0)
for j in range(opt):
plt.plot(xpts[cluster_membership == j],
ypts[cluster_membership == j], '.', color=colors[j])
plt.plot(xpts[bads], ypts[bads], '.', color='tab:gray')
for pt in cntr:
plt.plot(pt[0], pt[1], 'rs')
fig1.tight_layout()
Рис 22. Визуализация вместе с «плохими» объектами
Итак, в результате кластерного анализа мы получили идеальную C-means модель для исследуемых данных с долей достоверности принадлежности в 60%. После этого можно переходить к написанию интерфейса программы.
3.4 Интерпретация результатов
После проведённого кластерного анализа следует понять, а что вообще эти кластеры значат, и какие именно ученики описываются каждым классом. Для этого можно пойти двумя путями:
· Построить решающее дерево для описания процесса разбиения кластеров
· Вычислить центры кластеров и описать свойства наиболее близких объектов к ним
Для построения дерева найдём все те кластеры, которые оказались ближе всего к объектам после выполненного алгоритма нечёткой кластеризации. После этого воспользуемся классификатором решающего дерева для поиска тех переменных, по условиям которых объекты начинают делиться на разные группы. В качестве основного параметра разбиения было задано минимальное количество объектов в одном листе - 150. При таком количестве получается высокая точность классификатора, и дерево не перегружено информацией, сложной для визуального восприятия. Для демонстрации дерева воспользуемся библиотекой graphviz:
import graphviz
import os
from sklearn import tree
from io import StringIO
clf2 = tree.DecisionTreeClassifier(min_samples_leaf=150)
clf2 = clf2.fit(asd, mass)
out = StringIO()
ert = ["No cluster","1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
"20"]
with open("classifier.dot", "w") as f:
f = tree.export_graphviz(clf2, out_file=f, filled=True, class_names=ert, rounded=True,
special_characters=True)
(graph,) = pydot.graph_from_dot_file("classifier.dot")
В результате получим дерево разбиения объектов исходя из условий соответствующих переменных (Рис 23):
Рис 23. Дерево решений кластеризованных объектов.
Например, из части дерева, который представлен ниже, можно сказать, что кластер под номером 6 зависит от переменных(Рис 24).
Рис 24. Часть решающего дерева.
Для исследуемых данных переменная - gender, - pupasp, - ks3score. Иными словами, представители шестой группы учеников - девушки, которые не хотят получать высшее образование и имеют оценку за предыдущую стадию обучения ниже 28,895.
Другим способом интерпретации полученных кластеров может служить оценка объекта, который наиболее близок к центру самого кластера. Для поиска таких учеников будем использовать матрицу принадлежности модели нечёткой кластеризации, выполненной с оптимальным количеством центров:
cntrs=[]
for i in range(u.shape[0]):
max1=u[i].max()
for j in range(u.shape[1]):
if u[i][j]==max1:
cntrs.append(j)
break
Исходя из значений признаков, которые в линейной регрессионной модели были выделены, как важные, произведём описание каждого кластера по каждой переменной (для экономии места аналогичный по структуре с другими переменными код был заменён на «***»):
colors = ['b', 'orange', 'g', 'r', 'c', 'm', 'y', 'k', 'Brown', 'ForestGreen','tab:olive', 'tab:cyan', 'tab:orange', 'tab:green', 'tab:pink', 'tab:gray']
k = 0
f = open("interp.txt", "w")
for i in cntrs:
k = k + 1
cls = "Cluster %s " % k
cls = cls + "(%s): " % (colors[k - 1])
if asd.iloc[i]['gender'] == 0: cls = cls + "This is a girl, "
if asd.iloc[i]['gender'] == 1: cls = cls + "This is a boy, "
if asd.iloc[i]['asc'] == 1: cls = cls + "attitude towards schools was very bad,
if asd.iloc[i]['asc'] == 2: cls = cls + "attitude towards schools was bad, "
if asd.iloc[i]['asc'] == 3: cls = cls + "attitude towards schools was good, "
if asd.iloc[i]['asc'] == 4: cls = cls + "attitude towards schools was very good,
if asd.iloc[i]['house'] == 0: cls = cls + "his family had rented house and "
if asd.iloc[i]['house'] == 1: cls = cls + "his family had owned house and "
cls = cls + "his average ks3score is %s" % asd.iloc[i]['ks3score']
f.write(cls + '\n')
f.close()
В результате работы данного скрипта получился текстовый файл со следующими результатами:
Cluster 1 (b): This is a boy, attitude towards schools was very bad, pupil spent 3 hours per week doing homework, he didn't need the special conditions, didn't skip classes, This is not the only one child in the family, he wanted the higher education, he was absent more than month, his family had owned house and his average ks3score is 35.62
Cluster 2 (orange): This is a girl, attitude towards schools was bad, pupil spent 4 hours per week doing homework, he didn't need the special conditions, didn't skip classes, This is not the only one child in the family, he wanted the higher education, he was absent more than month, his family had owned house and his average ks3score is 41.19
Cluster 3 (g): This is a boy, attitude towards schools was good, pupil spent 5 hours per week doing homework, he didn't need the special conditions, didn't skip classes, This is the only one child in the family, he didn't want the higher education, he wasn't absent more than month, his family had owned house and his average ks3score is 39.64
Cluster 4 (r): This is a girl, attitude towards schools was good, pupil spent 3 hours per week doing homework, he didn't need the special conditions, skipped classes, This is not the only one child in the family, he wanted the higher education, he wasn't absent more than month, his family had rented house and his average ks3score is 36.33
Cluster 5 (c): This is a boy, attitude towards schools was good, pupil spent 1 hours per week doing homework, he didn't need the special conditions, skipped classes, This is not the only one child in the family, he wanted the higher education, he wasn't absent more than month, his family had rented house and his average ks3score is 32.71
Cluster 6 (m): This is a girl, attitude towards schools was very good, pupil spent 0 hours per week doing homework, he didn't need the special conditions, skipped classes. This is not the only one child in the family, he didn't want the higher education, he wasn't absent more than month, his family had rented house and his average ks3score is 28.02
Как мы можем видеть на примере шестого кластера, результаты получились похожими у обоих методов. Скорее всего, это группа девочек, которая не хочет получать высшее образование, и их ks3score балл варьируется в районе 28 пунктов.
3.5 Интерфейс программного продукта
Ввиду того, что выбранной платформой для реализации интерфейса был JetBrains PyCharm, будем использовать встроенную библиотеку для реализации графического интерфейса - Tkinter. Выделим основные элементы, которые должны быть в приложении:
· Стартовое меню загрузки csv файла
· Основное окно со списком отчётов
· Окно с двухмерным графическим отображением кластерного анализа
· Окно с просмотром таблицы объектов с информацией о степени принадлежности к кластерам
· Интерпретация полученных результатов
· Дерево разбиения каждого кластера
· Окно с возможностью загрузки результатов в csv формате в любую директорию на компьютере
Исходя из требований был разработан дизайн стартового окна приложения (Рис 25):
Рис 25. Дизайн стартового окна.
Дизайн основного меню (Рис 26):
Рис 26. Основное меню.
Дизайн окна с графиком (Рис 27):
Рис 27. Окно графической интерпретации.
Дизайн окна с деревом разбиения кластеризации (Рис 28):
Рис 28. Окно с деревом решений.
Вот так выглядит окно с сходным содержанием данных вместе с вероятностями принадлежности к кластерам:
Рис 29. Окно с содержанием данных.
Для текстовой интерпретации полученных результатов будем использовать следующее окно (Рис 30):
Рис 30. Окно с интерпретацией кластеров.
Окно с выбором пути сохранения csv файла выглядит, как обычный проводник в Windows. Для сохранения нужно лишь выбрать путь, где будет находиться файл outputdata.csv (Рис 31):
Рис 31. Окно выбора места сохранения файла.
Выводы
Была решена главная цель - выделены те признаки, которые сильнее всего влияют на успеваемость студентов. Проведя регрессионный и кластерный анализ, мы смогли получить близкую к идеальной визуальную интепретацию самых важных параметров жизни человека, от которых зависит успешность его образования.
Заключение
В ходе проделанной исследовательской работы были получены следующие основные результаты:
1. Было произведено изучение предметной области жизни студентов и их успеваемости. Выяснилось, каким наборов признаков обладает каждый из молодых людей, какого типа имелись переменные. Большинство характеристик - категории, чаще всего бинарные.
2. Результатом теоретического анализа регрессионных алгоритмов и методов кластеризации стало понимание, какие из них лучше всего подходят под данную предметную область.
3. Результатом проведённого регрессионного анализа в оптимальном смысле стала линейная функция с ridge регуляризацией. Ввиду относительной простоты и быстрого времени обучения, модель имела высокий показатель по метрике, который оказался равен 0.954. Показатель абсолютной ошибки был незначительно выше, чем у более сложных и долгих алгоритмов обучения (XGBoost), поэтому было принято справедливое решение об использовании этого метода в качестве оптимального регрессора исследуемых данных.
4. Была построена оптимальная модель нечёткой кластеризации, основанная на алгоритме C-means, которая выявила и описала 6 оптимальных кластеров изучаемых данных с коэффициентом точности FPC = 0,88.
5. Была разработана программа, вместе с её интерфейсом, в которой были реализованы все части исследовательского проекта, которая настроена под анализ любого датафрейма, имеющего схожую структуру с данным. В пользовательском функционале была разработана возможность просмотреть срез алгоритма кластеризации в виде двухмерного графика, изучить дерево построения кластеров по основным признакам, просмотреть исходную таблицу с данными с проявившими значениями степени принадлежности к каждому кластеру и сохранить её у себя в локальном формате.
6. Главным результатом стало выделение признаков, которые сильнее всего влияют на успеваемость (по убыванию):
· оценка за экзамен за предыдущую образовательную стадию;
· количество часов, которое тратит ученик на выполнение домашнего задания
· отношение к школе
· желание получать дальнейшее образование
· наличие прогулов за год
· отсутствовал ли ребёнок больше месяца за последний год
· имеет ли полную семью
· социально-экономический статус студента
· имеет ли собственный дом
· пол
Таким образом, задачи решены в полном объёме, исходная цель по выделению главных характеристик была достигнута. Полученные результаты могут дать почву для более глубинного исследования параметров и мотиваций подростков в дальнейших диссертационных работах.
Список литературы
1. Дрейпер Н., Смит Г. Прикладной регрессионный анализ. Издательский дом «Вильямс». 2007. 912 с.
2. P. Zhao, B. Yu. On Model Selection Consistency of Lasso // Journal of Machine Learning Research, V. 7, 2006, pp. 2541-2563.
3. Стрижов В. В. Методы индуктивного порождения регрессионных моделей. М.: ВЦ РАН. 2008. 55 с
4. Gunn, S. Support Vector Machines for Classification and Regression. ISIS Technical Report ISIS-1-98. Image Speech & Intelligent Systems Research Group, University of Southampton, U.K, 2008.
5. Левитин А. В. Глава 10. Ограничения мощи алгоритмов: Деревья принятия решения // Алгоритмы. Введение в разработку и анализ -- М.: Вильямс, 2006. -- С. 409-417. -- 576 с.
6. Chen, Tianqi; Carlos Guestrin XGBoost: A Scalable Tree Boosting System. CoRR., 2016.
7. Журавлев Ю. И., Рязанов В. В., Сенько О. В. Распознавание. // Математические методы. Программная система. Практические применения. -- М.: Фазис, 2006.
8. Amorim, R.C.; Hennig, C. Recovering the number of clusters in data sets with noise features using feature rescaling factors // Information Sciences, 2015. С. 126-145.
9. F. Hoppner, F. Klawonn, R. Kruse, T. Runkler. Fuzzy Cluster Analysis.1999. Wiley, Chichester.
10. J. C. Bezdek, J. M. Keller, R. Krishnapuram and N. R. Pal. Fuzzy Models and Algorithms for Pattern Recognition and Image Processing, 1999, Springer
11. Официальный сайт библиотеки SciPy.
12. Официальный сайт библиотеки XGBoost
13. Официальный сайт библиотеки CatBoost
Приложение 1
Иллюстрация дерева решений кластеризации
Приложение 2
алгоритм кластеризация интерфейс программирование
Размещено на Allbest.ru
Подобные документы
- Разработка системы учета успеваемости студентов на основе рейтинговой системы - подсистема "Кафедра"
Проектировка и создание системы, направленной на упразднение трудной и рутинной работы преподавателей, за счет централизованного хранения данных об успеваемости студентов и удобного доступа к ним. Средства реализации и тестирование программного средства.
курсовая работа [1,3 M], добавлен 28.08.2012 Основы для проведения кластеризации. Использование Data Mining как способа "обнаружения знаний в базах данных". Выбор алгоритмов кластеризации. Получение данных из хранилища базы данных дистанционного практикума. Кластеризация студентов и задач.
курсовая работа [728,4 K], добавлен 10.07.2017Сущность и понятие кластеризации, ее цель, задачи, алгоритмы; использование искусственных нейронных сетей для кластеризации данных. Сеть Кохонена, самоорганизующиеся нейронные сети: структура, архитектура; моделирование кластеризации данных в MATLAB NNT.
дипломная работа [3,1 M], добавлен 21.03.2011Методика разработки объектно-ориентированной модели информационной подсистемы необходимой для учета успеваемости студентов факультета, которая спроектирована с помощью программного продукта Rational Rose 2003 и унифицированного языка моделирования UML.
курсовая работа [183,9 K], добавлен 25.06.2011Требования к пользовательским интерфейсам, к аппаратным, программным и коммуникационным интерфейсам, к пользователям продукта. Проектирование структуры приложения для самоконтроля успеваемости студентов. Программные средства эксплуатации приложения.
курсовая работа [561,9 K], добавлен 28.08.2019Анализ проблем, возникающих при применении методов и алгоритмов кластеризации. Основные алгоритмы разбиения на кластеры. Программа RapidMiner как среда для машинного обучения и анализа данных. Оценка качества кластеризации с помощью методов Data Mining.
курсовая работа [3,9 M], добавлен 22.10.2012Комбинированный тип данных для хранения входных данных о студентах и информация, содержащаяся в полях. Пример структуры входных и выходных данных. Алгоритм работы и программный код программы по успеваемости студентов, описание используемых функций.
курсовая работа [135,9 K], добавлен 28.12.2012База данных по всем занимающимся студентам, электронный журнал посещаемости и успеваемости, средства подсчета статистики и подготовки документов. Ввод из журнала оценок и посещаемости студентов, составление ведомостей. Формирование табеля успеваемости.
курсовая работа [1,7 M], добавлен 11.05.2012Решение задачи средствами прикладных программ. Разработка алгоритмов и структур данных. Реализация задачи определения статистических данных по успеваемости на факультете на языке программирования C#. Программа перевода чисел в различные системы счисления.
курсовая работа [519,9 K], добавлен 03.01.2015Методы проектирования информационных систем. Обоснование выбора способа соединения с БД. Приёмы работы с СУБД Access и языком SQL. Логическая и физическая модели базы данных. Формы просмотра, редактирования и ввода данных. Алгоритм работы приложения.
курсовая работа [4,6 M], добавлен 24.06.2015