บ่อยครั้งที่ผู้คนที่เข้าสู่สาขา Data Science มีความคาดหวังที่รออยู่น้อยกว่าความเป็นจริง หลายคนคิดว่าตอนนี้พวกเขาจะเขียนโครงข่ายประสาทเทียมเจ๋งๆ สร้างผู้ช่วยด้านเสียงจาก Iron Man หรือเอาชนะทุกคนในตลาดการเงิน
แต่ทำงาน ข้อมูล นักวิทยาศาสตร์ขับเคลื่อนด้วยข้อมูล และแง่มุมหนึ่งที่สำคัญและใช้เวลานานที่สุดคือการประมวลผลข้อมูลก่อนที่จะป้อนเข้าสู่โครงข่ายประสาทเทียมหรือวิเคราะห์ด้วยวิธีใดวิธีหนึ่ง
ในบทความนี้ ทีมของเราจะอธิบายวิธีที่คุณสามารถประมวลผลข้อมูลได้อย่างรวดเร็วและง่ายดายพร้อมคำแนะนำและโค้ดทีละขั้นตอน เราพยายามทำให้โค้ดค่อนข้างยืดหยุ่นและสามารถนำไปใช้กับชุดข้อมูลที่แตกต่างกันได้
มืออาชีพหลายคนอาจไม่พบสิ่งพิเศษในบทความนี้ แต่ผู้เริ่มต้นจะสามารถเรียนรู้สิ่งใหม่ ๆ และใครก็ตามที่ใฝ่ฝันมานานแล้วว่าจะสร้างสมุดบันทึกแยกต่างหากเพื่อการประมวลผลข้อมูลที่รวดเร็วและมีโครงสร้างสามารถคัดลอกโค้ดและจัดรูปแบบเองหรือ
เราได้รับชุดข้อมูลแล้ว จะทำอย่างไรต่อไป?
ดังนั้น มาตรฐาน เราต้องเข้าใจสิ่งที่เรากำลังเผชิญ ภาพรวมโดยรวม ในการทำเช่นนี้ เราใช้แพนด้าเพื่อกำหนดประเภทข้อมูลที่แตกต่างกัน
import pandas as pd #импортируем pandas
import numpy as np #импортируем numpy
df = pd.read_csv("AB_NYC_2019.csv") #читаем датасет и записываем в переменную df
df.head(3) #смотрим на первые 3 строчки, чтобы понять, как выглядят значения
df.info() #Демонстрируем информацию о колонках
ลองดูค่าของคอลัมน์:
- จำนวนบรรทัดในแต่ละคอลัมน์ตรงกับจำนวนบรรทัดทั้งหมดหรือไม่
- สาระสำคัญของข้อมูลในแต่ละคอลัมน์คืออะไร?
- เราต้องการกำหนดเป้าหมายคอลัมน์ใดเพื่อคาดการณ์คอลัมน์นั้น
คำตอบสำหรับคำถามเหล่านี้จะช่วยให้คุณสามารถวิเคราะห์ชุดข้อมูลและวางแผนคร่าวๆ สำหรับการดำเนินการต่อไปของคุณได้
นอกจากนี้ หากต้องการดูค่าในแต่ละคอลัมน์ให้ละเอียดยิ่งขึ้น เราสามารถใช้ฟังก์ชัน pandas อธิบาย() ได้ อย่างไรก็ตาม ข้อเสียของฟังก์ชันนี้คือไม่มีข้อมูลเกี่ยวกับคอลัมน์ที่มีค่าสตริง เราจะจัดการกับพวกเขาในภายหลัง
df.describe()
การสร้างภาพมหัศจรรย์
มาดูกันว่าเราไม่มีค่าตรงไหนเลย:
import seaborn as sns
sns.heatmap(df.isnull(),yticklabels=False,cbar=False,cmap='viridis')
นี่เป็นเพียงการมองจากด้านบนสั้นๆ ตอนนี้เราจะไปยังสิ่งที่น่าสนใจเพิ่มเติมกัน
ลองค้นหาและถ้าเป็นไปได้ให้ลบคอลัมน์ที่มีค่าเพียงค่าเดียวในทุกแถว (จะไม่ส่งผลต่อผลลัพธ์ แต่อย่างใด):
df = df[[c for c
in list(df)
if len(df[c].unique()) > 1]] #Перезаписываем датасет, оставляя только те колонки, в которых больше одного уникального значения
ตอนนี้เราปกป้องตนเองและความสำเร็จของโครงการของเราจากบรรทัดที่ซ้ำกัน (บรรทัดที่มีข้อมูลเดียวกันในลำดับเดียวกันกับหนึ่งในบรรทัดที่มีอยู่):
df.drop_duplicates(inplace=True) #Делаем это, если считаем нужным.
#В некоторых проектах удалять такие данные с самого начала не стоит.
เราแบ่งชุดข้อมูลออกเป็นสองชุด: ชุดหนึ่งมีคุณค่าเชิงคุณภาพ และอีกชุดหนึ่งมีคุณค่าเชิงปริมาณ
ที่นี่เราต้องชี้แจงให้กระจ่าง: หากบรรทัดที่มีข้อมูลที่ขาดหายไปในข้อมูลเชิงคุณภาพและเชิงปริมาณไม่มีความสัมพันธ์กันมากนัก เราจะต้องตัดสินใจว่าจะเสียสละอะไร - บรรทัดทั้งหมดที่มีข้อมูลที่ขาดหายไป เพียงบางส่วนเท่านั้น หรือบางคอลัมน์ หากเส้นมีความสัมพันธ์กัน เรามีสิทธิ์ทุกประการที่จะแบ่งชุดข้อมูลออกเป็นสองส่วน มิฉะนั้น คุณจะต้องจัดการกับบรรทัดที่ไม่สัมพันธ์กับข้อมูลที่ขาดหายไปทั้งในเชิงคุณภาพและเชิงปริมาณ จากนั้นจึงแบ่งชุดข้อมูลออกเป็นสองส่วนเท่านั้น
df_numerical = df.select_dtypes(include = [np.number])
df_categorical = df.select_dtypes(exclude = [np.number])
เราทำเช่นนี้เพื่อให้การประมวลผลข้อมูลสองประเภทที่แตกต่างกันนี้ง่ายขึ้น - หลังจากนั้นเราจะเข้าใจว่าสิ่งนี้ทำให้ชีวิตของเราง่ายขึ้นเพียงใด
เราทำงานกับข้อมูลเชิงปริมาณ
สิ่งแรกที่เราควรทำคือพิจารณาว่ามี "คอลัมน์สายลับ" ในข้อมูลเชิงปริมาณหรือไม่ เราเรียกคอลัมน์เหล่านี้ว่าเนื่องจากนำเสนอตัวเองเป็นข้อมูลเชิงปริมาณ แต่ทำหน้าที่เป็นข้อมูลเชิงคุณภาพ
เราจะระบุได้อย่างไร? แน่นอนว่าทุกอย่างขึ้นอยู่กับลักษณะของข้อมูลที่คุณกำลังวิเคราะห์ แต่โดยทั่วไปแล้วคอลัมน์ดังกล่าวอาจมีข้อมูลที่ไม่ซ้ำกันเพียงเล็กน้อย (ในพื้นที่ของค่าที่ไม่ซ้ำกัน 3-10 ค่า)
print(df_numerical.nunique())
เมื่อเราระบุคอลัมน์สายลับแล้ว เราจะย้ายพวกมันจากข้อมูลเชิงปริมาณไปเป็นข้อมูลเชิงคุณภาพ:
spy_columns = df_numerical[['колонка1', 'колока2', 'колонка3']]#выделяем колонки-шпионы и записываем в отдельную dataframe
df_numerical.drop(labels=['колонка1', 'колока2', 'колонка3'], axis=1, inplace = True)#вырезаем эти колонки из количественных данных
df_categorical.insert(1, 'колонка1', spy_columns['колонка1']) #добавляем первую колонку-шпион в качественные данные
df_categorical.insert(1, 'колонка2', spy_columns['колонка2']) #добавляем вторую колонку-шпион в качественные данные
df_categorical.insert(1, 'колонка3', spy_columns['колонка3']) #добавляем третью колонку-шпион в качественные данные
สุดท้ายนี้ เราได้แยกข้อมูลเชิงปริมาณออกจากข้อมูลเชิงคุณภาพอย่างสมบูรณ์ และตอนนี้เราก็สามารถทำงานกับข้อมูลดังกล่าวได้อย่างถูกต้องแล้ว สิ่งแรกคือการทำความเข้าใจว่าเรามีค่าว่างอยู่ที่ไหน (NaN และในบางกรณี 0 จะถือเป็นค่าว่าง)
for i in df_numerical.columns:
print(i, df[i][df[i]==0].count())
ณ จุดนี้ สิ่งสำคัญคือต้องเข้าใจว่าคอลัมน์ใดที่เป็นศูนย์อาจบ่งบอกถึงค่าที่หายไป สาเหตุมาจากวิธีการรวบรวมข้อมูลหรือไม่ หรืออาจเกี่ยวข้องกับค่าข้อมูล? คำถามเหล่านี้จะต้องตอบเป็นกรณีไป
ดังนั้น หากเรายังตัดสินใจว่าเราอาจสูญเสียข้อมูลที่มีศูนย์ เราควรแทนที่ศูนย์ด้วย NaN เพื่อให้ง่ายต่อการทำงานกับข้อมูลที่สูญหายในภายหลัง:
df_numerical[["колонка 1", "колонка 2"]] = df_numerical[["колонка 1", "колонка 2"]].replace(0, nan)
ตอนนี้เรามาดูกันว่าข้อมูลที่เราขาดหายไปอยู่ที่ไหน:
sns.heatmap(df_numerical.isnull(),yticklabels=False,cbar=False,cmap='viridis') # Можно также воспользоваться df_numerical.info()
ที่นี่ค่าเหล่านั้นในคอลัมน์ที่หายไปควรทำเครื่องหมายเป็นสีเหลือง และตอนนี้ความสนุกก็เริ่มต้นขึ้น - จะจัดการกับค่านิยมเหล่านี้อย่างไร? ฉันควรลบแถวที่มีค่าหรือคอลัมน์เหล่านี้หรือไม่ หรือเติมค่าว่างเหล่านี้ด้วยค่าอื่น?
ต่อไปนี้เป็นแผนภาพโดยประมาณที่สามารถช่วยคุณตัดสินใจได้ว่าตามหลักการแล้ว สิ่งใดที่สามารถทำได้โดยใช้ค่าว่าง:
0. ลบคอลัมน์ที่ไม่จำเป็นออก
df_numerical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)
1. จำนวนค่าว่างในคอลัมน์นี้มากกว่า 50% หรือไม่?
print(df_numerical.isnull().sum() / df_numerical.shape[0] * 100)
df_numerical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)#Удаляем, если какая-то колонка имеет больше 50 пустых значений
2. ลบบรรทัดที่มีค่าว่าง
df_numerical.dropna(inplace=True)#Удаляем строчки с пустыми значениями, если потом останется достаточно данных для обучения
3.1. การแทรกค่าแบบสุ่ม
import random #импортируем random
df_numerical["колонка"].fillna(lambda x: random.choice(df[df[column] != np.nan]["колонка"]), inplace=True) #вставляем рандомные значения в пустые клетки таблицы
3.2. การแทรกค่าคงที่
from sklearn.impute import SimpleImputer #импортируем SimpleImputer, который поможет вставить значения
imputer = SimpleImputer(strategy='constant', fill_value="<Ваше значение здесь>") #вставляем определенное значение с помощью SimpleImputer
df_numerical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_numerical[['колонка1', 'колонка2', 'колонка3']]) #Применяем это для нашей таблицы
df_numerical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True) #Убираем колонки со старыми значениями
3.3. ใส่ค่าเฉลี่ยหรือค่าที่ใช้บ่อยที่สุด
from sklearn.impute import SimpleImputer #импортируем SimpleImputer, который поможет вставить значения
imputer = SimpleImputer(strategy='mean', missing_values = np.nan) #вместо mean можно также использовать most_frequent
df_numerical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_numerical[['колонка1', 'колонка2', 'колонка3']]) #Применяем это для нашей таблицы
df_numerical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True) #Убираем колонки со старыми значениями
3.4. แทรกค่าที่คำนวณโดยรุ่นอื่น
บางครั้งค่าสามารถคำนวณได้โดยใช้แบบจำลองการถดถอยโดยใช้แบบจำลองจากไลบรารี sklearn หรือไลบรารีอื่นที่คล้ายคลึงกัน ทีมงานของเราจะอุทิศบทความแยกต่างหากเกี่ยวกับวิธีการทำเช่นนี้ในอนาคตอันใกล้นี้
ดังนั้น สำหรับตอนนี้ การบรรยายเกี่ยวกับข้อมูลเชิงปริมาณจะถูกขัดจังหวะ เนื่องจากมีความแตกต่างอื่นๆ มากมายเกี่ยวกับวิธีการจัดเตรียมข้อมูลและการประมวลผลล่วงหน้าสำหรับงานต่างๆ ที่ดีขึ้น และสิ่งพื้นฐานสำหรับข้อมูลเชิงปริมาณได้ถูกนำมาพิจารณาในบทความนี้ด้วย และ ตอนนี้ถึงเวลากลับไปสู่ข้อมูลเชิงคุณภาพซึ่งเราแยกจากข้อมูลเชิงปริมาณไปหลายขั้นตอนแล้ว คุณสามารถเปลี่ยนสมุดบันทึกนี้ได้ตามต้องการ โดยปรับให้เข้ากับงานต่างๆ เพื่อให้การประมวลผลข้อมูลล่วงหน้าดำเนินไปอย่างรวดเร็ว!
ข้อมูลเชิงคุณภาพ
โดยพื้นฐานแล้ว สำหรับข้อมูลเชิงคุณภาพ วิธีการเข้ารหัสแบบ One-hot-encoding ใช้เพื่อจัดรูปแบบจากสตริง (หรืออ็อบเจ็กต์) เป็นตัวเลข ก่อนที่จะไปยังจุดนี้ ลองใช้ไดอะแกรมและโค้ดด้านบนเพื่อจัดการกับค่าว่าง
df_categorical.nunique()
sns.heatmap(df_categorical.isnull(),yticklabels=False,cbar=False,cmap='viridis')
0. ลบคอลัมน์ที่ไม่จำเป็นออก
df_categorical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True)
1. จำนวนค่าว่างในคอลัมน์นี้มากกว่า 50% หรือไม่?
print(df_categorical.isnull().sum() / df_numerical.shape[0] * 100)
df_categorical.drop(labels=["колонка1","колонка2"], axis=1, inplace=True) #Удаляем, если какая-то колонка
#имеет больше 50% пустых значений
2. ลบบรรทัดที่มีค่าว่าง
df_categorical.dropna(inplace=True)#Удаляем строчки с пустыми значениями,
#если потом останется достаточно данных для обучения
3.1. การแทรกค่าแบบสุ่ม
import random
df_categorical["колонка"].fillna(lambda x: random.choice(df[df[column] != np.nan]["колонка"]), inplace=True)
3.2. การแทรกค่าคงที่
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='constant', fill_value="<Ваше значение здесь>")
df_categorical[["новая_колонка1",'новая_колонка2','новая_колонка3']] = imputer.fit_transform(df_categorical[['колонка1', 'колонка2', 'колонка3']])
df_categorical.drop(labels = ["колонка1","колонка2","колонка3"], axis = 1, inplace = True)
ในที่สุดเราก็จัดการกับค่าว่างในข้อมูลเชิงคุณภาพได้ ตอนนี้ได้เวลาทำการเข้ารหัสแบบร้อนแรงกับค่าที่อยู่ในฐานข้อมูลของคุณแล้ว วิธีนี้มักใช้เพื่อให้แน่ใจว่าอัลกอริทึมของคุณสามารถเรียนรู้จากข้อมูลคุณภาพสูงได้
def encode_and_bind(original_dataframe, feature_to_encode):
dummies = pd.get_dummies(original_dataframe[[feature_to_encode]])
res = pd.concat([original_dataframe, dummies], axis=1)
res = res.drop([feature_to_encode], axis=1)
return(res)
features_to_encode = ["колонка1","колонка2","колонка3"]
for feature in features_to_encode:
df_categorical = encode_and_bind(df_categorical, feature))
ในที่สุด เราก็ได้เสร็จสิ้นการประมวลผลข้อมูลเชิงคุณภาพและเชิงปริมาณแยกกันแล้ว - ถึงเวลารวมกลับเข้าด้วยกัน
new_df = pd.concat([df_numerical,df_categorical], axis=1)
หลังจากที่เรารวมชุดข้อมูลเข้าด้วยกันเป็นชุดเดียว ในที่สุดเราก็สามารถใช้การแปลงข้อมูลโดยใช้ MinMaxScaler จากไลบรารี sklearn ได้ ซึ่งจะทำให้ค่าของเราอยู่ระหว่าง 0 ถึง 1 ซึ่งจะช่วยในการฝึกโมเดลในอนาคต
from sklearn.preprocessing import MinMaxScaler
min_max_scaler = MinMaxScaler()
new_df = min_max_scaler.fit_transform(new_df)
ข้อมูลนี้พร้อมสำหรับทุกสิ่งแล้ว - โครงข่ายประสาทเทียม, อัลกอริธึม ML มาตรฐาน ฯลฯ !
ในบทความนี้ เราไม่ได้คำนึงถึงการทำงานกับข้อมูลอนุกรมเวลา เนื่องจากสำหรับข้อมูลดังกล่าว คุณควรใช้เทคนิคการประมวลผลที่แตกต่างกันเล็กน้อย ขึ้นอยู่กับงานของคุณ ในอนาคต ทีมของเราจะอุทิศบทความแยกต่างหากในหัวข้อนี้ และเราหวังว่าจะสามารถนำสิ่งที่น่าสนใจ ใหม่ๆ และมีประโยชน์มาสู่ชีวิตของคุณได้เช่นเดียวกับบทความนี้
ที่มา: will.com