[ad_1]
Tất cả chúng ta đều cần lấy mẫu dân số của mình để thực hiện Phân tích thống kê và có được hiểu biết sâu sắc. Khi chúng ta làm như vậy, mục đích là để đảm bảo rằng sự phân bố mẫu của chúng ta khớp chặt chẽ với sự phân bố của dân số.
Để làm được điều này, chúng ta có nhiều phương pháp khác nhau: phương pháp lấy mẫu ngẫu nhiên đơn giản (nơi mọi thành viên của dân số đều có cơ hội được lựa chọn như nhau), lấy mẫu phân tầng (bao gồm việc chia dân số thành các nhóm nhỏ và lấy mẫu từ mỗi nhóm nhỏ), lấy mẫu theo cụm (nơi dân số được chia thành các cụm và toàn bộ các cụm được chọn ngẫu nhiên), Lấy mẫu hệ thống (bao gồm việc lựa chọn mọi thành viên thứ n của dân số), v.v. Mỗi phương pháp đều có những ưu điểm riêng và được lựa chọn dựa trên nhu cầu và đặc điểm cụ thể của nghiên cứu.
Trong bài viết này, chúng tôi sẽ không tập trung vào các phương pháp lấy mẫu riêng lẻ mà sẽ tập trung vào việc sử dụng các khái niệm này để chia tập dữ liệu được sử dụng cho các phương pháp học máy thành Đào tạo-Kiểm tra-Xác thực bộ. Những cách tiếp cận này có hiệu quả với tất cả các loại Dữ liệu dạng bảng. Chúng ta sẽ làm việc bằng Python ở đây.
Dưới đây là một số cách tiếp cận mà bạn có thể đã biết:
Cách tiếp cận này sử dụng lấy mẫu ngẫu nhiên phương pháp.
Mã ví dụ:
from sklearn.model_selection import train_test_split
# Assuming X is your characteristic set and y is your goal variable
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.4, random_state=42)
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)
Cách tiếp cận này đảm bảo rằng các phần tách ra duy trì cùng tỷ lệ các lớp học như tập dữ liệu gốc (tất nhiên là với việc lấy mẫu ngẫu nhiên một lần nữa), điều này hữu ích cho các tập dữ liệu mất cân bằng. Cách tiếp cận này sẽ hiệu quả khi biến mục tiêu của bạn là không phải là biến liên tục.
from sklearn.model_selection import train_test_split# Stratified cut up to take care of class distribution
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.4, stratify=y, random_state=42)
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, stratify=y_temp, random_state=42)
Trong xác thực chéo Okay-Fold, tập dữ liệu được chia thành ok
tập hợp con (nếp gấp). Mô hình được đào tạo trên k-1
gấp lại và thử nghiệm trên nếp gấp còn lại. Quá trình này được lặp lại ok
lần.
from sklearn.model_selection import KFold, train_test_splitkf = KFold(n_splits=5, shuffle=True, random_state=42)
for train_index, test_index in kf.cut up(X):
X_train, X_test = X(train_index), X(test_index)
y_train, y_test = y(train_index), y(test_index)
# Additional cut up X_train and y_train into prepare and validation units
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=42)
# Now you've gotten X_train, X_val, X_test, y_train, y_val, y_test for every fold
# Now you can prepare and consider your mannequin utilizing these units
Đúng như tên gọi, đây là sự kết hợp giữa lấy mẫu phân tầng và xác thực chéo Okay lần.
from sklearn.model_selection import StratifiedKFold, train_test_splitskf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
for train_index, test_index in skf.cut up(X, y):
X_train, X_test = X(train_index), X(test_index)
y_train, y_test = y(train_index), y(test_index)
# Additional cut up X_train and y_train into prepare and validation units
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, stratify=y_train, random_state=42)
# Now you've gotten X_train, X_val, X_test, y_train, y_val, y_test for every fold
# Now you can prepare and consider your mannequin utilizing these units
Ví dụ sử dụng đầy đủ:
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score# Initialize lists to retailer the scores for every fold
accuracy_scores = ()
precision_scores = ()
recall_scores = ()
f1_scores = ()
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
for train_index, test_index in skf.cut up(X, y): #y is a categorical goal variable
X_train, X_test = X(train_index), X(test_index)
y_train, y_test = y(train_index), y(test_index)
# Additional cut up X_train and y_train into prepare and validation units
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, stratify=y_train, random_state=42)
# Practice the mannequin
mannequin = LogisticRegression(random_state=42)
mannequin.match(X_train, y_train)
# Validate the mannequin
y_val_pred = mannequin.predict(X_val)
val_accuracy = accuracy_score(y_val, y_val_pred)
val_precision = precision_score(y_val, y_val_pred, common='weighted')
val_recall = recall_score(y_val, y_val_pred, common='weighted')
val_f1 = f1_score(y_val, y_val_pred, common='weighted')
print(f"Validation Scores - Accuracy: {val_accuracy}, Precision: {val_precision}, Recall: {val_recall}, F1 Rating: {val_f1}")
# Take a look at the mannequin
y_test_pred = mannequin.predict(X_test)
test_accuracy = accuracy_score(y_test, y_test_pred)
test_precision = precision_score(y_test, y_test_pred, common='weighted')
test_recall = recall_score(y_test, y_test_pred, common='weighted')
test_f1 = f1_score(y_test, y_test_pred, common='weighted')
# Retailer the scores
accuracy_scores.append(test_accuracy)
precision_scores.append(test_precision)
recall_scores.append(test_recall)
f1_scores.append(test_f1)
print(f"Take a look at Scores - Accuracy: {test_accuracy}, Precision: {test_precision}, Recall: {test_recall}, F1 Rating: {test_f1}")
# Calculate and print the common scores throughout all folds
print(f"nAverage Take a look at Scores throughout all folds - Accuracy: {sum(accuracy_scores) / len(accuracy_scores)}, Precision: {sum(precision_scores) / len(precision_scores)}, Recall: {sum(recall_scores) / len(recall_scores)}, F1 Rating: {sum(f1_scores) / len(f1_scores)}")
Bây giờ, bạn có thể sử dụng các phương pháp này để chia tách tập dữ liệu của mình nhưng chúng có những đặc điểm sau: những hạn chế:
- Phân chia ngẫu nhiên Practice-Take a look at-Val: Phương pháp này không thể đảm bảo tương tự phân phối giữa các phần tách, đặc biệt nếu tập dữ liệu không đủ lớn hoặc nếu có sự mất cân bằng trong biến mục tiêu.
- Phân chia theo tầng: Phương pháp này chỉ hữu ích khi bạn có không liên tục biến mục tiêu (y). Mặc dù có những giải pháp thay thế cho các biến mục tiêu liên tục (chẳng hạn như chuyển đổi biến liên tục thành biến phân loại thông qua một số điều kiện, ví dụ, nếu y ≥ tứ phân vị1 → 1, nếu không thì 0), những cách tiếp cận này vẫn không phải lúc nào cũng đảm bảo phân phối tương tự giữa các phần chia.
Bây giờ, giả sử bạn có một bé nhỏ tổng số quan sát trong tập dữ liệu của bạn và rất khó để đảm bảo phân phối tương tự giữa các phần chia tách của bạn. Trong trường hợp đó, bạn có thể kết hợp phân cụm Và lấy mẫu ngẫu nhiên (hoặc lấy mẫu phân tầng).
Dưới đây là cách tôi đã làm nó cho vấn đề của tôi trong tầm tay:
Trong phương pháp này, trước tiên, chúng tôi phân cụm tập dữ liệu của mình và sau đó sử dụng phương pháp lấy mẫu trên mỗi cụm để có được dữ liệu phân chia.
Ví dụ, sử dụng HDBSCAN:
import hdbscan
from sklearn.metrics import silhouette_score
from sklearn.model_selection import ParameterGrid
import random
random.seed(48) #for regeneration of similar outcomesdef get_clusters(df):
to_drop =("cluster_", "ID")
req_cols = sorted(set(df.columns) - set(to_drop))
X = df(req_cols) #preserve solely required columns in X
X_std = X.values #no want of scaling the coaching set for HDBSCAN
# Outline parameter grid for HDBSCAN, you may play with this grid accordingly
param_grid = {
'min_cluster_size': record(vary(2,20))
#'min_samples': (1, 2, 3)
}
best_score = -1
best_params = None
# Iterate over parameter grid
for params in ParameterGrid(param_grid):
mannequin = hdbscan.HDBSCAN(**params, gen_min_span_tree=True)
cluster_labels = mannequin.fit_predict(X_std)
unique_labels = np.distinctive(cluster_labels)
if len(unique_labels) > 1: # Test if multiple cluster is fashioned
silhouette_avg = silhouette_score(X_std, cluster_labels) if len(unique_labels) > 1 else -1
if silhouette_avg > best_score:
best_score = silhouette_avg
best_params = params
if best_params just isn't None:
print(best_params)
best_model = hdbscan.HDBSCAN(**best_params, gen_min_span_tree=True)
cluster_labels = best_model.fit_predict(X_std) #get cluster labels from finest mannequin
df("cluster_") = (str(i) for i in cluster_labels)
else:
print("HDBSCAN produced just one cluster label. Unable to separate the information.")
df("cluster_") = "0" #when no clusters are discovered
return df
Bạn cũng có thể sử dụng các phương pháp phân cụ khác tùy theo vấn đề của mình, ví dụ: Phân cụm Okay-Means:
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from sklearn.preprocessing import StandardScaler
from yellowbrick.cluster import KElbowVisualizerdef get_clusters(df):
to_drop =("cluster_", "ID")
req_cols = sorted(set(df.columns) - set(to_drop))
X = df(req_cols).values #preserve solely required columns in X
scaler = StandardScaler()
X_std = scaler.fit_transform(X) #scaling is required in case of Okay-Means
mannequin = KMeans()
visualizer = KElbowVisualizer(mannequin, ok=(2, 50)) #you may play with the vary accordingly
visualizer.match(X_std)
#visualizer.present()
optimal_n_clusters = visualizer.elbow_value_ #utilizing elbow technique to get optimum no. of clusters
kmeans = KMeans(n_clusters=optimal_n_clusters, random_state=42)
kmeans.match(X_std)
clust_labels = (str(i) for i in kmeans.labels_)
# Consider the clustering utilizing silhouette rating
silhouette_avg = silhouette_score(X_std, clust_labels)
df("cluster_") = clust_labels
return df
Bây giờ bạn cũng có thể thêm mức độ chi tiết (bất kỳ biến phân loại nào) vào tập dữ liệu của bạn để có được các cụm được tinh chỉnh hơn như sau:
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from sklearn.preprocessing import StandardScaler
from yellowbrick.cluster import KElbowVisualizerdef get_clusters(df):
# taking animal categorical variable as a degree of granularity to separate on
grp1 = df.loc((df('animal')=='cat'))
grp2 = df.loc((df('animal')=='canine'))
temps = ()
for num, temp in enumerate((grp1, grp2)):
to_drop =("cluster_", "ID")
final_cols = sorted(set(temp.columns) - set(to_drop))
X = temp(final_cols)
X = X.values
scaler = StandardScaler()
X_std = scaler.fit_transform(X) #scaling of variables is required for Okay-Means clustering
mannequin = KMeans()
visualizer = KElbowVisualizer(mannequin, ok=(2, 50))
visualizer.match(X_std)
# visualizer.present()
#get optimum no. of clusters, Okay utilizing elbow technique
optimal_n_clusters = visualizer.elbow_value_
kmeans = KMeans(n_clusters=optimal_n_clusters, random_state=42)
kmeans.match(X_std)
clust_labels = (str(num) + "_" + str(i) for i in kmeans.labels_)
# Consider the clustering utilizing silhouette rating
silhouette_avg = silhouette_score(X_std, clust_labels)
temp("cluster_") = clust_labels
temps.append(temp)
df = pd.concat(temps, axis=1)
return df
Một khi bạn đã có được nhãn cụm từ bất kỳ phương pháp phân cụm nào, bạn có thể sử dụng lấy mẫu ngẫu nhiên hoặc lấy mẫu phân tầng để chọn mẫu từ mỗi cụm.
Chúng tôi sẽ chọn các chỉ số ngẫu nhiên và sau đó sử dụng các chỉ số này để chọn các tập huấn luyện-kiểm tra-giá trị như sau:
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split# Assuming df is your DataFrame, "cluster_" is the column with cluster labels,
unique_clusters = df("cluster_").distinctive()
train_indices = ()
val_indices = ()
test_indices = ()
for cluster in unique_clusters:
cluster_data = df(df("cluster_") == cluster)
cluster_indices = cluster_data.index.values
cluster_y = cluster_data('y').values
if stratify_ == True: #when you've got categorical goal variable
train_idx, temp_idx, _, temp_y = train_test_split(cluster_indices, cluster_y, test_size=0.4, stratify=cluster_y, random_state=42)
val_idx, test_idx = train_test_split(temp_idx, test_size=0.5, stratify=temp_y, random_state=42)
else:
# Break up indices of the present cluster into prepare and temp (which will probably be additional cut up into val and check)
train_idx, temp_idx = train_test_split(cluster_indices, test_size=0.4, random_state=42)
val_idx, test_idx = train_test_split(temp_idx, test_size=0.5, random_state=42)
train_indices.prolong(train_idx)
val_indices.prolong(val_idx)
test_indices.prolong(test_idx)
# Convert the indices lists to numpy arrays
train_indices = np.array(train_indices)
val_indices = np.array(val_indices)
test_indices = np.array(test_indices)
# Assuming 'X' are the options and 'y' is the goal column
X = df.drop(columns=('y', 'cluster_')).values
y = df('y').values
# Choose the corresponding information for prepare, validation, and check units
X_train, y_train = X(train_indices), y(train_indices)
X_val, y_val = X(val_indices), y(val_indices)
X_test, y_test = X(test_indices), y(test_indices)
Theo trường hợp sử dụng của tôiviệc sắp xếp biến mục tiêu y của tôi và sau đó chọn mọi thứ là hữu ích 1, 2 và 3 chỉ số cho tập huấn luyện, thử nghiệm và xác thực tương ứng (tất cả đều loại trừ lẫn nhau), hay còn gọi là lấy mẫu ngẫu nhiên có hệ thống như sau:
def get_indices(df):
np.random.seed(seed=48)total_length = len(df)
sample1_length = int(0.60 * total_length) #you may select proportion accordingly
remaining_length = total_length - sample1_length
sample2_length = int(remaining_length / 2)
sample3_length = total_length - (sample1_length + sample2_length)
#create an array with vary 0 - size of the df
all_indxs = np.array(vary(total_length))
# Create arrays of indices divisible by 2 and three completely
indices_divisible_by_2 = np.array(record(set(np.the place(all_indxs % 2 == 0)(0)) - set(np.the place(all_indxs % 6 == 0)(0))))
indices_divisible_by_3 = np.array(record(set(np.the place(all_indxs % 3 == 0)(0)) - set((0))))
#randomly select indices divisibly by 2 with sample2_length
sample2_indices = sorted(indices_divisible_by_2(np.random.selection(len(indices_divisible_by_2), measurement=sample2_length, substitute=False)))
strive:
sample3_indices = sorted(indices_divisible_by_3(np.random.selection(len(indices_divisible_by_3), measurement=sample3_length, substitute=False)))
besides:
sample3_indices = ()
sample1_indices = sorted(set(all_indxs) - set(sample2_indices) - set(sample3_indices))
return sample1_indices, sample2_indices, sample3_indices
indices_train = ()
indices_test = ()
indices_val = ()for num, cluster in enumerate(df('cluster_').distinctive()):
temp_df = df(df('cluster_') == cluster)
sample1_indices, sample2_indices, sample3_indices = get_indices(temp_df)
indices_train.append(record(temp_df.iloc(sample1_indices).index))
indices_test.append(record(temp_df.iloc(sample2_indices).index))
indices_val.append(record(temp_df.iloc(sample3_indices).index))
# to flatten the record of lists containing indices for prepare,check,val set
indices_train = (x for xs in indices_train for x in xs)
indices_test = (x for xs in indices_test for x in xs)
indices_val = (x for xs in indices_val for x in xs)
def traintestvalsplit(df, id_col, cols_to_drop, cont_var, train_indices, test_indices, val_indices):prepare, check, val = df.loc(train_indices), df.loc(test_indices), df.loc(val_indices)
# Break up the information into prepare, validation, and check units based mostly on indices
X_train = prepare.drop(cols_to_drop + (cont_var) ,axis=1) #add which columns to drop
X_test = check.drop(cols_to_drop + (cont_var) ,axis=1)
X_val = val.drop(cols_to_drop + (cont_var) ,axis=1)
y_train = prepare((cont_var)) #goal variable
y_test = check((cont_var))
y_val = val((cont_var))
train_ids = prepare((id_col)) #to protect the IDs
test_ids = check((id_col))
val_ids = val((id_col))
print("Practice set measurement:", X_train.form, len(train_ids))
print("Take a look at set measurement:", X_test.form, len(test_ids))
print("Validation set measurement:", X_val.form, len(val_ids))
return X_train, X_val, X_test, y_train, y_val, y_test, train_ids, val_ids, test_ids
X_train, X_val, X_test, y_train, y_val, y_test, train_ids, val_ids, test_ids = traintestvalsplit(df, id_col, cols_to_drop, cont_var, train_indices, test_indices, val_indices)
Các phương pháp kết hợp phân cụ với các phương pháp lấy mẫu khác nhau được thảo luận ở trên rất hữu ích khi bạn có số lượng quan sát nhỏ trong tập dữ liệu của mình vì chúng đảm bảo duy trì sự phân phối tương tự giữa các tập Huấn luyện, Kiểm tra và Xác thực.
Cảm ơn bạn đã đọc và hy vọng bạn thấy bài viết này hữu ích!
[ad_2]
Source link