دسته بندی داده ها با پایتون — راهنمای کاربردی

در این مطلب، چندین الگوریتم «یادگیری ماشین» (Machine Learning) در «زبان برنامهنویسی پایتون» (Python Programming Language) با استفاده از کتابخانه «سایکیتلِرن» (Scikit-Learn) که یکی از محبوبترین کتابخانههای یادگیری ماشین است، پیادهسازی شدهاند. این الگوریتمها، برای «دستهبندی» (Classification) یک مجموعه داده برچسبدار از میوهها، مورد استفاده قرار گرفتهاند. در واقع، از یک مجموعه داده ساده، برای آموزش دادن «دستهبند» (Classifier) و تمایز ایجاد کردن بین انواع میوهها، استفاده شده است. هدف از این مطلب، شناسایی الگوریتم یادگیری ماشینی است که برای چنین مسالهای بالاترین صحت را ارائه میکند. بنابراین، الگوریتمهای گوناگون در ادامه با یکدیگر مقایسه میشوند و الگوریتمی با بهترین عملکرد، انتخاب میشود. با مطالعه این مطلب، میتوان با روشهای گوناگون دسته بندی داده ها با پایتون آشنا شد.
داده
مجموعه داده میوهها، توسط دکتر «لاین مورای» (Iain Murray) از «دانشگاه اِدینبرا» (University of Edinburgh) ساخته شده است. وی، مقادیر زیادی پرتقال، لیمو و سیب از گونههای گوناگون را تهیه و اندازههای آنها را در یک جدول ثبت کرده است.
سپس، اساتید دانشگاهی در «میشیگان» (Michigan)، دادههای میوهها را به تدریج قالببندی کردهاند. مجموعه داده نهایی حاصل شده از این فرایند را میتوان از اینجا [+] دانلود کرد. در ادامه، نگاهی به سطرهای اول این مجموعه داده انداخته میشود.
%matplotlib inline import pandas as pd import matplotlib.pyplot as plt fruits = pd.read_table('fruit_data_with_colors.txt') fruits.head()
هر سطر از مجموعه داده، نشانگر یک میوه به همراه «ویژگیهای» (Features) آن است. ۵۹ عدد نمونه (اطلاعات مربوط به ۵۹ میوه)، همراه با هفت ویژگی پیرامون آنها، در این مجموعه داده آورده شده است.
ورودی:
print(fruits.shape)
خروجی:
(59, 7)
چهار نوع میوه، در مجموعه داده وجود دارد (در واقع، با توجه به برچسبدار بودن مجموعه داده، چهار برچسب وجود دارد).
ورودی:
print(fruits['fruit_name'].unique())
خروجی:
[‘apple’ ‘mandarin’ ‘orange’ ‘lemon’]
دادهها به جز در مورد «پرتقال ماندارین» (Mandarin)، متوازن هستند (که البته میتوان با این مساله کنار آمد).
ورودی:
print(fruits.groupby('fruit_name').size())
ورودی:
import seaborn as sns sns.countplot(fruits['fruit_name'],label="Count") plt.show()
خروجی:
بصریسازی
نمودار جعبهای، برای هر متغیر عددی، ایدهای کلی از شیوه توزیع متغیرهای ورودی به دست میدهد.
ورودی:
fruits.drop('fruit_label', axis=1).plot(kind='box', subplots=True, layout=(2,2), sharex=False, sharey=False, figsize=(9,9), title='Box Plot for each input variable') plt.savefig('fruits_box') plt.show()
به نظر میرسد که امتیاز رنگ، دارای توزیعی نزدیک به «توزیع گاوسی» (Gaussian Distribution) است.
ورودی:
import pylab as pl fruits.drop('fruit_label' ,axis=1).hist(bins=30, figsize=(9,9)) pl.suptitle("Histogram for each numeric input variable") plt.savefig('fruits_hist') plt.show()
خروجی:
برخی از جفت ویژگیها، همبسته هستند (جرم و عرض). این امر موجب همبستگی بالا و رابطه قابل پیشبینی میشود.
ورودی:
from pandas.tools.plotting import scatter_matrix from matplotlib import cm feature_names = ['mass', 'width', 'height', 'color_score'] X = fruits[feature_names] y = fruits['fruit_label'] cmap = cm.get_cmap('gnuplot') scatter = pd.scatter_matrix(X, c = y, marker = 'o', s=40, hist_kwds={'bins':15}, figsize=(9,9), cmap = cmap) plt.suptitle('Scatter-matrix for each input variable') plt.savefig('fruits_scatter_matrix')
خلاصه آماری
میتوان مشاهده کرد که مقادیر عددی، دارای مقیاس یکسانی نیستند. بنابراین، نیاز به اعمال استانداردسازی مجموعه داده تست است؛ در اینجا باید همان روش استانداردسازی که برای مجموعه داده آموزش مورد استفاده قرار گرفته، روی مجموعه داده تست اعمال شود .
ساخت مجموعههای آموزش، تست و اعمال استانداردسازی
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0) from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test)
دسته بندی داده ها با پایتون
همانطور که پیشتر بیان شد، چندین مدل گوناگون روی مجموعه داده اعمال میشوند تا کارایی آنها سنجیده و صحت خروجی حاصل از هر یک از آنها، با دیگر الگوریتمها مقایسه شود. در نهایت، مدل با بهترین خروجی، انتخاب خواهد شد.
رگرسیون لجستیک
برای مطالعه بیشتر پیرامون الگوریتم «رگرسیون لجستیک» (Logistic Regression)، مطالعه مطلب «رگرسیون لجستیک در پایتون — راهنمای گام به گام»، توصیه میشود. در زیر، پیادهسازی این الگوریتم با استفاده از کتابخانه Scikit-Learn انجام شده است.
from sklearn.linear_model import LogisticRegression logreg = LogisticRegression() logreg.fit(X_train, y_train) print('Accuracy of Logistic regression classifier on training set: {:.2f}' .format(logreg.score(X_train, y_train))) print('Accuracy of Logistic regression classifier on test set: {:.2f}' .format(logreg.score(X_test, y_test)))
- صحت دستهبند رگرسیون لجستیک روی مجموعه داده آموزش: ۰.۷۰
- صحت دستهبند رگرسیون لجستیک روی مجموعه داده تست: ۰.۴۰
درخت تصمیم
برای مطالعه بیشتر پیرامون الگوریتم «درخت تصمیم» (Decision Tree)، مطالعه مطلب «درخت تصمیم با پایتون — راهنمای کاربردی» پیشنهاد میشود. در زیر، قطعه کد مربوط به اعمال این الگوریتم روی مجموعه داده میوهها، ارائه شده است.
from sklearn.tree import DecisionTreeClassifier clf = DecisionTreeClassifier().fit(X_train, y_train) print('Accuracy of Decision Tree classifier on training set: {:.2f}' .format(clf.score(X_train, y_train))) print('Accuracy of Decision Tree classifier on test set: {:.2f}' .format(clf.score(X_test, y_test)))
- صحت دستهبند درخت تصمیم روی مجموعه داده آموزش: 1.00
- صحت دستهبند درخت تصمیم، روی مجموعه داده تست: ۰.۷۳
K-نزدیکترین همسایگی
برای مطالعه بیشتر پیرامون الگوریتم «K-نزدیکترین همسایگی» (k-Nearest Neighbors | KNN)، مطالعه مطلب «الگوریتم K-نزدیکترین همسایگی به همراه کد پایتون» توصیه میشود. در ادامه، قطعه کد مربوط به اعمال الگوریتم KNN روی مجموعه داده میوهها، ارائه شده است.
from sklearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier() knn.fit(X_train, y_train) print('Accuracy of K-NN classifier on training set: {:.2f}' .format(knn.score(X_train, y_train))) print('Accuracy of K-NN classifier on test set: {:.2f}' .format(knn.score(X_test, y_test)))
- صحت دستهبندی KNN روی مجموعه داده آموزش: ۰.۹۵
- صحت دستهبندی KNN روی مجموعه تست: ۱.۰
آنالیز تشخیصی خطی
برای مطالعه بیشتر پیرامون الگوریتم «آنالیز تشخیصی خطی» (Linear Discriminant Analysis | LDA)، مطالعه مطلب «آنالیز تشخیصی خطی (LDA) در پایتون — راهنمای کاربردی» توصیه میشود.
در ادامه، الگوریتم LDA روی مجموعه داده میوه اعمال شده است.
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis lda = LinearDiscriminantAnalysis() lda.fit(X_train, y_train) print('Accuracy of LDA classifier on training set: {:.2f}' .format(lda.score(X_train, y_train))) print('Accuracy of LDA classifier on test set: {:.2f}' .format(lda.score(X_test, y_test)))
- صحت دستهبندی LDA روی مجموعه داده آموزش: ۰.۸۶
- صحت دستهبندی LDA روی مجموعه داده تست: ۰.۶۷
نایو بیز گاوسی
برای آشنایی بیشتر با الگوریتم «دستهبند بیز ساده» (Naive Bayes Classifiers)، مطالعه مطلب «دسته بند بیز ساده (Naive Bayes Classifiers) — مفاهیم اولیه و کاربردها» توصیه میشود. در ادامه، قطعه کد مربوط به اعمال الگوریتم نایو بیز گاوسی روی مجموعه داده میوهها ارائه شده است.
from sklearn.naive_bayes import GaussianNB gnb = GaussianNB() gnb.fit(X_train, y_train) print('Accuracy of GNB classifier on training set: {:.2f}' .format(gnb.score(X_train, y_train))) print('Accuracy of GNB classifier on test set: {:.2f}' .format(gnb.score(X_test, y_test)))
- صحت دستهبند نایو بیز گاوسی روی مجموعه آموزش: ۰.۸۶
- صحت دستهبند نایو بیز گاوسی روی مجموعه تست: ۰.۶۷
ماشین بردار پشتیبان
برای مطالعه بیشتر پیرامون الگوریتم «ماشین بردار پشتیبان» (Support Vector Machine | SVM)، مطالعه مطلب «ماشین بردار پشتیبان — به همراه کدنویسی پایتون و R» توصیه میشود.
در ادامه، پیادهسازی SVM با استفاده از کتابخانه سایکیتلرن انجام شده است.
from sklearn.svm import SVC svm = SVC() svm.fit(X_train, y_train) print('Accuracy of SVM classifier on training set: {:.2f}' .format(svm.score(X_train, y_train))) print('Accuracy of SVM classifier on test set: {:.2f}' .format(svm.score(X_test, y_test)))
- صحت دستهبند ماشین بردار پشتیبانی روی مجموعه آموزش: ۰.۶۱
- صحت دستهبند ماشین بردار پشتیبان روی مجموعه تست: ۰.۳۳
نتیجهگیری
همانطور که از صحتهای حاصل شده مشهود است، مدل KNN بالاترین خروجی را داشته است. «ماتریس درهم ریختگی» (Confusion Matrix) حاکی از عدم وجود هرگونه خطا در خروجی الگوریتم K-نزدیکترین همسایگی برای مجموعه داده تست است. اگرچه، مجموعه داده تست استفاده شده، خیلی کوچک محسوب میشود.
from sklearn.metrics import classification_report from sklearn.metrics import confusion_matrix pred = knn.predict(X_test) print(confusion_matrix(y_test, pred)) print(classification_report(y_test, pred))
ترسیم مرزهای دستهبندی برای دستهبند K-نزدیکترین همسایگی
import matplotlib.cm as cm from matplotlib.colors import ListedColormap, BoundaryNorm import matplotlib.patches as mpatches import matplotlib.patches as mpatches X = fruits[['mass', 'width', 'height', 'color_score']] y = fruits['fruit_label'] X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0) def plot_fruit_knn(X, y, n_neighbors, weights): X_mat = X[['height', 'width']].as_matrix() y_mat = y.as_matrix() # Create color maps cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF','#AFAFAF']) cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF','#AFAFAF']) clf = neighbors.KNeighborsClassifier(n_neighbors, weights=weights) clf.fit(X_mat, y_mat) # Plot the decision boundary by assigning a color in the color map # to each mesh point. mesh_step_size = .01 # step size in the mesh plot_symbol_size = 50 x_min, x_max = X_mat[:, 0].min() - 1, X_mat[:, 0].max() + 1 y_min, y_max = X_mat[:, 1].min() - 1, X_mat[:, 1].max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max, mesh_step_size), np.arange(y_min, y_max, mesh_step_size)) Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) # Put the result into a color plot Z = Z.reshape(xx.shape) plt.figure() plt.pcolormesh(xx, yy, Z, cmap=cmap_light) # Plot training points plt.scatter(X_mat[:, 0], X_mat[:, 1], s=plot_symbol_size, c=y, cmap=cmap_bold, edgecolor = 'black') plt.xlim(xx.min(), xx.max()) plt.ylim(yy.min(), yy.max()) patch0 = mpatches.Patch(color='#FF0000', label='apple') patch1 = mpatches.Patch(color='#00FF00', label='mandarin') patch2 = mpatches.Patch(color='#0000FF', label='orange') patch3 = mpatches.Patch(color='#AFAFAF', label='lemon') plt.legend(handles=[patch0, patch1, patch2, patch3]) plt.xlabel('height (cm)') plt.ylabel('width (cm)') plt.title("4-Class classification (k = %i, weights = '%s')" % (n_neighbors, weights)) plt.show() plot_fruit_knn(X_train, y_train, 5, 'uniform')
k_range = range(1, 20) scores = [] for k in k_range: knn = KNeighborsClassifier(n_neighbors = k) knn.fit(X_train, y_train) scores.append(knn.score(X_test, y_test)) plt.figure() plt.xlabel('k') plt.ylabel('accuracy') plt.scatter(k_range, scores) plt.xticks([0,5,10,15,20])
برای این مجموعه داده، بالاترین صحت هنگامی حاصل میشود که مقدار K در الگوریتم KNN برابر با پنج (k=5) تعیین شده است.
خلاصه
در این مطلب، الگوریتمهای دستهبندی گوناگون با استفاده از کتابخانه سایکیتلرن پیادهسازی و روی یک مجموعه داده برچسبدار (مجموعه داده میوهها) اعمال شدند. سپس، صحت نتایج حاصل از هر یک از الگوریتمها با دیگر موارد مقایسه شد. در واقع، در این بررسی موردی روی صحت پیشبینیها تمرکز شده و هدف، یافتن مدلی بود که صحت خوبی داشته باشد. چنین مدلی، صحت پیشبینی را بیشینه میسازد. در نهایت، الگوریتم یادگیری ماشینی که بهترین خروجی را برای مساله بیان شده داشت (دستهبندی انواع میوهها)، یعنی KNN، شناسایی شد. کدهای استفاده شده برای این پروژه، در گیتهاب [+] موجود هستند.
اگر مطلب بالا برای شما مفید بوده، آموزشهای زیر نیز به شما پیشنهاد میشود:
- مجموعه آموزشهای دادهکاوی و یادگیری ماشین
- مجموعه آموزشهای دادهکاوی یا Data Mining در متلب
- مجموعه آموزشهای هوش مصنوعی
- زبان برنامهنویسی پایتون (Python) — از صفر تا صد
- یادگیری ماشین با پایتون — به زبان ساده
- آموزش یادگیری ماشین با مثالهای کاربردی — مجموعه مقالات جامع وبلاگ فرادرس
- چگونه یک دانشمند داده شوید؟ — راهنمای گامبهگام به همراه معرفی منابع
^^
خیلی ب دردم خورد دمتون گرم