G2PInsight 1.1.2__tar.gz → 1.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight/__init__.py +1 -1
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight/bin/modeltraining.py +24 -12
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight/bin/plink_ld.py +2 -2
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight/bin/preprocess.py +18 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight.egg-info/PKG-INFO +17 -9
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight.egg-info/requires.txt +1 -1
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/PKG-INFO +17 -9
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/README.md +15 -7
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/pyproject.toml +3 -2
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight/bin/__init__.py +0 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight/bin/font_utils.py +0 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight/bin/gemma_gwas.py +0 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight/bin/software/gemma-0.98.5-linux-static-AMD64 +0 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight/bin/software/plink +0 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight/bin/visualization.py +0 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight/main.py +0 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight.egg-info/SOURCES.txt +0 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight.egg-info/dependency_links.txt +0 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight.egg-info/entry_points.txt +0 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight.egg-info/top_level.txt +0 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/LICENSE +0 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/MANIFEST.in +0 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/setup.cfg +0 -0
- {g2pinsight-1.1.2 → g2pinsight-1.1.4}/setup.py +0 -0
|
@@ -848,7 +848,7 @@ def resolve_training_hyperparameters(model_type: str, task_type: str, X_train: p
|
|
|
848
848
|
scoring = 'neg_mean_squared_error'
|
|
849
849
|
base_model = init_model(model_type, task_type, random_state=random_state, cpu_cores=cpu_cores)
|
|
850
850
|
search = RandomizedSearchCV(estimator=base_model, param_distributions=param_grid, n_iter=n_iter, cv=cv_splitter, scoring=scoring, n_jobs=DEFAULT_N_JOBS, random_state=random_state, verbose=0)
|
|
851
|
-
search.fit(X_search, y_search)
|
|
851
|
+
search.fit(_features_for_estimator(model_type, X_search), y_search)
|
|
852
852
|
tuned_model = search.best_estimator_
|
|
853
853
|
return (tuned_model, tuned_model.get_params())
|
|
854
854
|
TRAIN_TEST_HOLDOUT_RATIO = 0.20
|
|
@@ -907,16 +907,25 @@ def resolve_holdout_split_from_metadata(X: pd.DataFrame, y: pd.Series, metadata:
|
|
|
907
907
|
return holdout_from_sample_split(X, y, sample_split)
|
|
908
908
|
logger.warning('Metadata missing sample_split; falling back to local reproducible 80/20 split. Re-run preprocess to fix the split at feature-selection time.')
|
|
909
909
|
return split_train_test_holdout(X, y, task_type=task_type, test_ratio=TRAIN_TEST_HOLDOUT_RATIO, random_state=random_state)
|
|
910
|
+
def _is_catboost_model(model: Any) -> bool:
|
|
911
|
+
return isinstance(model, (CatBoostClassifier, CatBoostRegressor))
|
|
912
|
+
def _features_for_estimator(model_or_type: Any, X: Any) -> Any:
|
|
913
|
+
"""CatBoost+pandas2: old CatBoost calls DataFrame.iteritems (removed); use ndarray."""
|
|
914
|
+
use_numpy = model_or_type == 'CatBoost' if isinstance(model_or_type, str) else _is_catboost_model(model_or_type)
|
|
915
|
+
if use_numpy and isinstance(X, (pd.DataFrame, pd.Series)):
|
|
916
|
+
return np.asarray(X)
|
|
917
|
+
return X
|
|
910
918
|
def _predict_with_optional_proba(model: Any, X: pd.DataFrame, task_type: str) -> Tuple[np.ndarray, Optional[np.ndarray]]:
|
|
911
|
-
|
|
919
|
+
X_in = _features_for_estimator(model, X)
|
|
920
|
+
y_pred = model.predict(X_in)
|
|
912
921
|
y_prob = None
|
|
913
922
|
if task_type != 'classification':
|
|
914
923
|
return (y_pred, None)
|
|
915
924
|
try:
|
|
916
925
|
if hasattr(model, 'predict_proba'):
|
|
917
|
-
y_prob = model.predict_proba(
|
|
926
|
+
y_prob = model.predict_proba(X_in)
|
|
918
927
|
elif hasattr(model, 'decision_function'):
|
|
919
|
-
decision_scores = model.decision_function(
|
|
928
|
+
decision_scores = model.decision_function(X_in)
|
|
920
929
|
from sklearn.utils.extmath import softmax
|
|
921
930
|
if len(decision_scores.shape) == 1:
|
|
922
931
|
prob_neg = 1 / (1 + np.exp(decision_scores))
|
|
@@ -933,7 +942,7 @@ def _fit_model_with_params(model_type: str, task_type: str, X_train: pd.DataFram
|
|
|
933
942
|
model.set_params(**best_params)
|
|
934
943
|
except ValueError as e:
|
|
935
944
|
pass
|
|
936
|
-
model.fit(X_train, y_train)
|
|
945
|
+
model.fit(_features_for_estimator(model_type, X_train), y_train)
|
|
937
946
|
return model
|
|
938
947
|
def evaluate_model(y_true: pd.Series, y_pred: np.ndarray, y_prob: np.ndarray, task_type: str) -> Dict:
|
|
939
948
|
metrics = {}
|
|
@@ -1091,14 +1100,16 @@ def _run_one_cv_fold(fold_idx: int, n_folds: int, train_idx: np.ndarray, val_idx
|
|
|
1091
1100
|
y_pred_fold = None
|
|
1092
1101
|
y_prob_fold = None
|
|
1093
1102
|
try:
|
|
1094
|
-
|
|
1095
|
-
|
|
1103
|
+
X_tr = _features_for_estimator(model_type, X_train_fold)
|
|
1104
|
+
X_va = _features_for_estimator(model_type, X_val_fold)
|
|
1105
|
+
model_fold.fit(X_tr, y_train_fold)
|
|
1106
|
+
y_pred_fold = model_fold.predict(X_va)
|
|
1096
1107
|
if task_type == 'classification':
|
|
1097
1108
|
try:
|
|
1098
1109
|
if hasattr(model_fold, 'predict_proba'):
|
|
1099
|
-
y_prob_fold = model_fold.predict_proba(
|
|
1110
|
+
y_prob_fold = model_fold.predict_proba(X_va)
|
|
1100
1111
|
elif hasattr(model_fold, 'decision_function'):
|
|
1101
|
-
decision_scores = model_fold.decision_function(
|
|
1112
|
+
decision_scores = model_fold.decision_function(X_va)
|
|
1102
1113
|
from sklearn.utils.extmath import softmax
|
|
1103
1114
|
if len(decision_scores.shape) == 1:
|
|
1104
1115
|
prob_neg = 1 / (1 + np.exp(decision_scores))
|
|
@@ -1279,7 +1290,7 @@ def calculate_shap_values(model: Any, model_type: str, feature_names: List[str],
|
|
|
1279
1290
|
y_shap = y_shap.loc[X_input.index]
|
|
1280
1291
|
if model_type in ['LightGBM', 'XGBoost', 'CatBoost', 'RandomForest']:
|
|
1281
1292
|
explainer = shap.TreeExplainer(model)
|
|
1282
|
-
shap_values = explainer.shap_values(X_input)
|
|
1293
|
+
shap_values = explainer.shap_values(_features_for_estimator(model_type, X_input))
|
|
1283
1294
|
elif model_type == 'Logistic':
|
|
1284
1295
|
explainer = shap.LinearExplainer(model, X_input)
|
|
1285
1296
|
shap_values = explainer.shap_values(X_input)
|
|
@@ -2008,8 +2019,9 @@ def predict_with_model(input_path: str, model_path: str, output_dir: str, task_t
|
|
|
2008
2019
|
non_zero_counts = (X_aligned != 0).sum(axis=1)
|
|
2009
2020
|
if (non_zero_counts == 0).all():
|
|
2010
2021
|
logger.error(f' ERROR: All feature values are zero! This will result in constant predictions.\n Matched features: {matched_count}\n Missing features: {missing_count}\n Please check if chr_pos keys match between training and prediction data.')
|
|
2011
|
-
|
|
2012
|
-
|
|
2022
|
+
X_pred = _features_for_estimator(model, X_aligned)
|
|
2023
|
+
y_pred = model.predict(X_pred)
|
|
2024
|
+
y_prob = model.predict_proba(X_pred) if resolved_task_type == 'classification' and hasattr(model, 'predict_proba') else None
|
|
2013
2025
|
unique_predictions = len(np.unique(y_pred))
|
|
2014
2026
|
if unique_predictions == 1:
|
|
2015
2027
|
logger.error(f" ERROR: All predictions are the same value: {y_pred[0]}\n This usually indicates one of the following issues:\n 1. chr_pos keys don't match between training and prediction data\n 2. All feature values are zero (check matched features: {matched_count})\n 3. Model is predicting a constant value for all samples\n Please check the feature alignment logs above.")
|
|
@@ -161,9 +161,9 @@ def run_ld_filtering(input_path: str, output_prefix: str, ld_window_kb: int=50,
|
|
|
161
161
|
return 1
|
|
162
162
|
if not check_prune_file_exists(output_prefix):
|
|
163
163
|
return 1
|
|
164
|
+
# Prune may use --keep (e.g. train-only LD), but the final bed must keep
|
|
165
|
+
# all input samples so held-out test IDs remain in the training matrix.
|
|
164
166
|
extract_args = input_args + ['--extract', f'{output_prefix_abs}.prune.in', '--make-bed', '--allow-extra-chr', '--allow-no-sex', '--threads', str(threads), '--out', output_prefix_abs]
|
|
165
|
-
if keep_samples_file:
|
|
166
|
-
extract_args.extend(['--keep', keep_samples_file])
|
|
167
167
|
if not run_plink_command(plink_executable, extract_args, 'Extracting SNPs to generate bed/bim/fam'):
|
|
168
168
|
return 1
|
|
169
169
|
bed_file = Path(f'{output_prefix_abs}.bed')
|
|
@@ -1019,6 +1019,23 @@ def _validate_ids_file_pair(train_ids_file: Optional[str], test_ids_file: Option
|
|
|
1019
1019
|
has_test = test_ids_file is not None
|
|
1020
1020
|
if has_train ^ has_test:
|
|
1021
1021
|
raise ValueError('Both --train-ids-file and --test-ids-file must be provided together')
|
|
1022
|
+
def _reconcile_sample_split_with_matrix(sample_split: Dict[str, Any], matrix_sample_ids: List[str]) -> Dict[str, Any]:
|
|
1023
|
+
"""Keep sample_split IDs that actually appear in the exported training matrix."""
|
|
1024
|
+
matrix_set = {str(s) for s in matrix_sample_ids}
|
|
1025
|
+
train_ids = [str(s) for s in sample_split.get('train_ids') or [] if str(s) in matrix_set]
|
|
1026
|
+
test_ids = [str(s) for s in sample_split.get('test_ids') or [] if str(s) in matrix_set]
|
|
1027
|
+
dropped_train = len(sample_split.get('train_ids') or []) - len(train_ids)
|
|
1028
|
+
dropped_test = len(sample_split.get('test_ids') or []) - len(test_ids)
|
|
1029
|
+
if dropped_train or dropped_test:
|
|
1030
|
+
logger.warning(f'sample_split vs matrix: dropped {dropped_train} train / {dropped_test} test ID(s) absent from the genotype matrix')
|
|
1031
|
+
if not train_ids or not test_ids:
|
|
1032
|
+
raise RuntimeError(f'After building the training matrix, sample_split is invalid (n_train={len(train_ids)}, n_test={len(test_ids)}). Re-run preprocess; if using -f 3/4, ensure LD export keeps all samples.')
|
|
1033
|
+
out = dict(sample_split)
|
|
1034
|
+
out['train_ids'] = train_ids
|
|
1035
|
+
out['test_ids'] = test_ids
|
|
1036
|
+
out['n_train'] = len(train_ids)
|
|
1037
|
+
out['n_test'] = len(test_ids)
|
|
1038
|
+
return out
|
|
1022
1039
|
def resolve_sample_split(sample_ids: List[str], pheno_df: pd.DataFrame, task_type: str, train_ids_file: Optional[str]=None, test_ids_file: Optional[str]=None, test_ratio: float=TRAIN_TEST_HOLDOUT_RATIO, random_state: int=DEFAULT_SPLIT_RANDOM_STATE) -> Dict[str, Any]:
|
|
1023
1040
|
_validate_ids_file_pair(train_ids_file, test_ids_file)
|
|
1024
1041
|
sample_ids_str = [str(s) for s in sample_ids]
|
|
@@ -1247,6 +1264,7 @@ def run_preprocess(genotype_path: str, genotype_format: GenotypeFormat, phenotyp
|
|
|
1247
1264
|
actual_train_file = matrix_output.train_file
|
|
1248
1265
|
includes_phenotype_column = matrix_output.includes_phenotype_column
|
|
1249
1266
|
n_snp_features = matrix_output.n_snp_features
|
|
1267
|
+
sample_split = _reconcile_sample_split_with_matrix(sample_split, matrix_output.sample_ids)
|
|
1250
1268
|
generate_metadata(output_prefix=str(stage_output_dir / output_prefix), plink_prefix=gwas_genotype_prefix, train_file=actual_train_file, valid_samples=matrix_output.sample_ids, genotype_format=genotype_format, task_type=task_type, preprocess_tmp_dir=tmp_dir, filter_snps=filter_snps, feature_selection_mode=feature_selection_mode, gwas_pvalue=gwas_pvalue, ld_window_kb=ld_window_kb, ld_window=ld_window, ld_window_r2=ld_window_r2, n_feature_columns=n_snp_features, includes_phenotype_column=includes_phenotype_column, sample_split=sample_split)
|
|
1251
1269
|
logger.info(f'Preprocess completed: {len(matrix_output.sample_ids):,} samples × {n_snp_features:,} SNPs (mode={feature_selection_mode}, split={sample_split["mode"]})')
|
|
1252
1270
|
gc.collect()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: G2PInsight
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.4
|
|
4
4
|
Summary: Genome-wide association analysis toolkit
|
|
5
5
|
Author-email: chenrf <2010288571@qq.com>
|
|
6
6
|
License: MIT
|
|
@@ -38,7 +38,7 @@ Requires-Dist: lightgbm<4.0.0,>=3.3; python_version < "3.13"
|
|
|
38
38
|
Requires-Dist: lightgbm>=4.0; python_version >= "3.13"
|
|
39
39
|
Requires-Dist: xgboost<2.1,>=1.6; python_version < "3.13"
|
|
40
40
|
Requires-Dist: xgboost>=2.1; python_version >= "3.13"
|
|
41
|
-
Requires-Dist: catboost<2.0,>=1.
|
|
41
|
+
Requires-Dist: catboost<2.0,>=1.2
|
|
42
42
|
Requires-Dist: shap>=0.40; python_version < "3.13"
|
|
43
43
|
Requires-Dist: shap>=0.48; python_version >= "3.13"
|
|
44
44
|
Requires-Dist: plotly>=5.0
|
|
@@ -183,26 +183,26 @@ wget -r -np -nH --cut-dirs=1 -R "index.html*" https://pr-nxy.ynu.edu.cn/G2PInsig
|
|
|
183
183
|
**Alternative — `git clone`:** the same files are in the GitHub repo under `data/` (~53 MB VCF; clone may be slow on some networks).
|
|
184
184
|
|
|
185
185
|
```bash
|
|
186
|
-
# 1. Preprocess
|
|
186
|
+
# 1. Preprocess → test/preprocess/preprocess/preprocess_metadata.json
|
|
187
187
|
G2PInsight preprocess --vcf data/genotype.vcf -p data/pheno.txt -o test/preprocess
|
|
188
188
|
```
|
|
189
189
|
```bash
|
|
190
|
-
# 2. Train
|
|
190
|
+
# 2. Train → test/train/train/LightGBM/
|
|
191
191
|
G2PInsight train -j test/preprocess/preprocess/preprocess_metadata.json -m LightGBM -o test/train
|
|
192
192
|
```
|
|
193
193
|
```bash
|
|
194
|
-
# 3. Visualize
|
|
194
|
+
# 3. Visualize → test/plot/visualize/lightgbm_*
|
|
195
195
|
G2PInsight visualize \
|
|
196
|
-
-i test/train/LightGBM/LightGBM_shap_values.txt \
|
|
197
|
-
-I test/train/LightGBM/LightGBM_plotting_data.json \
|
|
198
|
-
-o
|
|
196
|
+
-i test/train/train/LightGBM/LightGBM_shap_values.txt \
|
|
197
|
+
-I test/train/train/LightGBM/LightGBM_plotting_data.json \
|
|
198
|
+
-o test/plot/lightgbm
|
|
199
199
|
```
|
|
200
200
|
|
|
201
201
|
**Larger SNP sets** — use preprocess feature selection (`-f 4`), then train conservatively:
|
|
202
202
|
|
|
203
203
|
```bash
|
|
204
204
|
G2PInsight preprocess --vcf data/genotype.vcf -p data/pheno.txt -o test/preprocess -f 4
|
|
205
|
-
G2PInsight train-all -j test/preprocess/preprocess/preprocess_metadata.json -o test/train
|
|
205
|
+
G2PInsight train-all -j test/preprocess/preprocess/preprocess_metadata.json -o test/train \
|
|
206
206
|
--parallel_models 1 --threads 4
|
|
207
207
|
```
|
|
208
208
|
|
|
@@ -535,6 +535,14 @@ Default is `--shap_dependence_top 50`. Use `0` only if you need all SNPs (can be
|
|
|
535
535
|
|
|
536
536
|
Your env has an old `bed-reader` (0.2.x). Upgrade: `pip install -U 'bed-reader>=1.0'`. Current G2PInsight also accepts the older `fam_filepath` API as a fallback.
|
|
537
537
|
|
|
538
|
+
### train / train-all: test IDs from metadata missing in matrix
|
|
539
|
+
|
|
540
|
+
Usually from an older preprocess with **`-f 3` / `-f 4`**: LD used train-only `--keep` and the final `.bed` dropped test samples while metadata still listed them. Fixed in current source — **re-run preprocess**, then train again.
|
|
541
|
+
|
|
542
|
+
### train-all / CatBoost: `DataFrame` has no attribute `iteritems`
|
|
543
|
+
|
|
544
|
+
Old CatBoost + **pandas 2.x** (removed `iteritems`). Current G2PInsight passes numpy arrays into CatBoost. Temporary workaround: `pip install -U 'catboost>=1.2,<2'` or `pip install 'pandas>=1.3,<2'`.
|
|
545
|
+
|
|
538
546
|
### train: XGBoost “Mismatched version … Python package … Shared object”
|
|
539
547
|
|
|
540
548
|
Usually **conda + pip mixed installs**: e.g. conda left `libxgboost.so` 2.0.x while pip upgraded the Python package to 3.x. Fix in the same env:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: G2PInsight
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.4
|
|
4
4
|
Summary: Genome-wide association analysis toolkit
|
|
5
5
|
Author-email: chenrf <2010288571@qq.com>
|
|
6
6
|
License: MIT
|
|
@@ -38,7 +38,7 @@ Requires-Dist: lightgbm<4.0.0,>=3.3; python_version < "3.13"
|
|
|
38
38
|
Requires-Dist: lightgbm>=4.0; python_version >= "3.13"
|
|
39
39
|
Requires-Dist: xgboost<2.1,>=1.6; python_version < "3.13"
|
|
40
40
|
Requires-Dist: xgboost>=2.1; python_version >= "3.13"
|
|
41
|
-
Requires-Dist: catboost<2.0,>=1.
|
|
41
|
+
Requires-Dist: catboost<2.0,>=1.2
|
|
42
42
|
Requires-Dist: shap>=0.40; python_version < "3.13"
|
|
43
43
|
Requires-Dist: shap>=0.48; python_version >= "3.13"
|
|
44
44
|
Requires-Dist: plotly>=5.0
|
|
@@ -183,26 +183,26 @@ wget -r -np -nH --cut-dirs=1 -R "index.html*" https://pr-nxy.ynu.edu.cn/G2PInsig
|
|
|
183
183
|
**Alternative — `git clone`:** the same files are in the GitHub repo under `data/` (~53 MB VCF; clone may be slow on some networks).
|
|
184
184
|
|
|
185
185
|
```bash
|
|
186
|
-
# 1. Preprocess
|
|
186
|
+
# 1. Preprocess → test/preprocess/preprocess/preprocess_metadata.json
|
|
187
187
|
G2PInsight preprocess --vcf data/genotype.vcf -p data/pheno.txt -o test/preprocess
|
|
188
188
|
```
|
|
189
189
|
```bash
|
|
190
|
-
# 2. Train
|
|
190
|
+
# 2. Train → test/train/train/LightGBM/
|
|
191
191
|
G2PInsight train -j test/preprocess/preprocess/preprocess_metadata.json -m LightGBM -o test/train
|
|
192
192
|
```
|
|
193
193
|
```bash
|
|
194
|
-
# 3. Visualize
|
|
194
|
+
# 3. Visualize → test/plot/visualize/lightgbm_*
|
|
195
195
|
G2PInsight visualize \
|
|
196
|
-
-i test/train/LightGBM/LightGBM_shap_values.txt \
|
|
197
|
-
-I test/train/LightGBM/LightGBM_plotting_data.json \
|
|
198
|
-
-o
|
|
196
|
+
-i test/train/train/LightGBM/LightGBM_shap_values.txt \
|
|
197
|
+
-I test/train/train/LightGBM/LightGBM_plotting_data.json \
|
|
198
|
+
-o test/plot/lightgbm
|
|
199
199
|
```
|
|
200
200
|
|
|
201
201
|
**Larger SNP sets** — use preprocess feature selection (`-f 4`), then train conservatively:
|
|
202
202
|
|
|
203
203
|
```bash
|
|
204
204
|
G2PInsight preprocess --vcf data/genotype.vcf -p data/pheno.txt -o test/preprocess -f 4
|
|
205
|
-
G2PInsight train-all -j test/preprocess/preprocess/preprocess_metadata.json -o test/train
|
|
205
|
+
G2PInsight train-all -j test/preprocess/preprocess/preprocess_metadata.json -o test/train \
|
|
206
206
|
--parallel_models 1 --threads 4
|
|
207
207
|
```
|
|
208
208
|
|
|
@@ -535,6 +535,14 @@ Default is `--shap_dependence_top 50`. Use `0` only if you need all SNPs (can be
|
|
|
535
535
|
|
|
536
536
|
Your env has an old `bed-reader` (0.2.x). Upgrade: `pip install -U 'bed-reader>=1.0'`. Current G2PInsight also accepts the older `fam_filepath` API as a fallback.
|
|
537
537
|
|
|
538
|
+
### train / train-all: test IDs from metadata missing in matrix
|
|
539
|
+
|
|
540
|
+
Usually from an older preprocess with **`-f 3` / `-f 4`**: LD used train-only `--keep` and the final `.bed` dropped test samples while metadata still listed them. Fixed in current source — **re-run preprocess**, then train again.
|
|
541
|
+
|
|
542
|
+
### train-all / CatBoost: `DataFrame` has no attribute `iteritems`
|
|
543
|
+
|
|
544
|
+
Old CatBoost + **pandas 2.x** (removed `iteritems`). Current G2PInsight passes numpy arrays into CatBoost. Temporary workaround: `pip install -U 'catboost>=1.2,<2'` or `pip install 'pandas>=1.3,<2'`.
|
|
545
|
+
|
|
538
546
|
### train: XGBoost “Mismatched version … Python package … Shared object”
|
|
539
547
|
|
|
540
548
|
Usually **conda + pip mixed installs**: e.g. conda left `libxgboost.so` 2.0.x while pip upgraded the Python package to 3.x. Fix in the same env:
|
|
@@ -134,26 +134,26 @@ wget -r -np -nH --cut-dirs=1 -R "index.html*" https://pr-nxy.ynu.edu.cn/G2PInsig
|
|
|
134
134
|
**Alternative — `git clone`:** the same files are in the GitHub repo under `data/` (~53 MB VCF; clone may be slow on some networks).
|
|
135
135
|
|
|
136
136
|
```bash
|
|
137
|
-
# 1. Preprocess
|
|
137
|
+
# 1. Preprocess → test/preprocess/preprocess/preprocess_metadata.json
|
|
138
138
|
G2PInsight preprocess --vcf data/genotype.vcf -p data/pheno.txt -o test/preprocess
|
|
139
139
|
```
|
|
140
140
|
```bash
|
|
141
|
-
# 2. Train
|
|
141
|
+
# 2. Train → test/train/train/LightGBM/
|
|
142
142
|
G2PInsight train -j test/preprocess/preprocess/preprocess_metadata.json -m LightGBM -o test/train
|
|
143
143
|
```
|
|
144
144
|
```bash
|
|
145
|
-
# 3. Visualize
|
|
145
|
+
# 3. Visualize → test/plot/visualize/lightgbm_*
|
|
146
146
|
G2PInsight visualize \
|
|
147
|
-
-i test/train/LightGBM/LightGBM_shap_values.txt \
|
|
148
|
-
-I test/train/LightGBM/LightGBM_plotting_data.json \
|
|
149
|
-
-o
|
|
147
|
+
-i test/train/train/LightGBM/LightGBM_shap_values.txt \
|
|
148
|
+
-I test/train/train/LightGBM/LightGBM_plotting_data.json \
|
|
149
|
+
-o test/plot/lightgbm
|
|
150
150
|
```
|
|
151
151
|
|
|
152
152
|
**Larger SNP sets** — use preprocess feature selection (`-f 4`), then train conservatively:
|
|
153
153
|
|
|
154
154
|
```bash
|
|
155
155
|
G2PInsight preprocess --vcf data/genotype.vcf -p data/pheno.txt -o test/preprocess -f 4
|
|
156
|
-
G2PInsight train-all -j test/preprocess/preprocess/preprocess_metadata.json -o test/train
|
|
156
|
+
G2PInsight train-all -j test/preprocess/preprocess/preprocess_metadata.json -o test/train \
|
|
157
157
|
--parallel_models 1 --threads 4
|
|
158
158
|
```
|
|
159
159
|
|
|
@@ -486,6 +486,14 @@ Default is `--shap_dependence_top 50`. Use `0` only if you need all SNPs (can be
|
|
|
486
486
|
|
|
487
487
|
Your env has an old `bed-reader` (0.2.x). Upgrade: `pip install -U 'bed-reader>=1.0'`. Current G2PInsight also accepts the older `fam_filepath` API as a fallback.
|
|
488
488
|
|
|
489
|
+
### train / train-all: test IDs from metadata missing in matrix
|
|
490
|
+
|
|
491
|
+
Usually from an older preprocess with **`-f 3` / `-f 4`**: LD used train-only `--keep` and the final `.bed` dropped test samples while metadata still listed them. Fixed in current source — **re-run preprocess**, then train again.
|
|
492
|
+
|
|
493
|
+
### train-all / CatBoost: `DataFrame` has no attribute `iteritems`
|
|
494
|
+
|
|
495
|
+
Old CatBoost + **pandas 2.x** (removed `iteritems`). Current G2PInsight passes numpy arrays into CatBoost. Temporary workaround: `pip install -U 'catboost>=1.2,<2'` or `pip install 'pandas>=1.3,<2'`.
|
|
496
|
+
|
|
489
497
|
### train: XGBoost “Mismatched version … Python package … Shared object”
|
|
490
498
|
|
|
491
499
|
Usually **conda + pip mixed installs**: e.g. conda left `libxgboost.so` 2.0.x while pip upgraded the Python package to 3.x. Fix in the same env:
|
|
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "G2PInsight"
|
|
10
|
-
version = "1.1.
|
|
10
|
+
version = "1.1.4"
|
|
11
11
|
description = "Genome-wide association analysis toolkit"
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
# Cap below 3.14: pandas/numpy for 3.14+ only ship manylinux_2_24+ wheels.
|
|
@@ -61,7 +61,8 @@ dependencies = [
|
|
|
61
61
|
"lightgbm>=4.0; python_version >= '3.13'",
|
|
62
62
|
"xgboost>=1.6,<2.1; python_version < '3.13'",
|
|
63
63
|
"xgboost>=2.1; python_version >= '3.13'",
|
|
64
|
-
|
|
64
|
+
# >=1.2: pandas 2.x removed DataFrame.iteritems; older CatBoost still calls it.
|
|
65
|
+
"catboost>=1.2,<2.0",
|
|
65
66
|
"shap>=0.40; python_version < '3.13'",
|
|
66
67
|
"shap>=0.48; python_version >= '3.13'",
|
|
67
68
|
"plotly>=5.0",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{g2pinsight-1.1.2 → g2pinsight-1.1.4}/G2PInsight/bin/software/gemma-0.98.5-linux-static-AMD64
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|