agwr


Nameagwr JSON
Version 1.2.0 PyPI version JSON
download
home_pagehttps://github.com/agwr-team/agwr
Summary各向异性地理加权回归模型实现
upload_time2025-09-01 11:42:16
maintainerNone
docs_urlNone
authorAGWR开发团队
requires_python>=3.8
licenseMIT
keywords geographically weighted regression spatial statistics anisotropy gwr agwr
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # AGWR - 各向异性地理加权回归模型

[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![PyPI version](https://badge.fury.io/py/agwr.svg)](https://badge.fury.io/py/agwr)

一个用于实现各向异性地理加权回归(Anisotropic Geographically Weighted Regression)的Python包。该包基于研究论文中的数学理论,提供了稳定、高效的AGWR模型实现。

## 功能特点

- **各向异性核函数**: 支持方向性距离计算和各向异性带宽参数
- **坐标投影**: 自动将地理坐标投影到平面坐标系以获得准确的距离计算
- **模型拟合**: 使用最大似然估计和L-BFGS-B优化算法
- **智能初始化**: 利用MGWR带宽选择器提供智能初始参数
- **模型诊断**: 提供AIC、残差分析等诊断工具
- **易于使用**: 简洁的API设计,类似scikit-learn的使用方式

## 安装

### 从PyPI安装(推荐)

```bash
pip install agwr
```

### 从源码安装

```bash
git clone https://github.com/agwr-team/agwr.git
cd agwr
pip install -e .
```

## 依赖要求

- Python >= 3.8
- numpy >= 1.20.0
- pandas >= 1.3.0
- scipy >= 1.7.0
- pyproj >= 3.0.0
- mgwr >= 2.1.0

## 快速开始

### 基本用法

```python
import pandas as pd
import numpy as np
from agwr import AGWR

# 准备数据
data = pd.DataFrame({
    'price': [1.2, 1.5, 1.8, 2.1, 1.9],  # 房价(万元/平方米)
    'pop': [100, 150, 200, 250, 180],     # 人口(万人)
    'gdp': [8, 10, 12, 15, 11],           # 人均GDP(万元)
    'density': [1000, 1200, 1500, 1800, 1300]  # 人口密度(人/平方公里)
})

# 地理坐标(经度,纬度)
coords = np.array([
    [116.4, 39.9],  # 北京
    [121.5, 31.2],  # 上海
    [113.3, 23.1],  # 广州
    [114.1, 22.5],  # 深圳
    [118.8, 32.0]   # 南京
])

# 定义变量类型
local_vars = ['intercept', 'gdp']      # 局部变量
global_vars = ['pop', 'density']       # 全局变量

# 添加截距项
data['intercept'] = 1.0

# 创建并拟合模型
model = AGWR(m=3)  # 使用3个空间节点
model.fit(data, data['price'], coords, local_vars, global_vars)

# 查看结果
print(f"AIC: {model.aic_:.4f}")
print("带宽参数:")
for var, theta in model.bandwidths_.items():
    print(f"  {var}: {theta}")

print("全局变量系数:")
for var, coef in model.coefficients_['global'].items():
    print(f"  {var}: {coef:.4f}")
```

### 高级用法

```python
# 使用自定义初始参数
model = AGWR(m=8)

# 拟合模型
model.fit(X, y, coords, local_vars, global_vars)

# 检查各向异性效果
for var, theta in model.bandwidths_.items():
    if var != 'intercept':
        anisotropy_ratio = theta[0] / theta[1]
        print(f"{var}各向异性比率: {anisotropy_ratio:.4f}")

# 获取拟合值和残差
fitted_values = model.fitted_values_
residuals = model.residuals_

# 进行预测(需要实现)
# predictions = model.predict(X_new, coords_new)
```

## 模型理论

AGWR模型基于以下数学公式:

### 各向异性核函数

```
K(h, θ) = exp(-∑(h²/θ))
```

其中:
- `h` 是方向性距离向量 `[h_u, h_v]`
- `θ` 是各向异性带宽向量 `[θ_u, θ_v]`

### 重构参数化方法

模型使用重构参数化方法来表示空间变化的系数:

```
β(x) = ∑ᵢ γᵢ bᵢ(x)
```

其中 `bᵢ(x)` 是基函数,`γᵢ` 是节点系数。

### 负对数似然函数

```
L = (n/2) log(2πσ²) + RSS/(2σ²)
```

其中 `RSS` 是残差平方和。

## API参考

### AGWR类

#### 初始化参数

- `m` (int): 重构方法的空间节点数量,默认为8

#### 主要方法

- `fit(X, y, coords, local_vars, global_vars)`: 拟合模型
- `predict(X, coords)`: 进行预测(待实现)

#### 属性

- `aic_`: Akaike信息准则
- `bandwidths_`: 各向异性带宽参数
- `coefficients_`: 模型系数
- `fitted_values_`: 拟合值
- `residuals_`: 残差
- `is_fitted_`: 模型是否已拟合

### 工具函数

- `anisotropic_kernel(h, theta)`: 计算各向异性核函数值
- `anisotropic_kernel_projected(coord1, coord2, theta)`: 使用投影坐标计算核函数
- `project_coordinates(coords)`: 将地理坐标投影到平面坐标系

## 测试

运行测试套件:

```bash
cd agwr_package
python -m pytest tests/
```

或者运行单个测试:

```bash
python tests/test_model.py
```

## 贡献

欢迎贡献代码!请遵循以下步骤:

1. Fork本仓库
2. 创建功能分支 (`git checkout -b feature/amazing-feature`)
3. 提交更改 (`git commit -m 'Add amazing feature'`)
4. 推送到分支 (`git push origin feature/amazing-feature`)
5. 创建Pull Request

## 许可证

本项目采用MIT许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。

## 引用

如果您在研究中使用了AGWR包,请引用相关论文:

```bibtex
@article{agwr2024,
  title={各向异性地理加权回归模型研究},
  author={AGWR开发团队},
  journal={空间统计学报},
  year={2024}
}
```

## 联系方式

- 项目主页: https://github.com/agwr-team/agwr
- 问题反馈: https://github.com/agwr-team/agwr/issues
- 邮箱: agwr@example.com

## 更新日志

### v1.0.0 (2024-01-01)
- 初始版本发布
- 实现基本的AGWR模型
- 支持各向异性核函数
- 提供坐标投影功能
- 包含完整的测试套件

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/agwr-team/agwr",
    "name": "agwr",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "AGWR\u5f00\u53d1\u56e2\u961f <agwr@example.com>",
    "keywords": "geographically weighted regression, spatial statistics, anisotropy, gwr, agwr",
    "author": "AGWR\u5f00\u53d1\u56e2\u961f",
    "author_email": "AGWR\u5f00\u53d1\u56e2\u961f <agwr@example.com>",
    "download_url": "https://files.pythonhosted.org/packages/40/9d/4296ff649e18bc4d5bb674472a986fed01993038cd38b3365a26ca6c0441/agwr-1.2.0.tar.gz",
    "platform": null,
    "description": "# AGWR - \u5404\u5411\u5f02\u6027\u5730\u7406\u52a0\u6743\u56de\u5f52\u6a21\u578b\n\n[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![PyPI version](https://badge.fury.io/py/agwr.svg)](https://badge.fury.io/py/agwr)\n\n\u4e00\u4e2a\u7528\u4e8e\u5b9e\u73b0\u5404\u5411\u5f02\u6027\u5730\u7406\u52a0\u6743\u56de\u5f52(Anisotropic Geographically Weighted Regression)\u7684Python\u5305\u3002\u8be5\u5305\u57fa\u4e8e\u7814\u7a76\u8bba\u6587\u4e2d\u7684\u6570\u5b66\u7406\u8bba\uff0c\u63d0\u4f9b\u4e86\u7a33\u5b9a\u3001\u9ad8\u6548\u7684AGWR\u6a21\u578b\u5b9e\u73b0\u3002\n\n## \u529f\u80fd\u7279\u70b9\n\n- **\u5404\u5411\u5f02\u6027\u6838\u51fd\u6570**: \u652f\u6301\u65b9\u5411\u6027\u8ddd\u79bb\u8ba1\u7b97\u548c\u5404\u5411\u5f02\u6027\u5e26\u5bbd\u53c2\u6570\n- **\u5750\u6807\u6295\u5f71**: \u81ea\u52a8\u5c06\u5730\u7406\u5750\u6807\u6295\u5f71\u5230\u5e73\u9762\u5750\u6807\u7cfb\u4ee5\u83b7\u5f97\u51c6\u786e\u7684\u8ddd\u79bb\u8ba1\u7b97\n- **\u6a21\u578b\u62df\u5408**: \u4f7f\u7528\u6700\u5927\u4f3c\u7136\u4f30\u8ba1\u548cL-BFGS-B\u4f18\u5316\u7b97\u6cd5\n- **\u667a\u80fd\u521d\u59cb\u5316**: \u5229\u7528MGWR\u5e26\u5bbd\u9009\u62e9\u5668\u63d0\u4f9b\u667a\u80fd\u521d\u59cb\u53c2\u6570\n- **\u6a21\u578b\u8bca\u65ad**: \u63d0\u4f9bAIC\u3001\u6b8b\u5dee\u5206\u6790\u7b49\u8bca\u65ad\u5de5\u5177\n- **\u6613\u4e8e\u4f7f\u7528**: \u7b80\u6d01\u7684API\u8bbe\u8ba1\uff0c\u7c7b\u4f3cscikit-learn\u7684\u4f7f\u7528\u65b9\u5f0f\n\n## \u5b89\u88c5\n\n### \u4ecePyPI\u5b89\u88c5\uff08\u63a8\u8350\uff09\n\n```bash\npip install agwr\n```\n\n### \u4ece\u6e90\u7801\u5b89\u88c5\n\n```bash\ngit clone https://github.com/agwr-team/agwr.git\ncd agwr\npip install -e .\n```\n\n## \u4f9d\u8d56\u8981\u6c42\n\n- Python >= 3.8\n- numpy >= 1.20.0\n- pandas >= 1.3.0\n- scipy >= 1.7.0\n- pyproj >= 3.0.0\n- mgwr >= 2.1.0\n\n## \u5feb\u901f\u5f00\u59cb\n\n### \u57fa\u672c\u7528\u6cd5\n\n```python\nimport pandas as pd\nimport numpy as np\nfrom agwr import AGWR\n\n# \u51c6\u5907\u6570\u636e\ndata = pd.DataFrame({\n    'price': [1.2, 1.5, 1.8, 2.1, 1.9],  # \u623f\u4ef7\uff08\u4e07\u5143/\u5e73\u65b9\u7c73\uff09\n    'pop': [100, 150, 200, 250, 180],     # \u4eba\u53e3\uff08\u4e07\u4eba\uff09\n    'gdp': [8, 10, 12, 15, 11],           # \u4eba\u5747GDP\uff08\u4e07\u5143\uff09\n    'density': [1000, 1200, 1500, 1800, 1300]  # \u4eba\u53e3\u5bc6\u5ea6\uff08\u4eba/\u5e73\u65b9\u516c\u91cc\uff09\n})\n\n# \u5730\u7406\u5750\u6807\uff08\u7ecf\u5ea6\uff0c\u7eac\u5ea6\uff09\ncoords = np.array([\n    [116.4, 39.9],  # \u5317\u4eac\n    [121.5, 31.2],  # \u4e0a\u6d77\n    [113.3, 23.1],  # \u5e7f\u5dde\n    [114.1, 22.5],  # \u6df1\u5733\n    [118.8, 32.0]   # \u5357\u4eac\n])\n\n# \u5b9a\u4e49\u53d8\u91cf\u7c7b\u578b\nlocal_vars = ['intercept', 'gdp']      # \u5c40\u90e8\u53d8\u91cf\nglobal_vars = ['pop', 'density']       # \u5168\u5c40\u53d8\u91cf\n\n# \u6dfb\u52a0\u622a\u8ddd\u9879\ndata['intercept'] = 1.0\n\n# \u521b\u5efa\u5e76\u62df\u5408\u6a21\u578b\nmodel = AGWR(m=3)  # \u4f7f\u75283\u4e2a\u7a7a\u95f4\u8282\u70b9\nmodel.fit(data, data['price'], coords, local_vars, global_vars)\n\n# \u67e5\u770b\u7ed3\u679c\nprint(f\"AIC: {model.aic_:.4f}\")\nprint(\"\u5e26\u5bbd\u53c2\u6570:\")\nfor var, theta in model.bandwidths_.items():\n    print(f\"  {var}: {theta}\")\n\nprint(\"\u5168\u5c40\u53d8\u91cf\u7cfb\u6570:\")\nfor var, coef in model.coefficients_['global'].items():\n    print(f\"  {var}: {coef:.4f}\")\n```\n\n### \u9ad8\u7ea7\u7528\u6cd5\n\n```python\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u521d\u59cb\u53c2\u6570\nmodel = AGWR(m=8)\n\n# \u62df\u5408\u6a21\u578b\nmodel.fit(X, y, coords, local_vars, global_vars)\n\n# \u68c0\u67e5\u5404\u5411\u5f02\u6027\u6548\u679c\nfor var, theta in model.bandwidths_.items():\n    if var != 'intercept':\n        anisotropy_ratio = theta[0] / theta[1]\n        print(f\"{var}\u5404\u5411\u5f02\u6027\u6bd4\u7387: {anisotropy_ratio:.4f}\")\n\n# \u83b7\u53d6\u62df\u5408\u503c\u548c\u6b8b\u5dee\nfitted_values = model.fitted_values_\nresiduals = model.residuals_\n\n# \u8fdb\u884c\u9884\u6d4b\uff08\u9700\u8981\u5b9e\u73b0\uff09\n# predictions = model.predict(X_new, coords_new)\n```\n\n## \u6a21\u578b\u7406\u8bba\n\nAGWR\u6a21\u578b\u57fa\u4e8e\u4ee5\u4e0b\u6570\u5b66\u516c\u5f0f\uff1a\n\n### \u5404\u5411\u5f02\u6027\u6838\u51fd\u6570\n\n```\nK(h, \u03b8) = exp(-\u2211(h\u00b2/\u03b8))\n```\n\n\u5176\u4e2d\uff1a\n- `h` \u662f\u65b9\u5411\u6027\u8ddd\u79bb\u5411\u91cf `[h_u, h_v]`\n- `\u03b8` \u662f\u5404\u5411\u5f02\u6027\u5e26\u5bbd\u5411\u91cf `[\u03b8_u, \u03b8_v]`\n\n### \u91cd\u6784\u53c2\u6570\u5316\u65b9\u6cd5\n\n\u6a21\u578b\u4f7f\u7528\u91cd\u6784\u53c2\u6570\u5316\u65b9\u6cd5\u6765\u8868\u793a\u7a7a\u95f4\u53d8\u5316\u7684\u7cfb\u6570\uff1a\n\n```\n\u03b2(x) = \u2211\u1d62 \u03b3\u1d62 b\u1d62(x)\n```\n\n\u5176\u4e2d `b\u1d62(x)` \u662f\u57fa\u51fd\u6570\uff0c`\u03b3\u1d62` \u662f\u8282\u70b9\u7cfb\u6570\u3002\n\n### \u8d1f\u5bf9\u6570\u4f3c\u7136\u51fd\u6570\n\n```\nL = (n/2) log(2\u03c0\u03c3\u00b2) + RSS/(2\u03c3\u00b2)\n```\n\n\u5176\u4e2d `RSS` \u662f\u6b8b\u5dee\u5e73\u65b9\u548c\u3002\n\n## API\u53c2\u8003\n\n### AGWR\u7c7b\n\n#### \u521d\u59cb\u5316\u53c2\u6570\n\n- `m` (int): \u91cd\u6784\u65b9\u6cd5\u7684\u7a7a\u95f4\u8282\u70b9\u6570\u91cf\uff0c\u9ed8\u8ba4\u4e3a8\n\n#### \u4e3b\u8981\u65b9\u6cd5\n\n- `fit(X, y, coords, local_vars, global_vars)`: \u62df\u5408\u6a21\u578b\n- `predict(X, coords)`: \u8fdb\u884c\u9884\u6d4b\uff08\u5f85\u5b9e\u73b0\uff09\n\n#### \u5c5e\u6027\n\n- `aic_`: Akaike\u4fe1\u606f\u51c6\u5219\n- `bandwidths_`: \u5404\u5411\u5f02\u6027\u5e26\u5bbd\u53c2\u6570\n- `coefficients_`: \u6a21\u578b\u7cfb\u6570\n- `fitted_values_`: \u62df\u5408\u503c\n- `residuals_`: \u6b8b\u5dee\n- `is_fitted_`: \u6a21\u578b\u662f\u5426\u5df2\u62df\u5408\n\n### \u5de5\u5177\u51fd\u6570\n\n- `anisotropic_kernel(h, theta)`: \u8ba1\u7b97\u5404\u5411\u5f02\u6027\u6838\u51fd\u6570\u503c\n- `anisotropic_kernel_projected(coord1, coord2, theta)`: \u4f7f\u7528\u6295\u5f71\u5750\u6807\u8ba1\u7b97\u6838\u51fd\u6570\n- `project_coordinates(coords)`: \u5c06\u5730\u7406\u5750\u6807\u6295\u5f71\u5230\u5e73\u9762\u5750\u6807\u7cfb\n\n## \u6d4b\u8bd5\n\n\u8fd0\u884c\u6d4b\u8bd5\u5957\u4ef6\uff1a\n\n```bash\ncd agwr_package\npython -m pytest tests/\n```\n\n\u6216\u8005\u8fd0\u884c\u5355\u4e2a\u6d4b\u8bd5\uff1a\n\n```bash\npython tests/test_model.py\n```\n\n## \u8d21\u732e\n\n\u6b22\u8fce\u8d21\u732e\u4ee3\u7801\uff01\u8bf7\u9075\u5faa\u4ee5\u4e0b\u6b65\u9aa4\uff1a\n\n1. Fork\u672c\u4ed3\u5e93\n2. \u521b\u5efa\u529f\u80fd\u5206\u652f (`git checkout -b feature/amazing-feature`)\n3. \u63d0\u4ea4\u66f4\u6539 (`git commit -m 'Add amazing feature'`)\n4. \u63a8\u9001\u5230\u5206\u652f (`git push origin feature/amazing-feature`)\n5. \u521b\u5efaPull Request\n\n## \u8bb8\u53ef\u8bc1\n\n\u672c\u9879\u76ee\u91c7\u7528MIT\u8bb8\u53ef\u8bc1 - \u67e5\u770b [LICENSE](LICENSE) \u6587\u4ef6\u4e86\u89e3\u8be6\u60c5\u3002\n\n## \u5f15\u7528\n\n\u5982\u679c\u60a8\u5728\u7814\u7a76\u4e2d\u4f7f\u7528\u4e86AGWR\u5305\uff0c\u8bf7\u5f15\u7528\u76f8\u5173\u8bba\u6587\uff1a\n\n```bibtex\n@article{agwr2024,\n  title={\u5404\u5411\u5f02\u6027\u5730\u7406\u52a0\u6743\u56de\u5f52\u6a21\u578b\u7814\u7a76},\n  author={AGWR\u5f00\u53d1\u56e2\u961f},\n  journal={\u7a7a\u95f4\u7edf\u8ba1\u5b66\u62a5},\n  year={2024}\n}\n```\n\n## \u8054\u7cfb\u65b9\u5f0f\n\n- \u9879\u76ee\u4e3b\u9875: https://github.com/agwr-team/agwr\n- \u95ee\u9898\u53cd\u9988: https://github.com/agwr-team/agwr/issues\n- \u90ae\u7bb1: agwr@example.com\n\n## \u66f4\u65b0\u65e5\u5fd7\n\n### v1.0.0 (2024-01-01)\n- \u521d\u59cb\u7248\u672c\u53d1\u5e03\n- \u5b9e\u73b0\u57fa\u672c\u7684AGWR\u6a21\u578b\n- \u652f\u6301\u5404\u5411\u5f02\u6027\u6838\u51fd\u6570\n- \u63d0\u4f9b\u5750\u6807\u6295\u5f71\u529f\u80fd\n- \u5305\u542b\u5b8c\u6574\u7684\u6d4b\u8bd5\u5957\u4ef6\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "\u5404\u5411\u5f02\u6027\u5730\u7406\u52a0\u6743\u56de\u5f52\u6a21\u578b\u5b9e\u73b0",
    "version": "1.2.0",
    "project_urls": {
        "Bug Tracker": "https://github.com/agwr-team/agwr/issues",
        "Documentation": "https://agwr.readthedocs.io/",
        "Homepage": "https://github.com/agwr-team/agwr",
        "Repository": "https://github.com/agwr-team/agwr"
    },
    "split_keywords": [
        "geographically weighted regression",
        " spatial statistics",
        " anisotropy",
        " gwr",
        " agwr"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "d41bb51cac22b024fd30122b88b9d5ab4ed2de3008d622dd448908fa949d049d",
                "md5": "c61c3a983d1c3b626e7496567659dc48",
                "sha256": "c9de58f9370a5380fa4a40f45ba32a16517475275bcc2e3a8056eb71daa19d97"
            },
            "downloads": -1,
            "filename": "agwr-1.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c61c3a983d1c3b626e7496567659dc48",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 12669,
            "upload_time": "2025-09-01T11:42:14",
            "upload_time_iso_8601": "2025-09-01T11:42:14.614445Z",
            "url": "https://files.pythonhosted.org/packages/d4/1b/b51cac22b024fd30122b88b9d5ab4ed2de3008d622dd448908fa949d049d/agwr-1.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "409d4296ff649e18bc4d5bb674472a986fed01993038cd38b3365a26ca6c0441",
                "md5": "79dbb644bc64fe46ecbe7feeea26d536",
                "sha256": "707c819222ee851a98245bf83727890bf057007c92fc68c50b1339b8db294b35"
            },
            "downloads": -1,
            "filename": "agwr-1.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "79dbb644bc64fe46ecbe7feeea26d536",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 16579,
            "upload_time": "2025-09-01T11:42:16",
            "upload_time_iso_8601": "2025-09-01T11:42:16.878902Z",
            "url": "https://files.pythonhosted.org/packages/40/9d/4296ff649e18bc4d5bb674472a986fed01993038cd38b3365a26ca6c0441/agwr-1.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-01 11:42:16",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "agwr-team",
    "github_project": "agwr",
    "github_not_found": true,
    "lcname": "agwr"
}
        
Elapsed time: 0.47204s