diff --git a/CHANGES b/CHANGES
index 66c1659..8a4d3df 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,7 @@
 ------
 
 * Expose `get_registry()` method of `RequestsMock` object. Replaces internal `_get_registry()`.
+* `query_param_matcher` can now accept dictionaries with `int` and `float` values.
 * Added support for `async/await` functions.
 
 0.18.0
diff --git a/responses/matchers.py b/responses/matchers.py
index 893edc1..1fee6a5 100644
--- a/responses/matchers.py
+++ b/responses/matchers.py
@@ -132,6 +132,10 @@ def query_param_matcher(params):
     :return: (func) matcher
     """
 
+    for k, v in params.items():
+        if isinstance(v, (int, float)):
+            params[k] = str(v)
+
     def match(request):
         reason = ""
         request_params = request.params
diff --git a/responses/matchers.pyi b/responses/matchers.pyi
index 188de2e..408eb55 100644
--- a/responses/matchers.pyi
+++ b/responses/matchers.pyi
@@ -19,7 +19,7 @@ def urlencoded_params_matcher(
 ) -> Callable[..., Any]: ...
 
 def query_param_matcher(
-    params: Optional[Dict[str, str]]
+    params: Optional[Dict[str, Any]]
 ) -> Callable[..., Any]: ...
 
 def query_string_matcher(

diff --git a/responses/test_matchers.py b/responses/test_matchers.py
index d061d97..937e8c0 100644
--- a/responses/test_matchers.py
+++ b/responses/test_matchers.py
@@ -87,6 +87,23 @@ def test_request_matches_post_params():
     assert_reset()
 
 
+def test_query_params_numbers():
+    @responses.activate
+    def run():
+        expected_query_params = {"float": 5.0, "int": 2}
+        responses.add(
+            responses.GET,
+            "https://example.com/",
+            match=[
+                matchers.query_param_matcher(expected_query_params),
+            ],
+        )
+        requests.get("https://example.com", params=expected_query_params)
+
+    run()
+    assert_reset()
+
+
 def test_request_matches_empty_body():
     def run():
         with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps:

Integer request query parameters fail to match
### Steps to Reproduce

1. implement a test with `matchers.query_param_matcher` using integers
```python
@responses.activate
def test_bad_matcher():
    expected_query_params = {"number": 5}
    responses.add(
        responses.GET,
        "/fake",
        match=[matchers.query_param_matcher(expected_query_params)]
    )
    requests.get("/fake", params=expected_query_params)
```
### Expected Result

I would expect this test to pass.

### Actual Result

Instead, an extremely confusing failure is produced:

> Parameters do not match. {number: 5} doesn't match {number: 5}

The issue can be worked around by manually casting the integers to a string, but it would be great if the library were able to handle equivalent query params on its own.

responses/test_matchers.py::test_query_params_numbers
responses/test_matchers.py::test_query_string_matcher responses/test_matchers.py::test_request_matches_post_params responses/test_matchers.py::test_request_matches_empty_body responses/test_matchers.py::test_request_matches_params responses/test_matchers.py::test_fail_matchers_error responses/test_matchers.py::test_multipart_matcher[Old responses/test_matchers.py::test_multipart_matcher[\xacHello responses/test_matchers.py::test_multipart_matcher_fail responses/test_matchers.py::test_query_string_matcher_raises responses/test_matchers.py::test_request_matches_headers responses/test_matchers.py::test_request_matches_headers_no_match responses/test_matchers.py::test_request_matches_headers_strict_match responses/test_matchers.py::test_fragment_identifier_matcher responses/test_matchers.py::test_fragment_identifier_matcher_error responses/test_matchers.py::test_fragment_identifier_matcher_and_match_querystring responses/test_matchers.py::test_matchers_create_key_val_str