SciPy چیست؟ آموزش کامل محاسبات علمی، آمار و بهینهسازی با پایتون
در این آموزش جامع SciPy، بهینهسازی، آزمون آماری، انتگرالگیری، درونیابی، جبر خطی، پردازش سیگنال و ماتریسهای Sparse را با پروژههای عملی پایتون و هوش مصنوعی درواره یاد میگیرید.
پایتون فقط یک زبان برای ساخت وبسایت، اتوماسیون یا توسعه هوش مصنوعی نیست. بخش مهمی از محبوبیت آن در علم داده، مهندسی و یادگیری ماشین به مجموعه کتابخانههایی مربوط میشود که الگوریتمهای عددی پیچیده را با یک رابط ساده در اختیار برنامهنویس قرار میدهند.
SciPy یکی از پایهایترین کتابخانههای این اکوسیستم است. اگر NumPy ابزار اصلی کار با آرایه و محاسبات برداری باشد، SciPy مجموعهای از الگوریتمهای تخصصی برای بهینهسازی، آمار، انتگرالگیری، جبر خطی، پردازش سیگنال، درونیابی، ماتریسهای Sparse و محاسبات فضایی ارائه میکند.
در این آموزش یاد میگیرید:
- SciPy چیست و چه تفاوتی با NumPy دارد
- چگونه SciPy را نصب و پیکربندی کنید
- ساختار Submoduleهای اصلی آن چگونه است
- چگونه یک تابع را بهینه کنید
- چگونه پارامترهای یک مدل را روی داده برازش دهید
- چگونه انتگرال و معادله دیفرانسیل را عددی حل کنید
- چگونه دادههای ناقص را درونیابی کنید
- چگونه آزمون آماری اجرا کنید
- چگونه نویز سیگنال را کاهش و قلهها را پیدا کنید
- چگونه از ماتریس Sparse استفاده کنید
- چگونه فاصله و نزدیکترین همسایه را محاسبه کنید
- چگونه نتیجه محاسبات را برای تحلیل متنی به API درواره بفرستید
SciPy چیست؟
SciPy یک کتابخانه متنباز پایتون برای محاسبات علمی، ریاضی و مهندسی است. این کتابخانه روی NumPy ساخته شده و بسیاری از توابع آن، آرایههای NumPy را بهعنوان ورودی دریافت میکنند.
طبق وبسایت رسمی SciPy، این کتابخانه الگوریتمهایی برای موارد زیر ارائه میکند:
- Optimization
- Integration
- Interpolation
- Linear Algebra
- Statistics
- Signal Processing
- Fourier Transform
- Sparse Matrices
- Spatial Algorithms
- Differential Equations
- Special Functions
SciPy بخشی از زیرساخت محاسبات علمی پایتون است و بسیاری از کتابخانههای Machine Learning، پردازش تصویر و تحلیل داده به آن وابستهاند.
تفاوت SciPy و NumPy
NumPy و SciPy مکمل یکدیگرند.
| ویژگی | NumPy | SciPy |
|---|---|---|
| آرایه چندبعدی | قابلیت اصلی | از آرایه NumPy استفاده میکند |
| محاسبات برداری | بسیار مناسب | برای الگوریتمهای تخصصی |
| جبر خطی پایه | دارد | کاملتر و تخصصیتر |
| آمار پایه | محدود | توزیعها و آزمونهای آماری |
| بهینهسازی | ندارد یا بسیار محدود | مجموعه کامل الگوریتمها |
| انتگرال عددی | ندارد | دارد |
| پردازش سیگنال | محدود | ابزارهای تخصصی |
| ماتریس Sparse | ندارد | دارد |
| الگوریتم فضایی | محدود | KDTree، Distance و موارد دیگر |
| درونیابی | محدود | مجموعه روشهای تخصصی |
مثال NumPy:
import numpy as np
values = np.array([
10,
15,
22,
18
])
print(values.mean())
مثال SciPy:
from scipy import stats
result = stats.ttest_1samp(
values,
popmean=15
)
print(result.statistic)
print(result.pvalue)
NumPy میانگین را محاسبه میکند، اما SciPy یک آزمون آماری کامل اجرا میکند.
نصب SciPy
ساخت محیط مجازی:
python -m venv .venv
فعالسازی در ویندوز:
.venv\Scripts\activate
فعالسازی در Linux یا macOS:
source .venv/bin/activate
بهروزرسانی Pip:
python -m pip install --upgrade pip
نصب SciPy:
python -m pip install scipy
برای اجرای مثالهای مقاله:
python -m pip install scipy numpy pandas matplotlib
راهنمای رسمی SciPy نیز استفاده از محیط مجازی و نصب با دستور زیر را پیشنهاد میکند:
python -m pip install scipy
بررسی نسخه نصبشده:
python -c "import scipy; print(scipy.__version__)"
تست Import:
import scipy
import numpy as np
print("SciPy:", scipy.__version__)
print("NumPy:", np.__version__)
ساختار Submoduleهای مهم SciPy
بهتر است بهجای Import کردن تمام SciPy، فقط Submodule موردنیاز را وارد کنید.
| Submodule | کاربرد |
|---|---|
scipy.optimize | بهینهسازی، پیداکردن ریشه و Curve Fitting |
scipy.integrate | انتگرالگیری و حل معادلات دیفرانسیل |
scipy.interpolate | درونیابی داده |
scipy.stats | آمار، توزیع احتمال و آزمون آماری |
scipy.linalg | جبر خطی |
scipy.sparse | ماتریس Sparse |
scipy.signal | پردازش سیگنال |
scipy.fft | تبدیل فوریه |
scipy.spatial | فاصله، KDTree و محاسبات فضایی |
scipy.ndimage | پردازش آرایههای چندبعدی و تصویر |
scipy.special | توابع ریاضی ویژه |
نمونه Import:
from scipy import optimize
from scipy import stats
from scipy import signal
یا:
from scipy.optimize import minimize
from scipy.stats import ttest_ind
from scipy.signal import find_peaks
روش دوم وابستگی هر بخش از کد را واضحتر میکند.
بهینهسازی با scipy.optimize
Optimization یعنی پیداکردن ورودیای که مقدار یک تابع را کمینه یا بیشینه کند.
کاربردهای آن:
- کمینهکردن هزینه
- انتخاب بهترین ترکیب منابع
- تنظیم پارامتر مدل
- برازش منحنی
- پیداکردن نقطه بهینه یک تابع
- برنامهریزی تولید
- بهینهسازی قیمت یا بودجه
کمینهکردن یک تابع ساده
تابع زیر در نقطه x = 3 کمینه میشود:
def objective(x):
return (x - 3) ** 2 + 5
استفاده از minimize_scalar:
from scipy.optimize import minimize_scalar
result = minimize_scalar(
objective
)
print("Success:", result.success)
print("Best x:", result.x)
print("Minimum value:", result.fun)
خروجی result فقط یک عدد نیست و اطلاعاتی مانند وضعیت موفقیت، تعداد ارزیابیها و پیام Solver را نیز نگهداری میکند.
همیشه وضعیت موفقیت را بررسی کنید:
if not result.success:
raise RuntimeError(
result.message
)
بهینهسازی چندمتغیره
فرض کنید هزینه یک سیستم با دو متغیر مشخص میشود:
def cost_function(values):
x, y = values
return (
(x - 4) ** 2
+ (y - 2) ** 2
+ 10
)
اجرای بهینهسازی:
from scipy.optimize import minimize
initial_guess = [0, 0]
result = minimize(
cost_function,
x0=initial_guess
)
print("Success:", result.success)
print("Best values:", result.x)
print("Minimum cost:", result.fun)
x0 نقطه شروع Solver است. در بعضی مسائل غیرخطی، نقطه شروع میتواند روی نتیجه اثر بگذارد.
اعمال محدودیت روی متغیرها
اگر هر متغیر باید داخل یک بازه باشد:
bounds = [
(0, 10),
(0, 8)
]
result = minimize(
cost_function,
x0=[1, 1],
bounds=bounds
)
در این مثال:
- مقدار
xبین صفر و ۱۰ است - مقدار
yبین صفر و ۸ است
بهینهسازی با Constraint
فرض کنید مجموع دو متغیر باید حداقل ۵ باشد:
constraints = [
{
"type": "ineq",
"fun": lambda values:
values[0]
+ values[1]
- 5
}
]
result = minimize(
cost_function,
x0=[2.5, 2.5],
bounds=[
(0, 10),
(0, 8)
],
constraints=constraints,
method="SLSQP"
)
print(result.x)
print(result.fun)
print(result.success)
در Constraint از نوع ineq، مقدار تابع باید بزرگتر یا مساوی صفر باشد.
نتیجه Optimization باید از نظر منطق مسئله نیز بررسی شود. موفقیت Solver به معنای صحیحبودن مدل کسبوکار، داده یا Constraintها نیست.
پیداکردن ریشه معادله
برای حل معادله زیر:
x^2 - 9 = 0
از root_scalar استفاده میکنیم:
from scipy.optimize import root_scalar
def equation(x):
return x ** 2 - 9
result = root_scalar(
equation,
bracket=[0, 10]
)
print("Root:", result.root)
print("Converged:", result.converged)
بازه bracket باید به شکلی انتخاب شود که ریشه داخل آن قرار گیرد و شرایط روش انتخابی برقرار باشد.
برای ریشه منفی:
result = root_scalar(
equation,
bracket=[-10, 0]
)
برازش منحنی با curve_fit
Curve Fitting برای تخمین پارامترهای یک مدل از روی داده استفاده میشود.
فرض کنید داده از یک رابطه خطی همراه با Noise آمده است:
import numpy as np
rng = np.random.default_rng(42)
x = np.linspace(
0,
20,
80
)
y = (
2.7 * x
+ 8
+ rng.normal(
0,
3,
size=len(x)
)
)
تابع مدل:
def linear_model(
x,
slope,
intercept
):
return (
slope * x
+ intercept
)
برازش:
from scipy.optimize import curve_fit
parameters, covariance = curve_fit(
linear_model,
x,
y
)
slope, intercept = parameters
print("Slope:", slope)
print("Intercept:", intercept)
رسم نتیجه:
import matplotlib.pyplot as plt
predicted = linear_model(
x,
slope,
intercept
)
fig, ax = plt.subplots(
figsize=(10, 5),
layout="constrained"
)
ax.scatter(
x,
y,
alpha=0.65,
label="Observed"
)
ax.plot(
x,
predicted,
color="#EF476F",
linewidth=2.5,
label="Fitted line"
)
ax.set_title("Curve Fitting with SciPy")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.legend()
ax.grid(alpha=0.2)
plt.show()
ماتریس covariance اطلاعاتی درباره عدمقطعیت تخمین پارامترها ارائه میکند.
تخمین تقریبی Standard Error پارامترها:
parameter_errors = np.sqrt(
np.diag(covariance)
)
print(parameter_errors)
برازش موفق یک منحنی به معنای مناسببودن آن مدل برای پیشبینی خارج از بازه داده نیست.
انتگرالگیری عددی با scipy.integrate
برای محاسبه انتگرال تابع زیر در بازه صفر تا یک:
f(x) = x^2
کد:
from scipy.integrate import quad
def function(x):
return x ** 2
value, estimated_error = quad(
function,
0,
1
)
print("Integral:", value)
print(
"Estimated error:",
estimated_error
)
نتیجه دقیق این انتگرال برابر یکسوم است. quad علاوه بر مقدار تقریبی، یک تخمین از خطای عددی نیز برمیگرداند.
انتگرال تابع دارای پارامتر
from scipy.integrate import quad
def exponential_decay(
x,
rate
):
return np.exp(
-rate * x
)
value, error = quad(
exponential_decay,
0,
5,
args=(0.8,)
)
print(value)
print(error)
آرگومان args پارامترهای اضافه تابع را ارسال میکند.
انتگرال روی داده نمونهبرداریشده
گاهی تابع تحلیلی نداریم و فقط مقدارهای ثبتشده را داریم. برای این حالت میتوان از Simpson استفاده کرد:
import numpy as np
from scipy.integrate import simpson
x = np.linspace(
0,
10,
101
)
y = np.sin(x) + 2
area = simpson(
y=y,
x=x
)
print(area)
مرتببودن محور X و کیفیت Sampleها روی نتیجه انتگرال عددی اثر دارد.
حل معادله دیفرانسیل با solve_ivp
معادلات دیفرانسیل در مدلسازی رشد، تغییر دما، حرکت، واکنش و بسیاری از سیستمهای پویا استفاده میشوند.
معادله ساده کاهش نمایی:
dy/dt = -k × y
کد:
from scipy.integrate import solve_ivp
def decay(
time,
value,
rate
):
return -rate * value
solution = solve_ivp(
fun=decay,
t_span=(0, 10),
y0=[100],
args=(0.35,),
dense_output=True
)
ساخت نقاط زمانی:
time_points = np.linspace(
0,
10,
100
)
values = solution.sol(
time_points
)[0]
رسم:
fig, ax = plt.subplots(
figsize=(10, 5),
layout="constrained"
)
ax.plot(
time_points,
values,
color="#6C4DF6",
linewidth=2.5
)
ax.set_title("Exponential Decay")
ax.set_xlabel("Time")
ax.set_ylabel("Value")
ax.grid(alpha=0.2)
plt.show()
وضعیت حل را بررسی کنید:
print(solution.success)
print(solution.message)
درونیابی با scipy.interpolate
Interpolation برای تخمین مقدار میان نقاط مشاهدهشده استفاده میشود.
کاربردهای رایج:
- پرکردن فاصله بین Sampleها
- ساخت منحنی هموار برای نمایش
- تبدیل داده به Grid منظم
- تخمین مقدار در زمانهای ثبتنشده
- Resampling سیگنال
داده نمونه:
import numpy as np
x = np.array([
0,
1,
2,
4,
7,
10
])
y = np.array([
10,
12,
15,
19,
18,
25
])
درونیابی خطی با NumPy
برای روش خطی ساده:
new_x = np.linspace(
0,
10,
100
)
linear_y = np.interp(
new_x,
x,
y
)
درونیابی Shape-preserving با PCHIP
from scipy.interpolate import (
PchipInterpolator
)
interpolator = PchipInterpolator(
x,
y
)
smooth_y = interpolator(
new_x
)
رسم:
fig, ax = plt.subplots(
figsize=(10, 5),
layout="constrained"
)
ax.scatter(
x,
y,
color="#EF476F",
s=70,
label="Observed"
)
ax.plot(
new_x,
smooth_y,
color="#6C4DF6",
linewidth=2.5,
label="PCHIP"
)
ax.set_title("Data Interpolation")
ax.legend()
ax.grid(alpha=0.2)
plt.show()
PCHIP برای بسیاری از دادهها شکل محلی را بهتر حفظ میکند و نسبت به بعضی Splineها کمتر دچار Overshoot میشود.
Interpolation برای تخمین داخل بازه داده است. استفاده از آن برای Extrapolation خارج از بازه مشاهدهشده ریسک خطای بیشتری دارد.
جبر خطی با scipy.linalg
SciPy توابع تخصصی جبر خطی را در scipy.linalg ارائه میکند.
حل دستگاه معادلات خطی
دستگاه زیر را در نظر بگیرید:
2x + y = 8
x + 3y = 9
نمایش ماتریسی:
import numpy as np
from scipy.linalg import solve
matrix = np.array([
[2, 1],
[1, 3]
])
values = np.array([
8,
9
])
solution = solve(
matrix,
values
)
print(solution)
اعتبارسنجی جواب:
print(
matrix @ solution
)
print(values)
بهجای محاسبه معکوس ماتریس و ضرب آن در بردار، معمولاً استفاده مستقیم از solve دقیقتر و کارآمدتر است.
محاسبه مقدار و بردار ویژه
from scipy.linalg import eig
matrix = np.array([
[4, 2],
[1, 3]
])
eigenvalues, eigenvectors = eig(
matrix
)
print(eigenvalues)
print(eigenvectors)
مقدارهای ویژه در تحلیل سیستمها، PCA، مدلهای پویا و الگوریتمهای عددی کاربرد دارند.
تجزیه SVD
from scipy.linalg import svd
matrix = np.array([
[1, 2],
[3, 4],
[5, 6]
])
u, singular_values, vt = svd(
matrix
)
print("U:", u)
print(
"Singular values:",
singular_values
)
print("Vt:", vt)
SVD در کاهش بُعد، فشردهسازی، حل مسئله Least Squares و تحلیل ماتریسها کاربرد دارد.
آمار با scipy.stats
ماژول scipy.stats شامل موارد زیر است:
- توزیعهای احتمال
- شاخصهای آماری
- آزمون فرض
- آزمون نرمالبودن
- همبستگی
- Bootstrap
- آزمونهای پارامتریک و ناپارامتریک
آمار توصیفی
from scipy import stats
import numpy as np
values = np.array([
12,
15,
13,
18,
21,
17,
16,
14
])
description = stats.describe(
values
)
print(description)
خروجی شامل تعداد نمونه، حداقل، حداکثر، میانگین، واریانس، Skewness و Kurtosis است.
محاسبه Z-score
z_scores = stats.zscore(
values
)
print(z_scores)
Z-score نشان میدهد هر مقدار چند Standard Deviation با میانگین فاصله دارد. مقدار بزرگ Z-score میتواند برای بررسی نقاط غیرعادی مفید باشد، اما معیار قطعی برای حذف داده نیست.
آزمون تفاوت میان دو گروه
فرض کنید نرخ پاسخ یا زمان انجام یک فرایند در دو نسخه اندازهگیری شده است:
rng = np.random.default_rng(42)
group_a = rng.normal(
loc=320,
scale=45,
size=120
)
group_b = rng.normal(
loc=300,
scale=48,
size=130
)
آزمون Welch:
from scipy.stats import ttest_ind
result = ttest_ind(
group_a,
group_b,
equal_var=False
)
print(
"Statistic:",
result.statistic
)
print(
"P-value:",
result.pvalue
)
استفاده از equal_var=False آزمون Welch را اجرا میکند که برابری واریانس دو گروه را فرض نمیکند.
تفسیر P-value باید همراه با موارد زیر باشد:
- اندازه نمونه
- اندازه اثر
- فاصله اطمینان
- کیفیت جمعآوری داده
- تعدد آزمونها
- اهمیت عملی اختلاف
P-value بهتنهایی اندازه یا اهمیت اختلاف را مشخص نمیکند.
محاسبه اندازه اثر ساده
mean_difference = (
group_b.mean()
- group_a.mean()
)
pooled_scale = np.sqrt(
(
group_a.var(
ddof=1
)
+ group_b.var(
ddof=1
)
)
/ 2
)
effect_size = (
mean_difference
/ pooled_scale
)
print(
"Mean difference:",
mean_difference
)
print(
"Effect size:",
effect_size
)
این محاسبه باید براساس طراحی مطالعه و تعریف مناسب Effect Size انتخاب شود.
آزمون ناپارامتریک Mann–Whitney U
اگر فرضهای آزمون t مناسب نیستند، ممکن است از آزمون ناپارامتریک استفاده شود:
from scipy.stats import mannwhitneyu
result = mannwhitneyu(
group_a,
group_b,
alternative="two-sided"
)
print(result.statistic)
print(result.pvalue)
این آزمون دقیقاً «آزمون اختلاف میانگین» نیست و تفسیر آن باید با شناخت فرضها و شکل توزیع انجام شود.
محاسبه همبستگی
Pearson:
from scipy.stats import pearsonr
x = np.array([
1,
2,
3,
4,
5,
6
])
y = np.array([
2,
4,
5,
8,
10,
11
])
result = pearsonr(
x,
y
)
print(
"Correlation:",
result.statistic
)
print(
"P-value:",
result.pvalue
)
Spearman برای رابطه رتبهای یا Monotonic:
from scipy.stats import spearmanr
result = spearmanr(
x,
y
)
همبستگی به معنای رابطه علت و معلولی نیست.
پردازش سیگنال با scipy.signal
سیگنال فقط صدای ضبطشده نیست. هر دادهای که در طول زمان یا یک محور منظم تغییر کند میتواند بهعنوان Signal تحلیل شود:
- زمان پاسخ API
- میزان مصرف CPU
- تعداد درخواست در دقیقه
- دمای حسگر
- داده صوتی
- لرزش
- فروش روزانه
- ترافیک سایت
کاهش نویز با Savitzky–Golay
ساخت سیگنال:
import numpy as np
from scipy.signal import savgol_filter
rng = np.random.default_rng(42)
time = np.linspace(
0,
20,
500
)
clean_signal = (
np.sin(time)
+ 0.35 * np.sin(
3 * time
)
)
noisy_signal = (
clean_signal
+ rng.normal(
0,
0.22,
size=len(time)
)
)
smoothed_signal = savgol_filter(
noisy_signal,
window_length=31,
polyorder=3
)
رسم:
fig, ax = plt.subplots(
figsize=(12, 5),
layout="constrained"
)
ax.plot(
time,
noisy_signal,
alpha=0.4,
label="Noisy"
)
ax.plot(
time,
smoothed_signal,
color="#6C4DF6",
linewidth=2.5,
label="Smoothed"
)
ax.set_title("Signal Smoothing")
ax.set_xlabel("Time")
ax.set_ylabel("Value")
ax.legend()
ax.grid(alpha=0.2)
plt.show()
window_length باید عددی فرد و متناسب با تعداد Sampleها باشد. پنجره بسیار بزرگ میتواند تغییرات واقعی را حذف کند.
پیداکردن قلهها با find_peaks
from scipy.signal import find_peaks
peaks, properties = find_peaks(
smoothed_signal,
prominence=0.5,
distance=30
)
print(peaks)
رسم قلهها:
fig, ax = plt.subplots(
figsize=(12, 5),
layout="constrained"
)
ax.plot(
time,
smoothed_signal,
color="#6C4DF6"
)
ax.scatter(
time[peaks],
smoothed_signal[peaks],
color="#EF476F",
s=65,
label="Peaks"
)
ax.legend()
ax.grid(alpha=0.2)
plt.show()
پارامترهای مهم:
height: حداقل ارتفاعdistance: حداقل فاصله میان قلههاprominence: میزان برجستگی قلهwidth: حداقل یا حداکثر عرض قله
انتخاب این پارامترها باید براساس واحد و منطق داده انجام شود.
تبدیل فوریه با scipy.fft
تبدیل فوریه کمک میکند فرکانسهای موجود در یک سیگنال را بررسی کنیم.
from scipy.fft import (
rfft,
rfftfreq
)
sample_rate = 100
duration = 5
time = np.arange(
0,
duration,
1 / sample_rate
)
signal_values = (
np.sin(
2 * np.pi * 5 * time
)
+ 0.5 * np.sin(
2 * np.pi * 12 * time
)
)
محاسبه FFT:
spectrum = np.abs(
rfft(signal_values)
)
frequencies = rfftfreq(
len(signal_values),
d=1 / sample_rate
)
رسم:
fig, ax = plt.subplots(
figsize=(10, 5),
layout="constrained"
)
ax.plot(
frequencies,
spectrum,
color="#6C4DF6"
)
ax.set_xlim(0, 30)
ax.set_title("Frequency Spectrum")
ax.set_xlabel("Frequency")
ax.set_ylabel("Amplitude")
ax.grid(alpha=0.2)
plt.show()
در نمودار باید قلههایی نزدیک فرکانسهای ۵ و ۱۲ مشاهده شود.
ماتریس Sparse با scipy.sparse
در بسیاری از پروژههای هوش مصنوعی و تحلیل متن، بیشتر مقدارهای ماتریس صفر هستند.
برای مثال:
- ماتریس واژه و سند
- ویژگیهای One-hot
- داده تعامل کاربر و محصول
- گراف بزرگ
- ماتریس توصیهگر
- خروجی Bag of Words یا TF-IDF
ذخیره تمام صفرها حافظه زیادی مصرف میکند. ماتریس Sparse فقط مقدارهای غیرصفر و موقعیت آنها را نگهداری میکند.
ساخت ماتریس CSR
import numpy as np
from scipy.sparse import csr_matrix
dense_matrix = np.array([
[0, 0, 4, 0],
[1, 0, 0, 0],
[0, 2, 0, 3],
[0, 0, 0, 5]
])
sparse_matrix = csr_matrix(
dense_matrix
)
print(sparse_matrix)
تعداد مقدارهای غیرصفر:
print(
sparse_matrix.nnz
)
Shape:
print(
sparse_matrix.shape
)
تبدیل به Dense:
restored = (
sparse_matrix.toarray()
)
print(restored)
برای ماتریس بسیار بزرگ، تبدیل کامل Sparse به Dense ممکن است حافظه زیادی مصرف کند و باید با احتیاط انجام شود.
عملیات روی ماتریس Sparse
vector = np.array([
1,
2,
3,
4
])
result = (
sparse_matrix @ vector
)
print(result)
بسیاری از الگوریتمهای Scikit-learn میتوانند مستقیم با ماتریس Sparse کار کنند.
محاسبات فضایی با scipy.spatial
ماژول scipy.spatial برای فاصله، نزدیکترین همسایه و ساختارهای فضایی کاربرد دارد.
محاسبه فاصله نقاط
from scipy.spatial.distance import (
cdist
)
users = np.array([
[1.0, 2.0],
[2.5, 3.0],
[7.0, 8.0]
])
centers = np.array([
[0.0, 0.0],
[5.0, 5.0]
])
distances = cdist(
users,
centers,
metric="euclidean"
)
print(distances)
هر سطر فاصله یک کاربر تا تمام Centerها را نشان میدهد.
نزدیکترین همسایه با KDTree
from scipy.spatial import KDTree
points = np.array([
[1, 2],
[2, 3],
[4, 5],
[8, 8],
[9, 10]
])
tree = KDTree(
points
)
distance, index = tree.query(
[3.8, 4.7]
)
print("Distance:", distance)
print(
"Nearest point:",
points[index]
)
KDTree برای دادههای کمبُعد مناسب است. در فضاهای بسیار پربُعد، کارایی و معنای فاصله باید جداگانه ارزیابی شود.
پروژه عملی: تحلیل زمان پاسخ API
در این پروژه یک مجموعه داده زمان پاسخ میسازیم و با SciPy موارد زیر را بررسی میکنیم:
- میانگین و Percentileهای Latency
- هموارسازی نویز
- شناسایی Spikeها
- مقایسه دو بازه
- تشخیص فرکانسهای احتمالی
- ساخت خلاصه برای تحلیل هوش مصنوعی
مرحله اول: ساخت داده
import numpy as np
import pandas as pd
rng = np.random.default_rng(42)
sample_count = 1440
timestamps = pd.date_range(
"2026-01-01",
periods=sample_count,
freq="min"
)
baseline = (
280
+ 25 * np.sin(
np.linspace(
0,
8 * np.pi,
sample_count
)
)
)
noise = rng.normal(
0,
18,
sample_count
)
latency = baseline + noise
spike_positions = rng.choice(
sample_count,
size=18,
replace=False
)
latency[spike_positions] += (
rng.integers(
180,
450,
size=len(spike_positions)
)
)
df = pd.DataFrame({
"timestamp": timestamps,
"latency_ms": latency
})
مرحله دوم: پاکسازی
df["timestamp"] = pd.to_datetime(
df["timestamp"],
errors="coerce"
)
df["latency_ms"] = pd.to_numeric(
df["latency_ms"],
errors="coerce"
)
df = (
df.dropna(
subset=[
"timestamp",
"latency_ms"
]
)
.sort_values("timestamp")
.drop_duplicates(
subset=["timestamp"]
)
)
مرحله سوم: هموارسازی
from scipy.signal import (
savgol_filter
)
df["smoothed_latency"] = (
savgol_filter(
df["latency_ms"],
window_length=31,
polyorder=3
)
)
مرحله چهارم: پیداکردن Spikeها
برای تشخیص Spike بهتر است روی تفاوت داده خام و Baseline هموارشده کار کنیم:
residual = (
df["latency_ms"]
- df["smoothed_latency"]
)
from scipy.signal import find_peaks
peaks, properties = find_peaks(
residual.to_numpy(),
prominence=100,
distance=10
)
spikes = df.iloc[peaks].copy()
spikes["prominence"] = (
properties["prominences"]
)
print(spikes.head())
مرحله پنجم: محاسبه شاخصها
latency_values = (
df["latency_ms"]
.to_numpy()
)
summary = {
"sample_count": int(
len(df)
),
"mean_latency_ms": float(
np.mean(latency_values)
),
"median_latency_ms": float(
np.median(latency_values)
),
"p95_latency_ms": float(
np.percentile(
latency_values,
95
)
),
"p99_latency_ms": float(
np.percentile(
latency_values,
99
)
),
"minimum_latency_ms": float(
np.min(latency_values)
),
"maximum_latency_ms": float(
np.max(latency_values)
),
"detected_spikes": int(
len(spikes)
)
}
مرحله ششم: مقایسه نیمه اول و دوم
middle = len(df) // 2
first_half = (
df.iloc[:middle][
"latency_ms"
]
.to_numpy()
)
second_half = (
df.iloc[middle:][
"latency_ms"
]
.to_numpy()
)
from scipy.stats import ttest_ind
comparison = ttest_ind(
first_half,
second_half,
equal_var=False
)
summary[
"first_half_mean_ms"
] = float(
first_half.mean()
)
summary[
"second_half_mean_ms"
] = float(
second_half.mean()
)
summary[
"comparison_pvalue"
] = float(
comparison.pvalue
)
این مقایسه فقط یک مثال آموزشی است. برای داده زمانی واقعی، استقلال Observationها، روند زمانی، Seasonality و Autocorrelation باید بررسی شوند.
مرحله هفتم: رسم نتیجه
import matplotlib.pyplot as plt
fig, ax = plt.subplots(
figsize=(14, 6),
layout="constrained"
)
ax.plot(
df["timestamp"],
df["latency_ms"],
color="#AEB4C0",
alpha=0.55,
linewidth=1,
label="Observed"
)
ax.plot(
df["timestamp"],
df["smoothed_latency"],
color="#6C4DF6",
linewidth=2.5,
label="Smoothed"
)
ax.scatter(
spikes["timestamp"],
spikes["latency_ms"],
color="#EF476F",
s=45,
label="Detected spikes",
zorder=3
)
ax.set_title(
"API Latency Analysis"
)
ax.set_xlabel("Time")
ax.set_ylabel("Latency (ms)")
ax.legend()
ax.grid(alpha=0.2)
fig.savefig(
"api-latency-analysis.png",
dpi=170,
bbox_inches="tight",
facecolor="white"
)
plt.show()
اتصال SciPy به هوش مصنوعی درواره
SciPy برای محاسبات قطعی و آماری استفاده میشود. هوش مصنوعی میتواند نتیجه محاسبهشده را توضیح دهد، اما نباید جایگزین محاسبات عددی شود.
فرایند پیشنهادی:
- داده با Pandas پاکسازی شود
- شاخصهای عددی با NumPy و SciPy محاسبه شوند
- نمودار با Matplotlib یا Plotly ساخته شود
- فقط خلاصه لازم به مدل ارسال شود
- مدل براساس اعداد موجود، گزارش متنی تولید کند
برای استفاده از مدلهای مختلف میتوانید در درواره ثبتنام کنید. فهرست مدلها و قیمت بهروز آنها در صفحه مدلهای درواره قرار دارد.
نگهداری API Key
در Linux یا macOS:
export DARVAREH_API_KEY="YOUR_DARVAREH_API_KEY"
در PowerShell:
$env:DARVAREH_API_KEY="YOUR_DARVAREH_API_KEY"
ارسال خلاصه تحلیل به API درواره
import json
import os
import requests
response = requests.post(
"https://api.darvareh.ir/v1/chat/completions",
headers={
"Authorization": (
f"Bearer "
f"{os.environ['DARVAREH_API_KEY']}"
),
"Content-Type": "application/json"
},
json={
"model": "YOUR_MODEL_ID",
"messages": [
{
"role": "system",
"content": (
"تو یک دستیار تحلیل داده هستی. "
"فقط از اعداد ورودی استفاده کن. "
"هیچ عدد یا علت جدیدی نساز. "
"نتیجه آزمون آماری را با احتیاط "
"و بدون ادعای علت و معلول توضیح بده."
)
},
{
"role": "user",
"content": (
"این خلاصه تحلیل زمان پاسخ API "
"را بررسی کن. چهار مشاهده مهم، "
"سه پیشنهاد برای بررسی فنی بیشتر "
"و یک خلاصه مدیریتی کوتاه بنویس."
"\n\n"
+ json.dumps(
summary,
ensure_ascii=False
)
)
}
],
"temperature": 0.2
},
timeout=60
)
response.raise_for_status()
result = response.json()
print(
result["choices"][0]
["message"]
["content"]
)
در این معماری، مدل به داده خام یا تمام Logها دسترسی ندارد. فقط شاخصهای انتخابشده و محاسبهشده را دریافت میکند.
تولید پیشنهاد تحلیل با هوش مصنوعی
Schema داده:
schema = {
"timestamp": (
"زمان ثبت اندازهگیری"
),
"latency_ms": (
"زمان پاسخ برحسب میلیثانیه"
),
"status": (
"وضعیت درخواست"
),
"model": (
"مدل استفادهشده"
),
"input_tokens": (
"تعداد توکن ورودی"
),
"output_tokens": (
"تعداد توکن خروجی"
)
}
پرامپت پیشنهادی:
برای دادهای با ستونهای معرفیشده، یک برنامه تحلیل با Pandas و SciPy پیشنهاد بده.
برای هر مرحله مشخص کن:
1. چه پاکسازیای لازم است
2. چه شاخصی باید محاسبه شود
3. از کدام تابع SciPy استفاده شود
4. چه فرضی باید بررسی شود
5. چه نموداری مناسب است
6. چه خطای تفسیری ممکن است رخ دهد
عدد اختراع نکن و فقط روی طراحی تحلیل تمرکز کن.
پیشنهاد مدل باید پیش از اجرا بررسی شود؛ بهخصوص وقتی انتخاب آزمون آماری به ساختار داده وابسته است.
ساخت تابع قابل استفاده مجدد برای تشخیص Spike
import numpy as np
import pandas as pd
from scipy.signal import (
find_peaks,
savgol_filter
)
def detect_spikes(
values,
window_length=31,
polyorder=3,
prominence=100,
distance=10
):
array = np.asarray(
values,
dtype=float
)
if array.ndim != 1:
raise ValueError(
"values must be one-dimensional"
)
if len(array) < window_length:
raise ValueError(
"window_length is larger "
"than the input data"
)
if window_length % 2 == 0:
raise ValueError(
"window_length must be odd"
)
smoothed = savgol_filter(
array,
window_length=window_length,
polyorder=polyorder
)
residual = array - smoothed
indices, properties = find_peaks(
residual,
prominence=prominence,
distance=distance
)
result = pd.DataFrame({
"index": indices,
"value": array[indices],
"baseline": smoothed[indices],
"residual": residual[indices],
"prominence": (
properties["prominences"]
)
})
return result, smoothed
استفاده:
spike_table, baseline = detect_spikes(
df["latency_ms"],
window_length=31,
prominence=100,
distance=10
)
print(spike_table.head())
تست تابع تشخیص Spike
def test_detect_spikes():
values = np.full(
101,
100.0
)
values[50] = 400.0
spikes, baseline = detect_spikes(
values,
window_length=11,
prominence=100,
distance=5
)
assert len(spikes) == 1
assert spikes.iloc[0]["index"] == 50
assert len(baseline) == len(values)
با تست میتوان رفتار تابع را روی ورودی کنترلشده بررسی کرد.
بهینهسازی کارایی SciPy
استفاده از آرایه NumPy
values = (
df["value"]
.to_numpy(
dtype=float
)
)
پرهیز از حلقه پایتون
بهجای:
result = []
for value in values:
result.append(
value ** 2
)
از محاسبه برداری استفاده کنید:
result = values ** 2
استفاده از ماتریس Sparse
اگر بیشتر مقدارهای ماتریس صفر است، آن را Dense نگهداری نکنید.
بررسی Dtype
در بعضی مسائل، float64 برای پایداری عددی لازم است:
values = np.asarray(
values,
dtype=np.float64
)
پرهیز از تبدیل غیرضروری
تبدیل مکرر میان DataFrame، List و Array هزینه پردازشی ایجاد میکند.
محدودکردن داده برای رسم
محاسبات میتوانند روی داده کامل انجام شوند، اما برای Scatter Plot شاید نمونهبرداری کافی باشد.
خطاهای رایج SciPy
خطای نصب نبودن SciPy
ModuleNotFoundError: No module named 'scipy'
راهحل:
python -m pip install scipy
نصب در محیط پایتون اشتباه
مسیر مفسر را بررسی کنید:
python -c "import sys; print(sys.executable)"
سپس:
python -m pip install scipy
خطای ناسازگاری NumPy و SciPy
بستهها را داخل محیط مجازی بهروزرسانی کنید:
python -m pip install --upgrade numpy scipy
در پروژه Production بهتر است نسخهها را پس از تست Pin کنید.
موفق نبودن Optimization
if not result.success:
print(result.message)
موارد زیر را بررسی کنید:
- نقطه شروع
- Bounds
- Constraintها
- Scale متغیرها
- تعریف تابع
- وجود مقدار NaN یا Infinite
- انتخاب Method مناسب
دریافت NaN
print(
np.isnan(values).sum()
)
print(
np.isinf(values).sum()
)
پاکسازی:
clean_values = values[
np.isfinite(values)
]
خطای Savitzky–Golay
window_length باید:
- فرد باشد
- از طول داده بیشتر نباشد
- از
polyorderبزرگتر باشد
نتیجه عجیب Interpolation
بررسی کنید:
- محور X مرتب باشد
- مقدار تکراری در X وجود نداشته باشد
- داده Missing نداشته باشد
- روش Interpolation با مسئله سازگار باشد
مصرف حافظه زیاد در Sparse
احتمالاً ماتریس Sparse را با toarray() به Dense تبدیل کردهاید. قبل از این کار، اندازه احتمالی آرایه Dense را محاسبه کنید.
اشتباهات تحلیلی رایج
انتخاب Solver بدون شناخت مسئله
هر Method برای نوع خاصی از تابع و Constraint مناسب است.
اعتماد به success=True بدون اعتبارسنجی
Solver ممکن است مسئله تعریفشده را حل کرده باشد، اما خود تابع هدف یا Constraintها اشتباه باشند.
استفاده از آزمون آماری بدون بررسی فرضها
نوع داده، استقلال نمونهها، شکل توزیع و طراحی آزمایش روی انتخاب آزمون اثر دارند.
یکی دانستن Statistical Significance و اهمیت عملی
یک اختلاف کوچک با نمونه بزرگ ممکن است P-value کمی داشته باشد، اما از نظر عملی مهم نباشد.
حذف خودکار داده پرت
داده پرت میتواند خطای ثبت، رویداد واقعی یا مهمترین Observation مجموعه داده باشد.
استفاده از Interpolation بهعنوان پیشبینی
Interpolation داخل محدوده داده انجام میشود. Extrapolation مسئله متفاوت و معمولاً پرریسکتری است.
هموارسازی بیش از حد Signal
فیلتر شدید میتواند Spike یا تغییر واقعی را حذف کند.
تفسیر همبستگی بهعنوان علیت
محاسبه Pearson یا Spearman دلیل ایجاد رابطه را مشخص نمیکند.
چکلیست استفاده حرفهای از SciPy
- مسئله و خروجی موردانتظار مشخص شده است
- نوع دادهها بررسی شده است
- مقدارهای NaN و Infinite کنترل شدهاند
- واحد متغیرها یکسان است
- Scale متغیرهای Optimization بررسی شده است
- Bounds و Constraintها منطق واقعی دارند
- وضعیت موفقیت Solver کنترل شده است
- نتیجه با یک روش مستقل اعتبارسنجی شده است
- فرضهای آزمون آماری بررسی شدهاند
- اندازه اثر کنار P-value گزارش شده است
- پارامترهای فیلتر براساس داده انتخاب شدهاند
- Interpolation از Extrapolation تفکیک شده است
- ماتریس Sparse بیدلیل به Dense تبدیل نشده است
- Seed داده تصادفی ثبت شده است
- نسخه وابستگیها در Production مشخص است
- محاسبات قطعی به مدل زبانی واگذار نشده است
- خلاصه ارسالی به هوش مصنوعی از قبل اعتبارسنجی شده است
پرسشهای متداول
SciPy چیست؟
SciPy یک کتابخانه پایتون برای محاسبات علمی است که ابزارهایی برای بهینهسازی، آمار، انتگرالگیری، جبر خطی، پردازش سیگنال، ماتریس Sparse و محاسبات فضایی ارائه میکند.
تفاوت NumPy و SciPy چیست؟
NumPy ابزار اصلی کار با آرایه و محاسبات برداری است. SciPy روی NumPy ساخته شده و الگوریتمهای تخصصی علمی و عددی ارائه میدهد.
آیا برای یادگیری SciPy باید NumPy بلد باشیم؟
آشنایی با Array، Shape، Dtype، Indexing و محاسبات برداری NumPy کمک زیادی میکند؛ زیرا بیشتر توابع SciPy با آرایههای NumPy کار میکنند.
SciPy در Machine Learning چه کاربردی دارد؟
SciPy در Optimization، ماتریسهای Sparse، محاسبه فاصله، آمار، جبر خطی و پردازش داده استفاده میشود. برخی کتابخانههای Machine Learning نیز به آن وابستهاند.
چگونه یک تابع را با SciPy بهینه کنیم؟
برای تابع تکمتغیره از minimize_scalar و برای مسائل چندمتغیره از minimize استفاده میشود. انتخاب Method به نوع تابع و Constraintها بستگی دارد.
چگونه با SciPy آزمون t اجرا کنیم؟
برای دو گروه مستقل میتوان از ttest_ind استفاده کرد:
result = ttest_ind(
group_a,
group_b,
equal_var=False
)
انتخاب آزمون باید براساس طراحی داده و فرضهای آماری باشد.
ماتریس Sparse چیست؟
ماتریسی است که بیشتر مقدارهای آن صفر است. ساختار Sparse فقط مقدارهای غیرصفر و موقعیت آنها را ذخیره میکند و میتواند مصرف حافظه را کاهش دهد.
چگونه نویز یک Signal را کاهش دهیم؟
یکی از روشها استفاده از savgol_filter است. پارامتر پنجره و درجه Polynomial باید متناسب با داده انتخاب شود.
آیا SciPy جایگزین Pandas است؟
خیر. Pandas برای مدیریت، پاکسازی و GroupBy داده جدولی مناسب است. SciPy الگوریتمهای علمی و آماری را ارائه میدهد.
چگونه SciPy را به هوش مصنوعی متصل کنیم؟
محاسبات را با SciPy انجام دهید، نتیجه را به یک Dictionary یا JSON خلاصه تبدیل کنید و آن را برای توضیح متنی به API درواره بفرستید.
جمعبندی
SciPy یکی از مهمترین اجزای اکوسیستم علمی پایتون است. این کتابخانه فاصله میان آرایههای NumPy و الگوریتمهای تخصصی مهندسی، آماری و عددی را پر میکند.
با SciPy میتوان:
- تابع را بهینه کرد
- ریشه معادله را پیدا کرد
- منحنی را روی داده برازش داد
- انتگرال را عددی محاسبه کرد
- معادله دیفرانسیل را حل کرد
- داده را Interpolate کرد
- آزمون آماری اجرا کرد
- Signal را فیلتر و تحلیل کرد
- ماتریس Sparse ساخت
- فاصله و نزدیکترین همسایه را محاسبه کرد
در یک پروژه تحلیل داده و هوش مصنوعی، تقسیم مسئولیت مناسب چنین است:
- Pandas برای خواندن و پاکسازی داده
- NumPy برای آرایه و محاسبات برداری
- SciPy برای الگوریتمهای علمی و آماری
- Matplotlib، Seaborn یا Plotly برای مصورسازی
- مدل زبانی برای توضیح و تولید گزارش
- درواره برای دسترسی API یکپارچه به مدل موردنیاز
برای شروع استفاده از مدلهای هوش مصنوعی، در درواره ثبتنام کنید، API Key بگیرید و مدل مناسب پروژه را از صفحه مدلها و قیمتها انتخاب کنید.
مقالات مرتبط
- آموزش تحلیل فایل CSV با هوش مصنوعی
- آموزش ساخت نمودار با هوش مصنوعی از روی داده
- هوش مصنوعی برای Excel، فرمولنویسی و تحلیل داده
- آموزش کامل ارزیابی مدلهای هوش مصنوعی
- آموزش دریافت API Key هوش مصنوعی
- راهنمای اتصال API هوش مصنوعی به برنامه
برای مطالعه شرایط استفاده و محدودیتهای مسئولیت، صفحه «سلب مسئولیت» را مشاهده کنید.