# python/02-advanced-analytics.py"""Advanced analytics patterns including clustering, dimensionality reduction, and time series analysis"""fromtypingimportList,Dict,Any,Optional,Union,Tupleimportpandasaspdimportnumpyasnpfromsklearn.clusterimportKMeans,DBSCAN,AgglomerativeClusteringfromsklearn.decompositionimportPCA,t-SNEfromsklearn.preprocessingimportStandardScaler,MinMaxScalerfromsklearn.metricsimportsilhouette_score,calinski_harabasz_scorefromsklearn.ensembleimportIsolationForestfromsklearn.manifoldimportTSNEimportmatplotlib.pyplotaspltimportseabornassnsfromdatetimeimportdatetime,timedeltaimportwarningswarnings.filterwarnings('ignore')classClusteringAnalyzer:"""Advanced clustering analysis"""def__init__(self,data:pd.DataFrame):self.data=dataself.numeric_data=data.select_dtypes(include=[np.number])self.scaler=StandardScaler()self.scaled_data=Noneself.cluster_results={}defprepare_data(self)->None:"""Prepare data for clustering"""self.scaled_data=self.scaler.fit_transform(self.numeric_data)defkmeans_clustering(self,n_clusters:int=3)->Dict[str,Any]:"""Perform K-means clustering"""ifself.scaled_dataisNone:self.prepare_data()kmeans=KMeans(n_clusters=n_clusters,random_state=42)cluster_labels=kmeans.fit_predict(self.scaled_data)# Calculate metricssilhouette_avg=silhouette_score(self.scaled_data,cluster_labels)calinski_harabasz=calinski_harabasz_score(self.scaled_data,cluster_labels)result={"n_clusters":n_clusters,"cluster_labels":cluster_labels.tolist(),"cluster_centers":kmeans.cluster_centers_.tolist(),"silhouette_score":silhouette_avg,"calinski_harabasz_score":calinski_harabasz,"inertia":kmeans.inertia_}self.cluster_results["kmeans"]=resultreturnresultdefdbscan_clustering(self,eps:float=0.5,min_samples:int=5)->Dict[str,Any]:"""Perform DBSCAN clustering"""ifself.scaled_dataisNone:self.prepare_data()dbscan=DBSCAN(eps=eps,min_samples=min_samples)cluster_labels=dbscan.fit_predict(self.scaled_data)n_clusters=len(set(cluster_labels))-(1if-1incluster_labelselse0)n_noise=list(cluster_labels).count(-1)result={"n_clusters":n_clusters,"n_noise":n_noise,"cluster_labels":cluster_labels.tolist(),"eps":eps,"min_samples":min_samples}self.cluster_results["dbscan"]=resultreturnresultdefhierarchical_clustering(self,n_clusters:int=3)->Dict[str,Any]:"""Perform hierarchical clustering"""ifself.scaled_dataisNone:self.prepare_data()hierarchical=AgglomerativeClustering(n_clusters=n_clusters)cluster_labels=hierarchical.fit_predict(self.scaled_data)result={"n_clusters":n_clusters,"cluster_labels":cluster_labels.tolist(),"linkage":"ward"}self.cluster_results["hierarchical"]=resultreturnresultdeffind_optimal_clusters(self,max_clusters:int=10)->Dict[str,Any]:"""Find optimal number of clusters using elbow method and silhouette analysis"""ifself.scaled_dataisNone:self.prepare_data()inertias=[]silhouette_scores=[]k_range=range(2,max_clusters+1)forkink_range:kmeans=KMeans(n_clusters=k,random_state=42)cluster_labels=kmeans.fit_predict(self.scaled_data)inertias.append(kmeans.inertia_)silhouette_scores.append(silhouette_score(self.scaled_data,cluster_labels))# Find optimal koptimal_k=k_range[np.argmax(silhouette_scores)]result={"k_range":list(k_range),"inertias":inertias,"silhouette_scores":silhouette_scores,"optimal_k":optimal_k,"max_silhouette_score":max(silhouette_scores)}self.cluster_results["optimal_clusters"]=resultreturnresultclassDimensionalityReducer:"""Dimensionality reduction analysis"""def__init__(self,data:pd.DataFrame):self.data=dataself.numeric_data=data.select_dtypes(include=[np.number])self.scaler=StandardScaler()self.scaled_data=Noneself.reduction_results={}defprepare_data(self)->None:"""Prepare data for dimensionality reduction"""self.scaled_data=self.scaler.fit_transform(self.numeric_data)defpca_analysis(self,n_components:int=2)->Dict[str,Any]:"""Perform PCA analysis"""ifself.scaled_dataisNone:self.prepare_data()pca=PCA(n_components=n_components)pca_result=pca.fit_transform(self.scaled_data)result={"n_components":n_components,"explained_variance_ratio":pca.explained_variance_ratio_.tolist(),"cumulative_variance_ratio":np.cumsum(pca.explained_variance_ratio_).tolist(),"components":pca.components_.tolist(),"transformed_data":pca_result.tolist()}self.reduction_results["pca"]=resultreturnresultdeftsne_analysis(self,n_components:int=2,perplexity:float=30)->Dict[str,Any]:"""Perform t-SNE analysis"""ifself.scaled_dataisNone:self.prepare_data()tsne=TSNE(n_components=n_components,perplexity=perplexity,random_state=42)tsne_result=tsne.fit_transform(self.scaled_data)result={"n_components":n_components,"perplexity":perplexity,"transformed_data":tsne_result.tolist(),"kl_divergence":tsne.kl_divergence_}self.reduction_results["tsne"]=resultreturnresultdeffind_optimal_components(self,max_components:int=None)->Dict[str,Any]:"""Find optimal number of components for PCA"""ifself.scaled_dataisNone:self.prepare_data()ifmax_componentsisNone:max_components=min(self.scaled_data.shape[1],10)pca_full=PCA()pca_full.fit(self.scaled_data)explained_variance_ratio=pca_full.explained_variance_ratio_cumulative_variance=np.cumsum(explained_variance_ratio)# Find number of components that explain 95% of variancen_components_95=np.argmax(cumulative_variance>=0.95)+1result={"explained_variance_ratio":explained_variance_ratio.tolist(),"cumulative_variance":cumulative_variance.tolist(),"n_components_95_variance":n_components_95,"total_variance_explained":cumulative_variance[-1]}self.reduction_results["optimal_components"]=resultreturnresultclassTimeSeriesAnalyzer:"""Time series analysis utilities"""def__init__(self,data:pd.DataFrame,date_col:str,value_col:str):self.data=data.copy()self.date_col=date_colself.value_col=value_colself.time_series=Noneself.analysis_results={}defprepare_time_series(self)->None:"""Prepare time series data"""self.data[self.date_col]=pd.to_datetime(self.data[self.date_col])self.data=self.data.sort_values(self.date_col)self.time_series=self.data.set_index(self.date_col)[self.value_col]deftrend_analysis(self)->Dict[str,Any]:"""Analyze time series trend"""ifself.time_seriesisNone:self.prepare_time_series()# Linear trendx=np.arange(len(self.time_series))slope,intercept,r_value,p_value,std_err=stats.linregress(x,self.time_series.values)# Moving averagesma_7=self.time_series.rolling(window=7).mean()ma_30=self.time_series.rolling(window=30).mean()result={"slope":slope,"intercept":intercept,"r_squared":r_value**2,"p_value":p_value,"trend_direction":"increasing"ifslope>0else"decreasing","moving_average_7":ma_7.dropna().tolist(),"moving_average_30":ma_30.dropna().tolist()}self.analysis_results["trend"]=resultreturnresultdefseasonality_analysis(self)->Dict[str,Any]:"""Analyze seasonality patterns"""ifself.time_seriesisNone:self.prepare_time_series()# Add time componentsself.data['year']=self.data[self.date_col].dt.yearself.data['month']=self.data[self.date_col].dt.monthself.data['day_of_week']=self.data[self.date_col].dt.dayofweek# Monthly patternsmonthly_avg=self.data.groupby('month')[self.value_col].mean()yearly_avg=self.data.groupby('year')[self.value_col].mean()weekday_avg=self.data.groupby('day_of_week')[self.value_col].mean()result={"monthly_patterns":monthly_avg.to_dict(),"yearly_patterns":yearly_avg.to_dict(),"weekday_patterns":weekday_avg.to_dict(),"seasonal_strength":monthly_avg.std()/monthly_avg.mean()ifmonthly_avg.mean()!=0else0}self.analysis_results["seasonality"]=resultreturnresultdefstationarity_test(self)->Dict[str,Any]:"""Test for stationarity using Augmented Dickey-Fuller test"""ifself.time_seriesisNone:self.prepare_time_series()fromstatsmodels.tsa.stattoolsimportadfulleradf_result=adfuller(self.time_series.dropna())result={"adf_statistic":adf_result[0],"p_value":adf_result[1],"critical_values":adf_result[4],"is_stationary":adf_result[1]<0.05}self.analysis_results["stationarity"]=resultreturnresultclassAnomalyDetector:"""Anomaly detection utilities"""def__init__(self,data:pd.DataFrame):self.data=dataself.numeric_data=data.select_dtypes(include=[np.number])self.anomaly_results={}defisolation_forest(self,contamination:float=0.1)->Dict[str,Any]:"""Detect anomalies using Isolation Forest"""iso_forest=IsolationForest(contamination=contamination,random_state=42)anomaly_labels=iso_forest.fit_predict(self.numeric_data)anomalies=self.data[anomaly_labels==-1]anomaly_scores=iso_forest.decision_function(self.numeric_data)result={"n_anomalies":len(anomalies),"anomaly_percentage":(len(anomalies)/len(self.data))*100,"anomaly_indices":anomalies.index.tolist(),"anomaly_scores":anomaly_scores.tolist(),"contamination":contamination}self.anomaly_results["isolation_forest"]=resultreturnresultdefstatistical_outliers(self,method:str="iqr")->Dict[str,Any]:"""Detect statistical outliers"""outliers={}forcolinself.numeric_data.columns:ifmethod=="iqr":Q1=self.numeric_data[col].quantile(0.25)Q3=self.numeric_data[col].quantile(0.75)IQR=Q3-Q1lower_bound=Q1-1.5*IQRupper_bound=Q3+1.5*IQRoutlier_mask=(self.numeric_data[col]<lower_bound)|(self.numeric_data[col]>upper_bound)elifmethod=="zscore":z_scores=np.abs(stats.zscore(self.numeric_data[col]))outlier_mask=z_scores>3else:continueoutliers[col]={"count":outlier_mask.sum(),"percentage":(outlier_mask.sum()/len(self.numeric_data))*100,"indices":self.numeric_data[outlier_mask].index.tolist()}result={"method":method,"outliers_by_column":outliers,"total_outliers":sum(col_data["count"]forcol_datainoutliers.values())}self.anomaly_results["statistical"]=resultreturnresult# Usage examplesdefexample_advanced_analytics():"""Example advanced analytics usage"""# Create sample datanp.random.seed(42)n_samples=1000data=pd.DataFrame({'feature1':np.random.normal(0,1,n_samples),'feature2':np.random.normal(0,1,n_samples),'feature3':np.random.normal(0,1,n_samples),'feature4':np.random.normal(0,1,n_samples),'feature5':np.random.normal(0,1,n_samples),'category':np.random.choice(['A','B','C'],n_samples)})# Clustering analysiscluster_analyzer=ClusteringAnalyzer(data)kmeans_result=cluster_analyzer.kmeans_clustering(n_clusters=3)print(f"K-means clustering: {kmeans_result['silhouette_score']:.3f}")optimal_clusters=cluster_analyzer.find_optimal_clusters(max_clusters=10)print(f"Optimal clusters: {optimal_clusters['optimal_k']}")# Dimensionality reductionreducer=DimensionalityReducer(data)pca_result=reducer.pca_analysis(n_components=2)print(f"PCA explained variance: {pca_result['explained_variance_ratio']}")tsne_result=reducer.tsne_analysis(n_components=2)print(f"t-SNE KL divergence: {tsne_result['kl_divergence']:.3f}")# Time series analysis (with sample time series data)dates=pd.date_range(start='2020-01-01',end='2023-12-31',freq='D')values=np.random.normal(100,10,len(dates))+np.sin(np.arange(len(dates))*2*np.pi/365)*5ts_data=pd.DataFrame({'date':dates,'value':values})ts_analyzer=TimeSeriesAnalyzer(ts_data,'date','value')trend_result=ts_analyzer.trend_analysis()print(f"Trend direction: {trend_result['trend_direction']}")seasonality_result=ts_analyzer.seasonality_analysis()print(f"Seasonal strength: {seasonality_result['seasonal_strength']:.3f}")# Anomaly detectionanomaly_detector=AnomalyDetector(data)iso_forest_result=anomaly_detector.isolation_forest(contamination=0.1)print(f"Anomalies detected: {iso_forest_result['n_anomalies']}")statistical_outliers=anomaly_detector.statistical_outliers(method="iqr")print(f"Statistical outliers: {statistical_outliers['total_outliers']}")
# Complete data analysis setupdefsetup_data_analysis():"""Setup complete data analysis environment"""# Data analyzeranalyzer=DataAnalyzer(data)# Data visualizervisualizer=DataVisualizer(data)# Statistical analyzerstat_analyzer=StatisticalAnalyzer(data)# Clustering analyzercluster_analyzer=ClusteringAnalyzer(data)# Dimensionality reducerreducer=DimensionalityReducer(data)# Time series analyzerts_analyzer=TimeSeriesAnalyzer(data,'date_col','value_col')# Anomaly detectoranomaly_detector=AnomalyDetector(data)print("Data analysis setup complete!")